diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 49a064bdbce6..931d97979b04 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
31 | 31 | ||
32 | #include <linux/firmware.h> | 32 | #include <linux/firmware.h> |
33 | #include <linux/export.h> | ||
33 | #include "../wifi.h" | 34 | #include "../wifi.h" |
34 | #include "../pci.h" | 35 | #include "../pci.h" |
35 | #include "../base.h" | 36 | #include "../base.h" |
@@ -72,6 +73,34 @@ static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) | |||
72 | } | 73 | } |
73 | } | 74 | } |
74 | 75 | ||
76 | static void rtl_block_fw_writeN(struct ieee80211_hw *hw, const u8 *buffer, | ||
77 | u32 size) | ||
78 | { | ||
79 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
80 | u32 blockSize = REALTEK_USB_VENQT_MAX_BUF_SIZE - 20; | ||
81 | u8 *bufferPtr = (u8 *) buffer; | ||
82 | u32 i, offset, blockCount, remainSize; | ||
83 | |||
84 | blockCount = size / blockSize; | ||
85 | remainSize = size % blockSize; | ||
86 | |||
87 | for (i = 0; i < blockCount; i++) { | ||
88 | offset = i * blockSize; | ||
89 | rtlpriv->io.writeN_sync(rtlpriv, | ||
90 | (FW_8192C_START_ADDRESS + offset), | ||
91 | (void *)(bufferPtr + offset), | ||
92 | blockSize); | ||
93 | } | ||
94 | |||
95 | if (remainSize) { | ||
96 | offset = blockCount * blockSize; | ||
97 | rtlpriv->io.writeN_sync(rtlpriv, | ||
98 | (FW_8192C_START_ADDRESS + offset), | ||
99 | (void *)(bufferPtr + offset), | ||
100 | remainSize); | ||
101 | } | ||
102 | } | ||
103 | |||
75 | static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, | 104 | static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, |
76 | const u8 *buffer, u32 size) | 105 | const u8 *buffer, u32 size) |
77 | { | 106 | { |
@@ -80,23 +109,30 @@ static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, | |||
80 | u8 *bufferPtr = (u8 *) buffer; | 109 | u8 *bufferPtr = (u8 *) buffer; |
81 | u32 *pu4BytePtr = (u32 *) buffer; | 110 | u32 *pu4BytePtr = (u32 *) buffer; |
82 | u32 i, offset, blockCount, remainSize; | 111 | u32 i, offset, blockCount, remainSize; |
112 | u32 data; | ||
83 | 113 | ||
114 | if (rtlpriv->io.writeN_sync) { | ||
115 | rtl_block_fw_writeN(hw, buffer, size); | ||
116 | return; | ||
117 | } | ||
84 | blockCount = size / blockSize; | 118 | blockCount = size / blockSize; |
85 | remainSize = size % blockSize; | 119 | remainSize = size % blockSize; |
120 | if (remainSize) { | ||
121 | /* the last word is < 4 bytes - pad it with zeros */ | ||
122 | for (i = 0; i < 4 - remainSize; i++) | ||
123 | *(bufferPtr + size + i) = 0; | ||
124 | blockCount++; | ||
125 | } | ||
86 | 126 | ||
87 | for (i = 0; i < blockCount; i++) { | 127 | for (i = 0; i < blockCount; i++) { |
88 | offset = i * blockSize; | 128 | offset = i * blockSize; |
129 | /* for big-endian platforms, the firmware data need to be byte | ||
130 | * swapped as it was read as a byte string and will be written | ||
131 | * as 32-bit dwords and byte swapped when written | ||
132 | */ | ||
133 | data = le32_to_cpu(*(__le32 *)(pu4BytePtr + i)); | ||
89 | rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), | 134 | rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), |
90 | *(pu4BytePtr + i)); | 135 | data); |
91 | } | ||
92 | |||
93 | if (remainSize) { | ||
94 | offset = blockCount * blockSize; | ||
95 | bufferPtr += offset; | ||
96 | for (i = 0; i < remainSize; i++) { | ||
97 | rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + | ||
98 | offset + i), *(bufferPtr + i)); | ||
99 | } | ||
100 | } | 136 | } |
101 | } | 137 | } |
102 | 138 | ||
@@ -226,10 +262,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) | |||
226 | u32 fwsize; | 262 | u32 fwsize; |
227 | enum version_8192c version = rtlhal->version; | 263 | enum version_8192c version = rtlhal->version; |
228 | 264 | ||
229 | pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); | ||
230 | if (!rtlhal->pfirmware) | 265 | if (!rtlhal->pfirmware) |
231 | return 1; | 266 | return 1; |
232 | 267 | ||
268 | pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); | ||
233 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; | 269 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; |
234 | pfwdata = (u8 *) rtlhal->pfirmware; | 270 | pfwdata = (u8 *) rtlhal->pfirmware; |
235 | fwsize = rtlhal->fwsize; | 271 | fwsize = rtlhal->fwsize; |
@@ -237,8 +273,9 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) | |||
237 | if (IS_FW_HEADER_EXIST(pfwheader)) { | 273 | if (IS_FW_HEADER_EXIST(pfwheader)) { |
238 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, | 274 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, |
239 | ("Firmware Version(%d), Signature(%#x),Size(%d)\n", | 275 | ("Firmware Version(%d), Signature(%#x),Size(%d)\n", |
240 | pfwheader->version, pfwheader->signature, | 276 | le16_to_cpu(pfwheader->version), |
241 | (uint)sizeof(struct rtl92c_firmware_header))); | 277 | le16_to_cpu(pfwheader->signature), |
278 | (uint)sizeof(struct rtl92c_firmware_header))); | ||
242 | 279 | ||
243 | pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); | 280 | pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); |
244 | fwsize = fwsize - sizeof(struct rtl92c_firmware_header); | 281 | fwsize = fwsize - sizeof(struct rtl92c_firmware_header); |