// // 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; } }*/ }
void spi_int_dpc(PADAPTER padapter, u32 sdio_hisr) { PHAL_DATA_TYPE phal; static u32 last_c2h; phal = GET_HAL_DATA(padapter); if (sdio_hisr & SPI_HISR_CPWM1) { struct reportpwrstate_parm report; report.state = spi_read8(padapter, SPI_LOCAL_OFFSET | SDIO_REG_HCPWM1, NULL); #ifdef CONFIG_LPS_LCLK cpwm_int_hdl(padapter, &report); #endif } if (sdio_hisr & SPI_HISR_TXERR) { u32 status; status = rtw_read32(padapter, REG_TXDMA_STATUS); rtw_write32(padapter, REG_TXDMA_STATUS, status); //DBG_8192C("%s: SPI_HISR_TXERR (0x%08x)\n", __func__, status); } if (sdio_hisr & SPI_HISR_TXBCNOK) { DBG_8192C("%s: SPI_HISR_TXBCNOK\n", __func__); } if (sdio_hisr & SPI_HISR_TXBCNERR) { DBG_8192C("%s: SPI_HISR_TXBCNERR\n", __func__); } if (sdio_hisr & SPI_HISR_C2HCMD) { DBG_8192C("%s: C2H Command\n", __func__); last_c2h = rtw_c2h_wk_cmd(padapter); } else if (last_c2h != _SUCCESS) { /* check C2H stuck */ u8 have_c2h = 0; have_c2h = rtw_read8(padapter, REG_C2HEVT_CLEAR); if (have_c2h) { DBG_871X_LEVEL(_drv_err_, "%s: c2h stuck\n", __FUNCTION__); last_c2h = rtw_c2h_wk_cmd(padapter); } else { last_c2h = _SUCCESS; } } if (sdio_hisr & SPI_HISR_RX_REQUEST)// || sdio_hisr & SPI_HISR_RXFOVW) { struct dvobj_priv *dvobj = padapter->dvobj; PGSPI_DATA pgspi_data = &dvobj->intf_data; if (pgspi_data->priv_wq) queue_delayed_work(pgspi_data->priv_wq, &pgspi_data->recv_work, 0); } }
void sd_int_dpc(PADAPTER padapter) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct intf_hdl * pintfhdl=&padapter->iopriv.intf; #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT if (pHalData->sdio_hisr & SDIO_HISR_AVAL) { //_irqL irql; u8 freepage[4]; _sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage); //_enter_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql); //_rtw_memcpy(pHalData->SdioTxFIFOFreePage, freepage, 4); //_exit_critical_bh(&pHalData->SdioTxFIFOFreePageLock, &irql); //DBG_871X("SDIO_HISR_AVAL, Tx Free Page = 0x%x%x%x%x\n", // freepage[0], // freepage[1], // freepage[2], // freepage[3]); _rtw_up_sema(&(padapter->xmitpriv.xmit_sema)); } #endif if (pHalData->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; #ifdef CONFIG_LPS_RPWM_TIMER u8 bcancelled; _cancel_timer(&(adapter_to_pwrctl(padapter)->pwr_rpwm_timer), &bcancelled); #endif // CONFIG_LPS_RPWM_TIMER _sdio_local_read(padapter, SDIO_REG_HCPWM1, 1, &report.state); #ifdef CONFIG_LPS_LCLK //88e's cpwm value only change BIT0, so driver need to add PS_STATE_S2 for LPS flow. //modify by Thomas. 2012/4/2. #ifdef CONFIG_EXT_CLK //for sprd if(report.state & BIT(4)) //indicate FW entering 32k { u8 chk_cnt = 0; do{ if(_sdio_read8(padapter, 0x90)&BIT(0))//FW in 32k already { if(pwrpriv->rpwm < PS_STATE_S2) { //DBG_871X("disable ext clk when FW in LPS-32K already!\n"); EnableGpio5ClockReq(padapter, _TRUE, 0); } break; } chk_cnt++; }while(chk_cnt<10); if(chk_cnt==10) { DBG_871X("polling fw in 32k already, fail!\n"); } } else //indicate fw leaving 32K #endif //CONFIG_EXT_CLK { report.state |= PS_STATE_S2; //cpwm_int_hdl(padapter, &report); _set_workitem(&(pwrpriv->cpwm_event)); } #endif } #ifdef CONFIG_WOWLAN if (pHalData->sdio_hisr & SDIO_HISR_CPWM2) { u32 value; value = rtw_read32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR); DBG_871X_LEVEL(_drv_always_, "Reset SDIO HISR(0x%08x) original:0x%08x\n", SDIO_LOCAL_BASE+SDIO_REG_HISR, value); value |= BIT19; rtw_write32(padapter, SDIO_LOCAL_BASE+SDIO_REG_HISR, value); value = rtw_read8(padapter, SDIO_LOCAL_BASE+SDIO_REG_HIMR+2); DBG_871X_LEVEL(_drv_always_, "Reset SDIO HIMR CPWM2(0x%08x) original:0x%02x\n", SDIO_LOCAL_BASE+SDIO_REG_HIMR + 2, value); } #endif if (pHalData->sdio_hisr & SDIO_HISR_TXERR) { u8 *status; u32 addr; status = rtw_malloc(4); if (status) { addr = REG_TXDMA_STATUS; HalSdioGetCmdAddr8723ASdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr); _sd_read(pintfhdl, addr, 4, status); _sd_write(pintfhdl, addr, 4, status); DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32*)status)); rtw_mfree(status, 4); } else { DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__); } } #ifdef CONFIG_INTERRUPT_BASED_TXBCN #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT) #endif #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR if (pHalData->sdio_hisr & (SDIO_HISR_TXBCNOK|SDIO_HISR_TXBCNERR)) #endif { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; #if 0 //for debug if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT) DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__); if (pHalData->sdio_hisr & SDIO_HISR_TXBCNOK) DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__); if (pHalData->sdio_hisr & SDIO_HISR_TXBCNERR) DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__); #endif if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) { //send_beacon(padapter); if(pmlmepriv->update_bcn == _TRUE) { //tx_beacon_hdl(padapter, NULL); set_tx_beacon_cmd(padapter); } } #ifdef CONFIG_CONCURRENT_MODE if(check_buddy_fwstate(padapter, WIFI_AP_STATE)) { //send_beacon(padapter); if(padapter->pbuddy_adapter->mlmepriv.update_bcn == _TRUE) { //tx_beacon_hdl(padapter, NULL); set_tx_beacon_cmd(padapter->pbuddy_adapter); } } #endif } #endif //CONFIG_INTERRUPT_BASED_TXBCN #ifdef CONFIG_EXT_CLK if (pHalData->sdio_hisr & SDIO_HISR_BCNERLY_INT) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; if(check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { //DBG_8192C("BCNERLY_INT for enabling ext clk\n"); EnableGpio5ClockReq(padapter, _TRUE, 1); } } #endif //CONFIG_EXT_CLK if (pHalData->sdio_hisr & SDIO_HISR_C2HCMD) { DBG_8192C("%s: C2H Command\n", __func__); } if (pHalData->sdio_hisr & SDIO_HISR_RX_REQUEST) { struct recv_buf *precvbuf; //DBG_8192C("%s: RX Request, size=%d\n", __func__, phal->SdioRxFIFOSize); pHalData->sdio_hisr ^= SDIO_HISR_RX_REQUEST; #ifdef CONFIG_MAC_LOOPBACK_DRIVER sd_recv_loopback(padapter, pHalData->SdioRxFIFOSize); #else do { //Sometimes rx length will be zero. driver need to use cmd53 read again. if(pHalData->SdioRxFIFOSize == 0) { u8 data[4]; _sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 4, data); pHalData->SdioRxFIFOSize = le16_to_cpu(*(u16*)data); } if(pHalData->SdioRxFIFOSize) { precvbuf = sd_recv_rxfifo(padapter, pHalData->SdioRxFIFOSize); pHalData->SdioRxFIFOSize = 0; if (precvbuf) sd_rxhandler(padapter, precvbuf); else break; } else break; #ifdef CONFIG_SDIO_DISABLE_RXFIFO_POLLING_LOOP } while (0); #else } while (1); #endif #endif }
s32 MPT_InitializeAdapter( IN PADAPTER pAdapter, IN u8 Channel ) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); s32 rtStatus = _SUCCESS; PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; u32 ledsetting; //------------------------------------------------------------------------- // HW Initialization for 8190 MPT. //------------------------------------------------------------------------- //------------------------------------------------------------------------- // SW Initialization for 8190 MP. //------------------------------------------------------------------------- pMptCtx->bMptDrvUnload = _FALSE; pMptCtx->bMassProdTest = _FALSE; pMptCtx->bMptIndexEven = _TRUE; //default gain index is -6.0db /* Init mpt event. */ #if 0 // for Windows NdisInitializeEvent( &(pMptCtx->MptWorkItemEvent) ); NdisAllocateSpinLock( &(pMptCtx->MptWorkItemSpinLock) ); PlatformInitializeWorkItem( Adapter, &(pMptCtx->MptWorkItem), (RT_WORKITEM_CALL_BACK)MPT_WorkItemCallback, (PVOID)Adapter, "MptWorkItem"); #endif pMptCtx->bMptWorkItemInProgress = _FALSE; pMptCtx->CurrMptAct = NULL; //------------------------------------------------------------------------- #if 1 // Don't accept any packets rtw_write32(pAdapter, REG_RCR, 0); #else // Accept CRC error and destination address pHalData->ReceiveConfig |= (RCR_ACRC32|RCR_AAP); rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig); #endif #if 0 // If EEPROM or EFUSE is empty,we assign as RF 2T2R for MP. if (pHalData->AutoloadFailFlag == TRUE) { pHalData->RF_Type = RF_2T2R; } #endif ledsetting = rtw_read32(pAdapter, REG_LEDCFG0); rtw_write32(pAdapter, REG_LEDCFG0, ledsetting & ~LED0DIS); #ifdef CONFIG_RTL8192C PHY_IQCalibrate(pAdapter, _FALSE); dm_CheckTXPowerTracking(pAdapter); //trigger thermal meter PHY_LCCalibrate(pAdapter); #endif #ifdef CONFIG_RTL8192D PHY_IQCalibrate(pAdapter); dm_CheckTXPowerTracking(pAdapter); //trigger thermal meter PHY_LCCalibrate(pAdapter); #endif #ifdef CONFIG_PCI_HCI PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); //Wifi default use Main #else #ifdef CONFIG_RTL8192C #if 1 if (pHalData->BoardType == BOARD_MINICARD) PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); //default use Main #else if(pAdapter->HalFunc.GetInterfaceSelectionHandler(pAdapter) == INTF_SEL2_MINICARD ) PHY_SetRFPathSwitch(Adapter, pAdapter->MgntInfo.bDefaultAntenna); //default use Main #endif #endif #endif pMptCtx->backup0xc50 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0); pMptCtx->backup0xc58 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0); pMptCtx->backup0xc30 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0); return rtStatus; }
// // Description: // Disable SDIO Host IMR configuration to mask unnecessary interrupt service. // // Assumption: // Using SDIO Local register ONLY for configuration. // // Created by Roger, 2011.02.11. // void DisableInterrupt8723ASdio(PADAPTER padapter) { rtw_write32(padapter, SPI_LOCAL_OFFSET | SDIO_REG_HIMR, SPI_HIMR_DISABLED); }
s32 MPT_InitializeAdapter( IN PADAPTER pAdapter, IN u8 Channel ) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter); s32 rtStatus = _SUCCESS; PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; u32 ledsetting; struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv; //------------------------------------------------------------------------- // HW Initialization for 8190 MPT. //------------------------------------------------------------------------- //------------------------------------------------------------------------- // SW Initialization for 8190 MP. //------------------------------------------------------------------------- pMptCtx->bMptDrvUnload = _FALSE; pMptCtx->bMassProdTest = _FALSE; pMptCtx->bMptIndexEven = _TRUE; //default gain index is -6.0db pMptCtx->h2cReqNum = 0x0; /* Init mpt event. */ #if 0 // for Windows NdisInitializeEvent( &(pMptCtx->MptWorkItemEvent) ); NdisAllocateSpinLock( &(pMptCtx->MptWorkItemSpinLock) ); PlatformInitializeWorkItem( Adapter, &(pMptCtx->MptWorkItem), (RT_WORKITEM_CALL_BACK)MPT_WorkItemCallback, (PVOID)Adapter, "MptWorkItem"); #endif //init for BT MP #ifdef CONFIG_RTL8723A pMptCtx->bMPh2c_timeout = _FALSE; pMptCtx->MptH2cRspEvent = _FALSE; pMptCtx->MptBtC2hEvent = _FALSE; _rtw_init_sema(&pMptCtx->MPh2c_Sema, 0); _init_timer( &pMptCtx->MPh2c_timeout_timer, pAdapter->pnetdev, MPh2c_timeout_handle, pAdapter ); //before the reset bt patch command,set the wifi page 0's IO to BT mac reboot. #endif pMptCtx->bMptWorkItemInProgress = _FALSE; pMptCtx->CurrMptAct = NULL; //------------------------------------------------------------------------- #if 1 // Don't accept any packets rtw_write32(pAdapter, REG_RCR, 0); #else // Accept CRC error and destination address //pHalData->ReceiveConfig |= (RCR_ACRC32|RCR_AAP); //rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig); rtw_write32(pAdapter, REG_RCR, 0x70000101); #endif #if 0 // If EEPROM or EFUSE is empty,we assign as RF 2T2R for MP. if (pHalData->AutoloadFailFlag == TRUE) { pHalData->RF_Type = RF_2T2R; } #endif //ledsetting = rtw_read32(pAdapter, REG_LEDCFG0); //rtw_write32(pAdapter, REG_LEDCFG0, ledsetting & ~LED0DIS); if(IS_HARDWARE_TYPE_8192DU(pAdapter)) { rtw_write32(pAdapter, REG_LEDCFG0, 0x8888); } else { //rtw_write32(pAdapter, REG_LEDCFG0, 0x08080); ledsetting = rtw_read32(pAdapter, REG_LEDCFG0); #if defined (CONFIG_RTL8192C) || defined( CONFIG_RTL8192D ) rtw_write32(pAdapter, REG_LEDCFG0, ledsetting & ~LED0DIS); #endif } PHY_IQCalibrate(pAdapter, _FALSE); dm_CheckTXPowerTracking(&pHalData->odmpriv); //trigger thermal meter PHY_LCCalibrate(pAdapter); #ifdef CONFIG_PCI_HCI PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); //Wifi default use Main #else #ifdef CONFIG_RTL8192C if (pHalData->BoardType == BOARD_MINICARD) PHY_SetRFPathSwitch(pAdapter, 1/*pHalData->bDefaultAntenna*/); //default use Main #endif #endif pMptCtx->backup0xc50 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0); pMptCtx->backup0xc58 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0); pMptCtx->backup0xc30 = (u1Byte)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0); #ifdef CONFIG_RTL8188E pMptCtx->backup0x52_RF_A = (u1Byte)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); pMptCtx->backup0x52_RF_B = (u1Byte)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0); #endif //set ant to wifi side in mp mode #ifdef CONFIG_RTL8723A rtl8723a_InitAntenna_Selection(pAdapter); #endif //CONFIG_RTL8723A //set ant to wifi side in mp mode rtw_write16(pAdapter, 0x870, 0x300); rtw_write16(pAdapter, 0x860, 0x110); if (pAdapter->registrypriv.mp_mode == 1) pmlmepriv->fw_state = WIFI_MP_STATE; return rtStatus; }
// 1: write RCR DATA BIT // 2: issue peer traffic indication // 3: go back to the channel linked with AP, terminating channel switch procedure // 4: init channel sensing, receive all data and mgnt frame // 5: channel sensing and report candidate channel // 6: first time set channel to off channel // 7: go back tp the channel linked with AP when set base channel as target channel void TDLS_option_workitem_callback(struct work_struct *work) { struct sta_info *ptdls_sta = container_of(work, struct sta_info, option_workitem); _adapter *padapter = ptdls_sta->padapter; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u32 bit_6=1<<6, bit_7=1<<7, bit_4=1<<4; u8 survey_channel, i, min; switch(ptdls_sta->option){ case 1: //As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 //such we can receive all kinds of data frames. rtw_write32(padapter, 0x0608, rtw_read32(padapter, 0x0608)&(~bit_6)); DBG_8192C("wirte 0x0608, set bit6 off\n"); break; case 2: issue_tdls_peer_traffic_indication(padapter, ptdls_sta); break; case 3: _cancel_timer_ex(&ptdls_sta->base_ch_timer); _cancel_timer_ex(&ptdls_sta->off_ch_timer); SelectChannel(padapter, pmlmeext->cur_channel); ptdls_sta->state &= ~(TDLS_CH_SWITCH_ON_STATE | TDLS_PEER_AT_OFF_STATE | TDLS_AT_OFF_CH_STATE); DBG_8192C("go back to base channel\n "); issue_nulldata(padapter, 0); break; case 4: rtw_write32(padapter, 0x0608, rtw_read32(padapter, 0x0608)&(~bit_6)&(~bit_7)); rtw_write16(padapter, 0x06A4,0xffff); //maybe don't need to write here //disable update TSF rtw_write8(padapter, 0x0550, rtw_read8(padapter, 0x0550)|bit_4); pmlmeext->sitesurvey_res.channel_idx = 0; ptdls_sta->option = 5; _set_workitem(&ptdls_sta->option_workitem); break; case 5: survey_channel = pmlmeext->channel_set[pmlmeext->sitesurvey_res.channel_idx].ChannelNum; if(survey_channel){ SelectChannel(padapter, survey_channel); pmlmeinfo->tdls_cur_channel = survey_channel; pmlmeext->sitesurvey_res.channel_idx++; _set_timer(&ptdls_sta->option_timer, SURVEY_TO); }else{ SelectChannel(padapter, pmlmeext->cur_channel); //enable update TSF rtw_write8(padapter, 0x0550, rtw_read8(padapter, 0x0550)&(~bit_4)); rtw_write32(padapter, 0x0608, rtw_read32(padapter, 0x0608)|(bit_7)); if(pmlmeinfo->tdls_ch_sensing==1){ pmlmeinfo->tdls_ch_sensing=0; pmlmeinfo->tdls_cur_channel=1; min=pmlmeinfo->tdls_collect_pkt_num[0]; for(i=1; i<14-1; i++){ if(min > pmlmeinfo->tdls_collect_pkt_num[i]){ pmlmeinfo->tdls_cur_channel=i+1; min=pmlmeinfo->tdls_collect_pkt_num[i]; } pmlmeinfo->tdls_collect_pkt_num[i]=0; } pmlmeinfo->tdls_collect_pkt_num[0]=0; pmlmeinfo->tdls_candidate_ch=pmlmeinfo->tdls_cur_channel; DBG_8192C("TDLS channel sensing done, candidate channel: %02x\n", pmlmeinfo->tdls_candidate_ch); pmlmeinfo->tdls_cur_channel=0; } if(ptdls_sta->state & TDLS_PEER_SLEEP_STATE){ ptdls_sta->state |= TDLS_APSD_CHSW_STATE; }else{ //send null data with pwrbit==1 before send ch_switching_req to peer STA. issue_nulldata(padapter, 1); ptdls_sta->state |= TDLS_CH_SW_INITIATOR_STATE; issue_tdls_ch_switch_req(padapter, ptdls_sta->hwaddr); DBG_8192C("issue tdls ch switch req\n"); } } break; case 6: issue_nulldata(padapter, 1); SelectChannel(padapter, ptdls_sta->off_ch); DBG_8192C("change channel to tar ch:%02x\n", ptdls_sta->off_ch); ptdls_sta->state |= TDLS_AT_OFF_CH_STATE; ptdls_sta->state &= ~(TDLS_PEER_AT_OFF_STATE); _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time); break; case 7: _cancel_timer_ex(&ptdls_sta->base_ch_timer); _cancel_timer_ex(&ptdls_sta->off_ch_timer); SelectChannel(padapter, pmlmeext->cur_channel); ptdls_sta->state &= ~(TDLS_CH_SWITCH_ON_STATE | TDLS_PEER_AT_OFF_STATE | TDLS_AT_OFF_CH_STATE); DBG_8192C("go back to base channel\n "); issue_nulldata(padapter, 0); _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time); break; } }
/***************************************** * H2C Msg format : * 0x1DF - 0x1D0 *| 31 - 8 | 7-5 4 - 0 | *| h2c_msg |Class_ID CMD_ID | * * Extend 0x1FF - 0x1F0 *|31 - 0 | *|ext_msg| ******************************************/ static s32 FillH2CCmd_88E(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) { struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); u8 h2c_box_num; u32 msgbox_addr; u32 msgbox_ex_addr; u8 cmd_idx,ext_cmd_len; u32 h2c_cmd = 0; u32 h2c_cmd_ex = 0; s32 ret = _FAIL; _func_enter_; padapter = GET_PRIMARY_ADAPTER(padapter); pHalData = GET_HAL_DATA(padapter); if(padapter->bFWReady == _FALSE) { DBG_8192C("FillH2CCmd_88E(): return H2C cmd because fw is not ready\n"); return ret; } _enter_critical_mutex(&(dvobj->h2c_fwcmd_mutex), NULL); if (!pCmdBuffer) { goto exit; } if (CmdLen > RTL88E_MAX_CMD_LEN) { goto exit; } if (padapter->bSurpriseRemoved == _TRUE) goto exit; //pay attention to if race condition happened in H2C cmd setting. do{ h2c_box_num = pHalData->LastHMEBoxNum; if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){ DBG_8192C(" fw read cmd failed...\n"); goto exit; } *(u8*)(&h2c_cmd) = ElementID; if(CmdLen<=3) { _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen ); } else{ _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer,3); ext_cmd_len = CmdLen-3; _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3,ext_cmd_len ); //Write Ext command msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num *RTL88E_EX_MESSAGE_BOX_SIZE); #ifdef CONFIG_H2C_EF for(cmd_idx=0;cmd_idx<ext_cmd_len;cmd_idx++ ){ rtw_write8(padapter,msgbox_ex_addr+cmd_idx,*((u8*)(&h2c_cmd_ex)+cmd_idx)); } #else h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex ); rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex); #endif } // Write command msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *RTL88E_MESSAGE_BOX_SIZE); #ifdef CONFIG_H2C_EF for(cmd_idx=0;cmd_idx<RTL88E_MESSAGE_BOX_SIZE;cmd_idx++ ){ rtw_write8(padapter,msgbox_addr+cmd_idx,*((u8*)(&h2c_cmd)+cmd_idx)); } #else h2c_cmd = le32_to_cpu( h2c_cmd ); rtw_write32(padapter,msgbox_addr, h2c_cmd); #endif // DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n" // ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex); pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL88E_MAX_H2C_BOX_NUMS; }while(0); ret = _SUCCESS; exit: _exit_critical_mutex(&(dvobj->h2c_fwcmd_mutex), NULL); _func_exit_; return ret; }
static void writeOFDMPowerReg( IN PADAPTER Adapter, IN u8 index, IN u32* pValue ) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); u16 RegOffset_A[6] = { rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24, rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04, rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12}; u16 RegOffset_B[6] = { rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24, rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04, rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12}; u8 i, rf, pwr_val[4]; u32 writeVal; u16 RegOffset; for(rf=0; rf<2; rf++) { writeVal = pValue[rf]; for(i=0; i<4; i++) { pwr_val[i] = (u8)((writeVal & (0x7f<<(i*8)))>>(i*8)); if (pwr_val[i] > RF6052_MAX_TX_PWR) pwr_val[i] = RF6052_MAX_TX_PWR; } writeVal = (pwr_val[3]<<24) | (pwr_val[2]<<16) |(pwr_val[1]<<8) |pwr_val[0]; if(rf == 0) RegOffset = RegOffset_A[index]; else RegOffset = RegOffset_B[index]; PHY_SetBBReg(Adapter, RegOffset, bMaskDWord, writeVal); //RTPRINT(FPHY, PHY_TXPWR, ("Set 0x%x = %08x\n", RegOffset, writeVal)); // 201005115 Joseph: Set Tx Power diff for Tx power training mechanism. if(((pHalData->rf_type == RF_2T2R) && (RegOffset == rTxAGC_A_Mcs15_Mcs12 || RegOffset == rTxAGC_B_Mcs15_Mcs12))|| ((pHalData->rf_type != RF_2T2R) && (RegOffset == rTxAGC_A_Mcs07_Mcs04 || RegOffset == rTxAGC_B_Mcs07_Mcs04)) ) { writeVal = pwr_val[3]; if(RegOffset == rTxAGC_A_Mcs15_Mcs12 || RegOffset == rTxAGC_A_Mcs07_Mcs04) RegOffset = 0xc90; if(RegOffset == rTxAGC_B_Mcs15_Mcs12 || RegOffset == rTxAGC_B_Mcs07_Mcs04) RegOffset = 0xc98; for(i=0; i<3; i++) { if(i!=2) writeVal = (writeVal>8)?(writeVal-8):0; else writeVal = (writeVal>6)?(writeVal-6):0; rtw_write8(Adapter, (u32)(RegOffset+i), (u8)writeVal); } } #ifdef CONFIG_BT_COEXIST #ifdef CONFIG_CMCC_TEST if (pHalData->bt_coexist.LowPwr_11g) { //DBG_871X("[BTCoex-CMCC], %s BT busy, lower 11G power\n", __func__); rtw_write32(Adapter,0xe00,0x1c1c1c1c); rtw_write32(Adapter,0xe04,0x1c1c1c1c); } #endif #endif } }
void rtl8188e_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); struct P2P_PS_Offload_t *p2p_ps_offload = (struct P2P_PS_Offload_t *)(&pHalData->p2p_ps_offload); u8 i; _func_enter_; #if 1 switch(p2p_ps_state) { case P2P_PS_DISABLE: DBG_8192C("P2P_PS_DISABLE \n"); _rtw_memset(p2p_ps_offload, 0 ,1); break; case P2P_PS_ENABLE: DBG_8192C("P2P_PS_ENABLE \n"); // update CTWindow value. if( pwdinfo->ctwindow > 0 ) { p2p_ps_offload->CTWindow_En = 1; rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow); } // hw only support 2 set of NoA for( i=0 ; i<pwdinfo->noa_num ; i++) { // To control the register setting for which NOA rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4)); if(i == 0) p2p_ps_offload->NoA0_En = 1; else p2p_ps_offload->NoA1_En = 1; // config P2P NoA Descriptor Register //DBG_8192C("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]); rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]); //DBG_8192C("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]); rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]); //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]); rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]); //DBG_8192C("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]); rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]); } if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) ) { // rst p2p circuit rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4)); p2p_ps_offload->Offload_En = 1; if(pwdinfo->role == P2P_ROLE_GO) { p2p_ps_offload->role= 1; p2p_ps_offload->AllStaSleep = 0; } else { p2p_ps_offload->role= 0; } p2p_ps_offload->discovery = 0; } break; case P2P_PS_SCAN: DBG_8192C("P2P_PS_SCAN \n"); p2p_ps_offload->discovery = 1; break; case P2P_PS_SCAN_DONE: DBG_8192C("P2P_PS_SCAN_DONE \n"); p2p_ps_offload->discovery = 0; pwdinfo->p2p_ps_state = P2P_PS_ENABLE; break; default: break; } FillH2CCmd_88E(padapter, H2C_PS_P2P_OFFLOAD, 1, (u8 *)p2p_ps_offload); #endif _func_exit_; }
static void _restore_network_status(_adapter *padapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network)); unsigned short caps; u8 join_type; #if 1 //======================================================= // reset related register of Beacon control //set MSR to nolink Set_MSR(padapter, _HW_STATE_NOLINK_); // reject all data frame rtw_write16(padapter, REG_RXFLTMAP2,0x00); //reset TSF rtw_write8(padapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1))); // disable update TSF SetBcnCtrlReg(padapter, BIT(4), 0); //======================================================= rtw_joinbss_reset(padapter); set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); //pmlmeinfo->assoc_AP_vendor = maxAP; if (padapter->registrypriv.wifi_spec) { // for WiFi test, follow WMM test plan spec rtw_write32(padapter, REG_EDCA_VO_PARAM, 0x002F431C); rtw_write32(padapter, REG_EDCA_VI_PARAM, 0x005E541C); rtw_write32(padapter, REG_EDCA_BE_PARAM, 0x0000A525); rtw_write32(padapter, REG_EDCA_BK_PARAM, 0x0000A549); #ifdef CONFIG_80211N_HT // for WiFi test, mixed mode with intel STA under bg mode throughput issue if (padapter->mlmepriv.htpriv.ht_option == 0) #endif //CONFIG_80211N_HT rtw_write32(padapter, REG_EDCA_BE_PARAM, 0x00004320); } else { rtw_write32(padapter, REG_EDCA_VO_PARAM, 0x002F3217); rtw_write32(padapter, REG_EDCA_VI_PARAM, 0x005E4317); rtw_write32(padapter, REG_EDCA_BE_PARAM, 0x00105320); rtw_write32(padapter, REG_EDCA_BK_PARAM, 0x0000A444); } //disable dynamic functions, such as high power, DIG //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); #endif rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); join_type = 0; rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); Set_MSR(padapter, (pmlmeinfo->state & 0x3)); mlmeext_joinbss_event_callback(padapter, 1); //restore Sequence No. rtw_write8(padapter,0x4dc,padapter->xmitpriv.nqos_ssn); }
void rtl8192d_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct wifidirect_info *pwdinfo = &( padapter->wdinfo ); struct P2P_PS_Offload_t *p2p_ps_offload = &pHalData->p2p_ps_offload; u8 i; u16 ctwindow; u32 start_time, tsf_low; _func_enter_; switch(p2p_ps_state) { case P2P_PS_DISABLE: DBG_8192C("P2P_PS_DISABLE \n"); _rtw_memset(p2p_ps_offload, 0 ,1); break; case P2P_PS_ENABLE: DBG_8192C("P2P_PS_ENABLE \n"); // update CTWindow value. if( pwdinfo->ctwindow > 0 ) { p2p_ps_offload->CTWindow_En = 1; ctwindow = pwdinfo->ctwindow; rtl8192d_set_p2p_ctw_period_cmd(padapter, ctwindow); //rtw_write16(padapter, REG_ATIMWND, ctwindow); } // hw only support 2 set of NoA for( i=0 ; i<pwdinfo->noa_num ; i++) { // To control the register setting for which NOA rtw_write8(padapter, 0x5CF, (i << 4)); if(i == 0) p2p_ps_offload->NoA0_En = 1; else p2p_ps_offload->NoA1_En = 1; // config P2P NoA Descriptor Register rtw_write32(padapter, 0x5E0, pwdinfo->noa_duration[i]); rtw_write32(padapter, 0x5E4, pwdinfo->noa_interval[i]); //Get Current TSF value tsf_low = rtw_read32(padapter, REG_TSFTR); start_time = pwdinfo->noa_start_time[i]; if(pwdinfo->noa_count[i] != 1) { while( start_time <= (tsf_low+(50*1024) ) ) { start_time += pwdinfo->noa_interval[i]; if(pwdinfo->noa_count[i] != 255) pwdinfo->noa_count[i]--; } } //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,start_time); rtw_write32(padapter, 0x5E8, start_time); rtw_write8(padapter, 0x5EC, pwdinfo->noa_count[i]); } if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) ) { // rst p2p circuit rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4)); p2p_ps_offload->Offload_En = 1; if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { p2p_ps_offload->role= 1; p2p_ps_offload->AllStaSleep = 0; } else { p2p_ps_offload->role= 0; } p2p_ps_offload->discovery = 0; } break; case P2P_PS_SCAN: DBG_8192C("P2P_PS_SCAN \n"); p2p_ps_offload->discovery = 1; break; case P2P_PS_SCAN_DONE: DBG_8192C("P2P_PS_SCAN_DONE \n"); p2p_ps_offload->discovery = 0; pwdinfo->p2p_ps_state = P2P_PS_ENABLE; break; default: break; } FillH2CCmd92D(padapter, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); _func_exit_; }
void odm_EdcaTurboCheckCE( IN void * pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; PADAPTER Adapter = pDM_Odm->Adapter; u32 EDCA_BE_UL = 0x5ea42b;//Parameter suggested by Scott //edca_setting_UL[pMgntInfo->IOTPeer]; u32 EDCA_BE_DL = 0x5ea42b;//Parameter suggested by Scott //edca_setting_DL[pMgntInfo->IOTPeer]; u32 IOTPeer=0; u8 WirelessMode=0xFF; //invalid value u32 trafficIndex; u32 edca_param; u64 cur_tx_bytes = 0; u64 cur_rx_bytes = 0; u8 bbtchange = false; u8 bBiasOnRx = false; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter); struct recv_priv *precvpriv = &(Adapter->recvpriv); struct registry_priv *pregpriv = &Adapter->registrypriv; struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); if(pDM_Odm->bLinked != true) { precvpriv->bIsAnyNonBEPkts = false; return; } if ((pregpriv->wifi_spec == 1) )//|| (pmlmeinfo->HT_enable == 0)) { precvpriv->bIsAnyNonBEPkts = false; return; } if(pDM_Odm->pWirelessMode!=NULL) WirelessMode=*(pDM_Odm->pWirelessMode); IOTPeer = pmlmeinfo->assoc_AP_vendor; if (IOTPeer >= HT_IOT_PEER_MAX) { precvpriv->bIsAnyNonBEPkts = false; return; } // Check if the status needs to be changed. if((bbtchange) || (!precvpriv->bIsAnyNonBEPkts) ) { cur_tx_bytes = pdvobjpriv->traffic_stat.cur_tx_bytes; cur_rx_bytes = pdvobjpriv->traffic_stat.cur_rx_bytes; //traffic, TX or RX if(bBiasOnRx) { if (cur_tx_bytes > (cur_rx_bytes << 2)) { // Uplink TP is present. trafficIndex = UP_LINK; } else { // Balance TP is present. trafficIndex = DOWN_LINK; } } else { if (cur_rx_bytes > (cur_tx_bytes << 2)) { // Downlink TP is present. trafficIndex = DOWN_LINK; } else { // Balance TP is present. trafficIndex = UP_LINK; } } //if ((pDM_Odm->DM_EDCA_Table.prv_traffic_idx != trafficIndex) || (!pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA)) { //92D txop can't be set to 0x3e for cisco1250 if((IOTPeer== HT_IOT_PEER_CISCO) &&(WirelessMode==ODM_WM_N24G)) { EDCA_BE_DL = edca_setting_DL[IOTPeer]; EDCA_BE_UL = edca_setting_UL[IOTPeer]; } //merge from 92s_92c_merge temp brunch v2445 20120215 else if((IOTPeer == HT_IOT_PEER_CISCO) &&((WirelessMode==ODM_WM_G)||(WirelessMode==(ODM_WM_B|ODM_WM_G))||(WirelessMode==ODM_WM_A)||(WirelessMode==ODM_WM_B))) { EDCA_BE_DL = edca_setting_DL_GMode[IOTPeer]; } else if((IOTPeer== HT_IOT_PEER_AIRGO )&& ((WirelessMode==ODM_WM_G)||(WirelessMode==ODM_WM_A))) { EDCA_BE_DL = 0xa630; } else if(IOTPeer == HT_IOT_PEER_MARVELL) { EDCA_BE_DL = edca_setting_DL[IOTPeer]; EDCA_BE_UL = edca_setting_UL[IOTPeer]; } else if(IOTPeer == HT_IOT_PEER_ATHEROS) { // Set DL EDCA for Atheros peer to 0x3ea42b. Suggested by SD3 Wilson for ASUS TP issue. EDCA_BE_DL = edca_setting_DL[IOTPeer]; } if (trafficIndex == DOWN_LINK) edca_param = EDCA_BE_DL; else edca_param = EDCA_BE_UL; rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param); pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex; } pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true; } else { // // Turn Off EDCA turbo here. // Restore original EDCA according to the declaration of AP. // if(pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) { rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE); pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; } } }
static VOID _BlockWrite( IN PADAPTER Adapter, IN PVOID buffer, IN u32 size ) { #if 1 #ifdef SUPPORTED_BLOCK_IO u32 blockSize = MAX_REG_BOLCK_SIZE; // Use 196-byte write to download FW u32 blockSize2 = MIN_REG_BOLCK_SIZE; #else u32 blockSize = sizeof(u32); // Use 4-byte write to download FW u32* pu4BytePtr = (u32*)buffer; u32 blockSize2 = sizeof(u8); #endif u8* bufferPtr = (u8*)buffer; u32 i, offset, offset2, blockCount, remainSize, remainSize2; blockCount = size / blockSize; remainSize = size % blockSize; for(i = 0 ; i < blockCount ; i++){ offset = i * blockSize; #ifdef SUPPORTED_BLOCK_IO writeN(Adapter, (FW_8192C_START_ADDRESS + offset), blockSize, (bufferPtr + offset)); #else rtw_write32(Adapter, (FW_8192C_START_ADDRESS + offset), le32_to_cpu(*(pu4BytePtr + i))); #endif } if(remainSize){ offset2 = blockCount * blockSize; blockCount = remainSize / blockSize2; remainSize2 = remainSize % blockSize2; for(i = 0 ; i < blockCount ; i++){ offset = offset2 + i * blockSize2; #ifdef SUPPORTED_BLOCK_IO writeN(Adapter, (FW_8192C_START_ADDRESS + offset), blockSize2, (bufferPtr + offset)); #else rtw_write8(Adapter, (FW_8192C_START_ADDRESS + offset ), *(bufferPtr + offset)); #endif } if(remainSize2) { offset += blockSize2; bufferPtr += offset; for(i = 0 ; i < remainSize2 ; i++){ rtw_write8(Adapter, (FW_8192C_START_ADDRESS + offset + i), *(bufferPtr + i)); } } } #else u32 blockSize = sizeof(u32); // Use 4-byte write to download FW u8* bufferPtr = (u8*)buffer; u32* pu4BytePtr = (u32*)buffer; u32 i, offset, blockCount, remainSize; blockCount = size / blockSize; remainSize = size % blockSize; for(i = 0 ; i < blockCount ; i++){ offset = i * blockSize; rtw_write32(Adapter, (FW_8192C_START_ADDRESS + offset), le32_to_cpu(*(pu4BytePtr + i))); } if(remainSize){ offset = blockCount * blockSize; bufferPtr += offset; for(i = 0 ; i < remainSize ; i++){ rtw_write8(Adapter, (FW_8192C_START_ADDRESS + offset + i), *(bufferPtr + i)); } } #endif }