Esempio n. 1
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 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;
}
Esempio n. 2
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;
}