aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c')
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c63
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
76static 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
75static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, 104static 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);