diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 62 | 
1 files changed, 49 insertions, 13 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 950c65a15b8..931d97979b0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -73,6 +73,34 @@ static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)  	}  } +static void rtl_block_fw_writeN(struct ieee80211_hw *hw, const u8 *buffer, +				u32 size) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 blockSize = REALTEK_USB_VENQT_MAX_BUF_SIZE - 20; +	u8 *bufferPtr = (u8 *) buffer; +	u32 i, offset, blockCount, remainSize; + +	blockCount = size / blockSize; +	remainSize = size % blockSize; + +	for (i = 0; i < blockCount; i++) { +		offset = i * blockSize; +		rtlpriv->io.writeN_sync(rtlpriv, +					(FW_8192C_START_ADDRESS + offset), +					(void *)(bufferPtr + offset), +					blockSize); +	} + +	if (remainSize) { +		offset = blockCount * blockSize; +		rtlpriv->io.writeN_sync(rtlpriv, +					(FW_8192C_START_ADDRESS + offset), +					(void *)(bufferPtr + offset), +					remainSize); +	} +} +  static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,  				   const u8 *buffer, u32 size)  { @@ -81,23 +109,30 @@ static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,  	u8 *bufferPtr = (u8 *) buffer;  	u32 *pu4BytePtr = (u32 *) buffer;  	u32 i, offset, blockCount, remainSize; +	u32 data; +	if (rtlpriv->io.writeN_sync) { +		rtl_block_fw_writeN(hw, buffer, size); +		return; +	}  	blockCount = size / blockSize;  	remainSize = size % blockSize; +	if (remainSize) { +		/* the last word is < 4 bytes - pad it with zeros */ +		for (i = 0; i < 4 - remainSize; i++) +			*(bufferPtr + size + i) = 0; +		blockCount++; +	}  	for (i = 0; i < blockCount; i++) {  		offset = i * blockSize; +		/* for big-endian platforms, the firmware data need to be byte +		 * swapped as it was read as a byte string and will be written +		 * as 32-bit dwords and byte swapped when written +		 */ +		data = le32_to_cpu(*(__le32 *)(pu4BytePtr + i));  		rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), -				*(pu4BytePtr + i)); -	} - -	if (remainSize) { -		offset = blockCount * blockSize; -		bufferPtr += offset; -		for (i = 0; i < remainSize; i++) { -			rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + -						 offset + i), *(bufferPtr + i)); -		} +				data);  	}  } @@ -227,10 +262,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)  	u32 fwsize;  	enum version_8192c version = rtlhal->version; -	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);  	if (!rtlhal->pfirmware)  		return 1; +	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);  	pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;  	pfwdata = (u8 *) rtlhal->pfirmware;  	fwsize = rtlhal->fwsize; @@ -238,8 +273,9 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)  	if (IS_FW_HEADER_EXIST(pfwheader)) {  		RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,  			 ("Firmware Version(%d), Signature(%#x),Size(%d)\n", -			  pfwheader->version, pfwheader->signature, -			  (uint)sizeof(struct rtl92c_firmware_header))); +			 le16_to_cpu(pfwheader->version), +			 le16_to_cpu(pfwheader->signature), +			 (uint)sizeof(struct rtl92c_firmware_header)));  		pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);  		fwsize = fwsize - sizeof(struct rtl92c_firmware_header);  |