int netdev_open(struct net_device *pnetdev) { int ret; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); _enter_critical_mutex(&padapter->hw_init_mutex, NULL); ret = _netdev_open(pnetdev); mutex_unlock(&padapter->hw_init_mutex); return ret; }
void rtw_write8(_adapter *adapter, u32 addr, u8 val) { //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; struct io_priv *pio_priv = &adapter->iopriv; struct intf_hdl *pintfhdl = &(pio_priv->intf); void (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); _irqL irqL; _func_enter_; _write8 = pintfhdl->io_ops._write8; _enter_critical_mutex(&pintfhdl->io_mutex, &irqL); _write8(pintfhdl, addr, val); _exit_critical_mutex(&pintfhdl->io_mutex, &irqL); }
void writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata) { //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; struct io_priv *pio_priv = &adapter->iopriv; struct intf_hdl *pintfhdl = (struct intf_hdl*)(&(pio_priv->intf)); void (*_writeN)(struct intf_hdl *pintfhdl, u32 addr,u32 length, u8 *pdata); _irqL irqL; _func_enter_; _writeN = pintfhdl->io_ops._writeN; _enter_critical_mutex(&pintfhdl->io_mutex, &irqL); _writeN(pintfhdl, addr,length,pdata); _exit_critical_mutex(&pintfhdl->io_mutex, &irqL); _func_exit_; }
u16 rtw_read16(_adapter *adapter, u32 addr) { u16 r_val; //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; struct io_priv *pio_priv = &adapter->iopriv; struct intf_hdl *pintfhdl = &(pio_priv->intf); u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); _irqL irqL; _func_enter_; _read16 = pintfhdl->io_ops._read16; _enter_critical_mutex(&pintfhdl->io_mutex, &irqL); r_val = _read16(pintfhdl, addr); _exit_critical_mutex(&pintfhdl->io_mutex, &irqL); _func_exit_; return r_val; }
void rtl8723b_silentreset_for_specific_platform(_adapter *padapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct sreset_priv *psrtpriv = &pHalData->srestpriv; struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; _irqL irqL; #ifdef DBG_CONFIG_ERROR_RESET DBG_871X("%s\n", __FUNCTION__); psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; if (!rtw_netif_queue_stopped(padapter->pnetdev)) rtw_netif_stop_queue(padapter->pnetdev); rtw_cancel_all_timer(padapter); tasklet_kill(&pxmitpriv->xmit_tasklet); _enter_critical_mutex(&psrtpriv->silentreset_mutex, &irqL); psrtpriv->silent_reset_inprogress = _TRUE; pwrpriv->change_rfpwrstate = rf_off; #ifdef CONFIG_IPS ips_enter(padapter); ips_leave(padapter); #endif if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) { _restore_network_status(padapter); _restore_security_setting(padapter); } _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING); psrtpriv->silent_reset_inprogress = _FALSE; _exit_critical_mutex(&psrtpriv->silentreset_mutex, &irqL); tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); if (netif_queue_stopped(padapter->pnetdev)) netif_wake_queue(padapter->pnetdev); #endif }
void rtl8192c_silentreset_for_specific_platform(_adapter *padapter) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct sreset_priv *psrtpriv = &pHalData->srestpriv; struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; _irqL irqL; psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; if (!netif_queue_stopped(padapter->pnetdev)) netif_stop_queue(padapter->pnetdev); rtw_cancel_all_timer(padapter); tasklet_kill(&pxmitpriv->xmit_tasklet); _enter_critical_mutex(&psrtpriv->silentreset_mutex, &irqL); psrtpriv->silent_reset_inprogress = _TRUE; pwrpriv->change_rfpwrstate = rf_off; ips_enter(padapter); ips_leave(padapter); if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) { _restore_network_status(padapter); _restore_security_setting(padapter); } if(pmlmepriv->fw_state & _FW_UNDER_SURVEY) pmlmepriv->fw_state ^= _FW_UNDER_SURVEY; if(pmlmepriv->fw_state & _FW_UNDER_LINKING) pmlmepriv->fw_state ^= _FW_UNDER_LINKING; psrtpriv->silent_reset_inprogress = _FALSE; _exit_critical_mutex(&psrtpriv->silentreset_mutex, &irqL); tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); if (netif_queue_stopped(padapter->pnetdev)) netif_wake_queue(padapter->pnetdev); }
void sreset_reset(_adapter *padapter) { #ifdef DBG_CONFIG_ERROR_RESET HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct sreset_priv *psrtpriv = &pHalData->srestpriv; struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct xmit_priv *pxmitpriv = &padapter->xmitpriv; _irqL irqL; u32 start = rtw_get_current_time(); DBG_871X("%s\n", __FUNCTION__); psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS; _enter_critical_mutex(&psrtpriv->silentreset_mutex, &irqL); psrtpriv->silent_reset_inprogress = _TRUE; pwrpriv->change_rfpwrstate = rf_off; sreset_stop_adapter(padapter); #ifdef CONFIG_CONCURRENT_MODE sreset_stop_adapter(padapter->pbuddy_adapter); #endif #ifdef CONFIG_IPS ips_enter(padapter); ips_leave(padapter); #endif sreset_start_adapter(padapter); #ifdef CONFIG_CONCURRENT_MODE sreset_start_adapter(padapter->pbuddy_adapter); #endif psrtpriv->silent_reset_inprogress = _FALSE; _exit_critical_mutex(&psrtpriv->silentreset_mutex, &irqL); DBG_871X("%s done in %d ms\n", __FUNCTION__, rtw_get_passing_time_ms(start)); #endif }
/***************************************** * H2C Msg format : *| 31 - 8 |7 | 6 - 0 | *| h2c_msg |Ext_bit |CMD_ID | * ******************************************/ static void _FillH2CCmd92D(_adapter* padapter, u8 ElementID, u32 CmdLen, u8* pCmdBuffer) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); u8 BoxNum; u16 BOXReg=0, BOXExtReg=0; u8 BoxContent[4], BoxExtContent[2]; u8 BufIndex=0; u8 U1btmp; //Read 0x1bf u8 bWriteSucess = _FALSE; u8 IsFwRead = _FALSE; u8 WaitH2cLimmit = 100; u8 WaitWriteH2cLimmit = 100; u8 idx=0; _func_enter_; padapter = GET_PRIMARY_ADAPTER(padapter); pHalData = GET_HAL_DATA(padapter); _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL); //DBG_8192C("FillH2CCmd : ElementID=%d \n",ElementID); while(!bWriteSucess) { WaitWriteH2cLimmit--; if(WaitWriteH2cLimmit == 0) { DBG_8192C("FillH2CCmd92C():Write H2C fail because no trigger for FW INT!!!!!!!!\n"); break; } // 2. Find the last BOX number which has been writen. BoxNum = pHalData->LastHMEBoxNum; switch(BoxNum) { case 0: BOXReg = REG_HMEBOX_0; BOXExtReg = REG_HMEBOX_EXT_0; break; case 1: BOXReg = REG_HMEBOX_1; BOXExtReg = REG_HMEBOX_EXT_1; break; case 2: BOXReg = REG_HMEBOX_2; BOXExtReg = REG_HMEBOX_EXT_2; break; case 3: BOXReg = REG_HMEBOX_3; BOXExtReg = REG_HMEBOX_EXT_3; break; default: break; } // 3. Check if the box content is empty. IsFwRead = CheckFwReadLastH2C(padapter, BoxNum); while(!IsFwRead) { //wait until Fw read WaitH2cLimmit--; if(WaitH2cLimmit == 0) { DBG_8192C("FillH2CCmd92C(): Wating too long for FW read clear HMEBox(%d)!!!\n", BoxNum); break; } rtw_udelay_os(10); //us IsFwRead = CheckFwReadLastH2C(padapter, BoxNum); U1btmp = rtw_read8(padapter, 0x1BF); //DBG_8192C("FillH2CCmd92C(): Wating for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", BoxNum, U1btmp); } // If Fw has not read the last H2C cmd, break and give up this H2C. if(!IsFwRead) { DBG_8192C("FillH2CCmd92C(): Write H2C register BOX[%d] fail!!!!! Fw do not read. \n", BoxNum); break; } // 4. Fill the H2C cmd into box _rtw_memset(BoxContent, 0, sizeof(BoxContent)); _rtw_memset(BoxExtContent, 0, sizeof(BoxExtContent)); BoxContent[0] = ElementID; // Fill element ID //DBG_8192C("FillH2CCmd92C():Write ElementID BOXReg(%4x) = %2x \n", BOXReg, ElementID); switch(CmdLen) { case 1: { BoxContent[0] &= ~(BIT7); _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex, 1); //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent)); //For Endian Free. for(idx= 0; idx < 4; idx++) { rtw_write8(padapter, BOXReg+idx, BoxContent[idx]); } break; } case 2: { BoxContent[0] &= ~(BIT7); _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex, 2); //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent)); for(idx=0; idx < 4; idx++) { rtw_write8(padapter, BOXReg+idx, BoxContent[idx]); } break; } case 3: { BoxContent[0] &= ~(BIT7); _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex, 3); //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent)); for(idx = 0; idx < 4 ; idx++) { rtw_write8(padapter, BOXReg+idx, BoxContent[idx]); } break; } case 4: { BoxContent[0] |= (BIT7); _rtw_memcpy((u8 *)(BoxExtContent), pCmdBuffer+BufIndex, 2); _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex+2, 2); //PlatformEFIOWrite2Byte(Adapter, BOXExtReg, *((pu2Byte)BoxExtContent)); //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent)); for(idx = 0 ; idx < 2 ; idx ++) { rtw_write8(padapter, BOXExtReg+idx, BoxExtContent[idx]); } for(idx = 0 ; idx < 4 ; idx ++) { rtw_write8(padapter, BOXReg+idx, BoxContent[idx]); } break; } case 5: { BoxContent[0] |= (BIT7); _rtw_memcpy((u8 *)(BoxExtContent), pCmdBuffer+BufIndex, 2); _rtw_memcpy((u8 *)(BoxContent)+1, pCmdBuffer+BufIndex+2, 3); //PlatformEFIOWrite2Byte(Adapter, BOXExtReg, *((pu2Byte)BoxExtContent)); //PlatformEFIOWrite4Byte(Adapter, BOXReg, *((pu4Byte)BoxContent)); for(idx = 0 ; idx < 2 ; idx ++) { rtw_write8(padapter, BOXExtReg+idx, BoxExtContent[idx]); } for(idx = 0 ; idx < 4 ; idx ++) { rtw_write8(padapter, BOXReg+idx, BoxContent[idx]); } break; } default: break; } //DBG_8192C("FillH2CCmd(): BoxExtContent=0x%04x\n", *(u16*)BoxExtContent); //DBG_8192C("FillH2CCmd(): BoxContent=0x%08x\n", *(u32*)BoxContent); // 5. Normal chip does not need to check if the H2C cmd has be written successfully. // 92D test chip does not need to check, bWriteSucess = _TRUE; // Record the next BoxNum pHalData->LastHMEBoxNum = BoxNum+1; if(pHalData->LastHMEBoxNum == 4) // loop to 0 pHalData->LastHMEBoxNum = 0; //DBG_8192C("FillH2CCmd92C():pHalData->LastHMEBoxNum = %d\n", pHalData->LastHMEBoxNum); } _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL); _func_exit_; }
int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) { _adapter *padapter = pintfhdl->padapter; struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); //struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobjpriv); struct usb_device *udev=pdvobjpriv->pusbdev; unsigned int pipe; int status = 0; //u32 tmp_buflen=0; u8 reqtype; u8 *pIo_buf; int vendorreq_times = 0; #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE u8 *tmp_buf; #else // use stack memory //u8 tmp_buf[MAX_USB_IO_CTL_SIZE]; #endif #ifdef CONFIG_CONCURRENT_MODE if(padapter->adapter_type > PRIMARY_ADAPTER) { padapter = padapter->pbuddy_adapter; pdvobjpriv = adapter_to_dvobj(padapter); udev = pdvobjpriv->pusbdev; } #endif //DBG_871X("%s %s:%d\n",__FUNCTION__, current->comm, current->pid); if (RTW_CANNOT_IO(padapter)) { RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usbctrl_vendorreq:(RTW_CANNOT_IO)!!!\n")); status = -EPERM; goto exit; } if(len>MAX_VENDOR_REQ_CMD_SIZE) { DBG_8192C( "[%s] Buffer len error ,vendor request failed\n", __FUNCTION__ ); status = -EINVAL; goto exit; } #ifdef CONFIG_USB_VENDOR_REQ_MUTEX _enter_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL); #endif // Acquire IO memory for vendorreq #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC pIo_buf = pdvobjpriv->usb_vendor_req_buf; #else #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE tmp_buf = rtw_malloc( (u32) len + ALIGNMENT_UNIT); tmp_buflen = (u32)len + ALIGNMENT_UNIT; #else // use stack memory tmp_buflen = MAX_USB_IO_CTL_SIZE; #endif // Added by Albert 2010/02/09 // For mstar platform, mstar suggests the address for USB IO should be 16 bytes alignment. // Trying to fix it here. pIo_buf = (tmp_buf==NULL)?NULL:tmp_buf + ALIGNMENT_UNIT -((SIZE_PTR)(tmp_buf) & 0x0f ); #endif if ( pIo_buf== NULL) { DBG_8192C( "[%s] pIo_buf == NULL \n", __FUNCTION__ ); status = -ENOMEM; goto release_mutex; } while(++vendorreq_times<= MAX_USBCTRL_VENDORREQ_TIMES) { _rtw_memset(pIo_buf, 0, len); if (requesttype == 0x01) { pipe = usb_rcvctrlpipe(udev, 0);//read_in reqtype = REALTEK_USB_VENQT_READ; } else { pipe = usb_sndctrlpipe(udev, 0);//write_out reqtype = REALTEK_USB_VENQT_WRITE; _rtw_memcpy( pIo_buf, pdata, len); } status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT); if ( status == len) { // Success this control transfer. rtw_reset_continual_io_error(pdvobjpriv); if ( requesttype == 0x01 ) { // For Control read transfer, we have to copy the read data from pIo_buf to pdata. _rtw_memcpy( pdata, pIo_buf, len ); } } else { // error cases DBG_8192C("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n" , value,(requesttype == 0x01)?"read":"write" , len, status, *(u32*)pdata, vendorreq_times); if (status < 0) { if(status == (-ESHUTDOWN) || status == -ENODEV ) { padapter->bSurpriseRemoved = _TRUE; } else { #ifdef DBG_CONFIG_ERROR_DETECT { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); pHalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL; } #endif } } else { // status != len && status >= 0 if(status > 0) { if ( requesttype == 0x01 ) { // For Control read transfer, we have to copy the read data from pIo_buf to pdata. _rtw_memcpy( pdata, pIo_buf, len ); } } } if(rtw_inc_and_chk_continual_io_error(pdvobjpriv) == _TRUE ) { padapter->bSurpriseRemoved = _TRUE; break; } } // firmware download is checksumed, don't retry if( (value >= FW_START_ADDRESS ) || status == len ) break; } // release IO memory used by vendorreq #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE rtw_mfree(tmp_buf, tmp_buflen); #endif release_mutex: #ifdef CONFIG_USB_VENDOR_REQ_MUTEX _exit_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL); #endif exit: return status; }
/***************************************** * 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; }