int rtl92s_download_fw( struct ieee80211_hw *hw ) { struct rtl_priv *rtlpriv = rtl_priv( hw ); struct rtl_hal *rtlhal = rtl_hal( rtl_priv( hw ) ); struct rt_firmware *pfirmware = NULL; struct fw_hdr *pfwheader; struct fw_priv *pfw_priv = NULL; u8 *puc_mappedfile = NULL; u32 ul_filelength = 0; u32 file_length = 0; u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE; u8 fwstatus = FW_STATUS_INIT; bool rtstatus = true; if( !rtlhal->pfirmware ) return 1; pfirmware = ( struct rt_firmware * )rtlhal->pfirmware; pfirmware->fwstatus = FW_STATUS_INIT; puc_mappedfile = pfirmware->sz_fw_tmpbuffer; file_length = pfirmware->sz_fw_tmpbufferlen; /* 1. Retrieve FW header. */ pfirmware->pfwheader = ( struct fw_hdr * ) puc_mappedfile; pfwheader = pfirmware->pfwheader; pfirmware->firmwareversion = byte( pfwheader->version ,0 ); pfirmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */ RT_TRACE( COMP_INIT, DBG_DMESG, ( "signature:%x, version:%x, size:%x," "imemsize:%x, sram size:%x\n", pfwheader->signature, pfirmware->firmwareversion, pfwheader->dmem_size, pfwheader->img_imem_size, pfwheader->img_sram_size ) ); /* 2. Retrieve IMEM image. */ if ( ( pfwheader->img_imem_size == 0 ) || ( pfwheader->img_imem_size > sizeof( pfirmware->fw_imem ) ) ) { RT_TRACE( COMP_ERR, DBG_EMERG, ( "memory for data image is less than IMEM required\n" ) ); goto fail; } else { puc_mappedfile += fwhdr_size; memcpy( pfirmware->fw_imem, puc_mappedfile, pfwheader->img_imem_size ); pfirmware->fw_imem_len = pfwheader->img_imem_size; } /* 3. Retriecve EMEM image. */ if ( pfwheader->img_sram_size > sizeof( pfirmware->fw_emem ) ) { RT_TRACE( COMP_ERR, DBG_EMERG, ( "memory for data image is less than EMEM required\n" ) ); goto fail; } else { puc_mappedfile += pfirmware->fw_imem_len; memcpy( pfirmware->fw_emem, puc_mappedfile, pfwheader->img_sram_size ); pfirmware->fw_emem_len = pfwheader->img_sram_size; } /* 4. download fw now */ fwstatus = _rtl92s_firmware_get_nextstatus( pfirmware->fwstatus ); while( fwstatus != FW_STATUS_READY ) { /* Image buffer redirection. */ switch ( fwstatus ) { case FW_STATUS_LOAD_IMEM: puc_mappedfile = pfirmware->fw_imem; ul_filelength = pfirmware->fw_imem_len; break; case FW_STATUS_LOAD_EMEM: puc_mappedfile = pfirmware->fw_emem; ul_filelength = pfirmware->fw_emem_len; break; case FW_STATUS_LOAD_DMEM: /* Partial update the content of header private. */ pfwheader = pfirmware->pfwheader; pfw_priv = &pfwheader->fwpriv; _rtl92s_firmwareheader_priveupdate( hw, pfw_priv ); puc_mappedfile = ( u8 * )( pfirmware->pfwheader ) + RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; ul_filelength = fwhdr_size - RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; break; default: RT_TRACE( COMP_ERR, DBG_EMERG, ( "Unexpected Download step!!\n" ) ); goto fail; break; } /* <2> Download image file */ rtstatus = _rtl92s_firmware_downloadcode( hw, puc_mappedfile, ul_filelength ); if ( rtstatus != true ) { RT_TRACE( COMP_ERR, DBG_EMERG, ( "fail ! \n" ) ); goto fail; } /* <3> Check whether load FW process is ready */ rtstatus = _rtl92s_firmware_checkready( hw, fwstatus ); if ( rtstatus != true ) { RT_TRACE( COMP_ERR, DBG_EMERG, ( "fail ! \n" ) ); goto fail; } fwstatus = _rtl92s_firmware_get_nextstatus( pfirmware->fwstatus ); } return rtstatus; fail: return 0; }
int rtl92s_download_fw(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); struct rt_firmware *firmware = NULL; struct fw_hdr *pfwheader; struct fw_priv *pfw_priv = NULL; u8 *puc_mappedfile = NULL; u32 ul_filelength = 0; u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE; u8 fwstatus = FW_STATUS_INIT; int err = 0; if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return -EINVAL; firmware = (struct rt_firmware *)rtlhal->pfirmware; firmware->fwstatus = FW_STATUS_INIT; puc_mappedfile = firmware->sz_fw_tmpbuffer; /* 1. Retrieve FW header. */ firmware->pfwheader = (struct fw_hdr *) puc_mappedfile; pfwheader = firmware->pfwheader; firmware->firmwareversion = le16_to_cpu(pfwheader->version); pfwheader->fwpriv.usb_ep_num = rtlusb->in_ep_nums + rtlusb->out_ep_nums; pfwheader->fwpriv.mp_mode = 0; pfwheader->fwpriv.turbo_mode = 0; pfwheader->fwpriv.beacon_offload = 0; pfwheader->fwpriv.mlme_offload = 0; pfwheader->fwpriv.hwpc_offload = 0; firmware->fw_imem_len = le32_to_cpu(pfwheader->img_imem_size); firmware->fw_emem_len = le32_to_cpu(pfwheader->img_sram_size); firmware->fw_dmem_len = le32_to_cpu(pfwheader->dmem_size); /* 2. Retrieve IMEM image. */ if ((firmware->fw_imem_len == 0) || (firmware->fw_imem_len > sizeof(firmware->fw_imem))) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "memory for data image is less than IMEM required\n"); err = -EINVAL; goto fail; } else { puc_mappedfile += fwhdr_size; memcpy(firmware->fw_imem, puc_mappedfile, firmware->fw_imem_len); } /* 3. Retrieve EMEM image. */ if (firmware->fw_emem_len > sizeof(firmware->fw_emem)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "memory for data image is less than EMEM required\n"); err = -EINVAL; goto fail; } else { puc_mappedfile += firmware->fw_imem_len; memcpy(firmware->fw_emem, puc_mappedfile, firmware->fw_emem_len); } /* 4. download fw now */ fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus); while (fwstatus != FW_STATUS_READY) { /* Image buffer redirection. */ switch (fwstatus) { case FW_STATUS_LOAD_IMEM: puc_mappedfile = firmware->fw_imem; ul_filelength = firmware->fw_imem_len; break; case FW_STATUS_LOAD_EMEM: puc_mappedfile = firmware->fw_emem; ul_filelength = firmware->fw_emem_len; break; case FW_STATUS_LOAD_DMEM: /* Partial update the content of header private. */ pfwheader = firmware->pfwheader; pfw_priv = &pfwheader->fwpriv; _rtl92s_firmwareheader_priveupdate(hw, pfw_priv); puc_mappedfile = (u8 *)(firmware->pfwheader) + RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; ul_filelength = fwhdr_size - RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; break; default: err = -EINVAL; RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Unexpected Download step!!\n"); goto fail; break; } /* <2> Download image file */ err = _rtl92s_firmware_downloadcode(hw, puc_mappedfile, ul_filelength); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fw download failed (%d)!\n", err); goto fail; } /* <3> Check whether load FW process is ready */ err = _rtl92s_firmware_checkready(hw, fwstatus); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fw not ready (%d)!\n", err); goto fail; } fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus); } return 0; fail: return err; }