0001
0002
0003
0004 #include "../wifi.h"
0005 #include "../pci.h"
0006 #include "../base.h"
0007 #include "../efuse.h"
0008 #include "fw_common.h"
0009 #include <linux/module.h>
0010
0011 void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable)
0012 {
0013 struct rtl_priv *rtlpriv = rtl_priv(hw);
0014 u8 tmp;
0015
0016 if (enable) {
0017 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0018 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
0019 tmp | 0x04);
0020
0021 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
0022 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
0023
0024 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
0025 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
0026 } else {
0027 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
0028 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
0029
0030 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
0031 }
0032 }
0033 EXPORT_SYMBOL_GPL(rtl8723_enable_fw_download);
0034
0035 void rtl8723_write_fw(struct ieee80211_hw *hw,
0036 enum version_8723e version,
0037 u8 *buffer, u32 size, u8 max_page)
0038 {
0039 struct rtl_priv *rtlpriv = rtl_priv(hw);
0040 u8 *bufferptr = buffer;
0041 u32 page_nums, remain_size;
0042 u32 page, offset;
0043
0044 rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
0045
0046 rtl_fill_dummy(bufferptr, &size);
0047
0048 page_nums = size / FW_8192C_PAGE_SIZE;
0049 remain_size = size % FW_8192C_PAGE_SIZE;
0050
0051 if (page_nums > max_page) {
0052 pr_err("Page numbers should not greater than %d\n",
0053 max_page);
0054 }
0055 for (page = 0; page < page_nums; page++) {
0056 offset = page * FW_8192C_PAGE_SIZE;
0057 rtl_fw_page_write(hw, page, (bufferptr + offset),
0058 FW_8192C_PAGE_SIZE);
0059 }
0060
0061 if (remain_size) {
0062 offset = page_nums * FW_8192C_PAGE_SIZE;
0063 page = page_nums;
0064 rtl_fw_page_write(hw, page, (bufferptr + offset), remain_size);
0065 }
0066 rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n");
0067 }
0068 EXPORT_SYMBOL_GPL(rtl8723_write_fw);
0069
0070 void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw)
0071 {
0072 u8 u1b_tmp;
0073 u8 delay = 100;
0074 struct rtl_priv *rtlpriv = rtl_priv(hw);
0075
0076 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
0077 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0078
0079 while (u1b_tmp & BIT(2)) {
0080 delay--;
0081 if (delay == 0)
0082 break;
0083 udelay(50);
0084 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0085 }
0086 if (delay == 0) {
0087 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0088 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
0089 u1b_tmp&(~BIT(2)));
0090 }
0091 }
0092 EXPORT_SYMBOL_GPL(rtl8723ae_firmware_selfreset);
0093
0094 void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw)
0095 {
0096 u8 u1b_tmp;
0097 struct rtl_priv *rtlpriv = rtl_priv(hw);
0098
0099 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
0100 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
0101
0102 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0103 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
0104 udelay(50);
0105
0106 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
0107 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0)));
0108
0109 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0110 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2)));
0111
0112 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
0113 "_8051Reset8723be(): 8051 reset success .\n");
0114 }
0115 EXPORT_SYMBOL_GPL(rtl8723be_firmware_selfreset);
0116
0117 int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be,
0118 int max_count)
0119 {
0120 struct rtl_priv *rtlpriv = rtl_priv(hw);
0121 int err = -EIO;
0122 u32 counter = 0;
0123 u32 value32;
0124
0125 do {
0126 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0127 } while ((counter++ < max_count) &&
0128 (!(value32 & FWDL_CHKSUM_RPT)));
0129
0130 if (counter >= max_count) {
0131 pr_err("chksum report fail ! REG_MCUFWDL:0x%08x .\n",
0132 value32);
0133 goto exit;
0134 }
0135 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL) | MCUFWDL_RDY;
0136 value32 &= ~WINTINI_RDY;
0137 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
0138
0139 if (is_8723be)
0140 rtl8723be_firmware_selfreset(hw);
0141 counter = 0;
0142
0143 do {
0144 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0145 if (value32 & WINTINI_RDY) {
0146 rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE,
0147 "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",
0148 value32);
0149 err = 0;
0150 goto exit;
0151 }
0152
0153 mdelay(FW_8192C_POLLING_DELAY);
0154
0155 } while (counter++ < max_count);
0156
0157 pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n",
0158 value32);
0159
0160 exit:
0161 return err;
0162 }
0163 EXPORT_SYMBOL_GPL(rtl8723_fw_free_to_go);
0164
0165 int rtl8723_download_fw(struct ieee80211_hw *hw,
0166 bool is_8723be, int max_count)
0167 {
0168 struct rtl_priv *rtlpriv = rtl_priv(hw);
0169 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0170 struct rtlwifi_firmware_header *pfwheader;
0171 u8 *pfwdata;
0172 u32 fwsize;
0173 int err;
0174 enum version_8723e version = rtlhal->version;
0175 int max_page;
0176
0177 if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
0178 return 1;
0179
0180 pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
0181 rtlhal->fw_version = le16_to_cpu(pfwheader->version);
0182 rtlhal->fw_subversion = pfwheader->subversion;
0183 pfwdata = rtlhal->pfirmware;
0184 fwsize = rtlhal->fwsize;
0185
0186 if (!is_8723be)
0187 max_page = 6;
0188 else
0189 max_page = 8;
0190 if (rtlpriv->cfg->ops->is_fw_header(pfwheader)) {
0191 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD,
0192 "Firmware Version(%d), Signature(%#x), Size(%d)\n",
0193 pfwheader->version, pfwheader->signature,
0194 (int)sizeof(struct rtlwifi_firmware_header));
0195
0196 pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
0197 fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
0198 }
0199
0200 if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) {
0201 if (is_8723be)
0202 rtl8723be_firmware_selfreset(hw);
0203 else
0204 rtl8723ae_firmware_selfreset(hw);
0205 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
0206 }
0207 rtl8723_enable_fw_download(hw, true);
0208 rtl8723_write_fw(hw, version, pfwdata, fwsize, max_page);
0209 rtl8723_enable_fw_download(hw, false);
0210
0211 err = rtl8723_fw_free_to_go(hw, is_8723be, max_count);
0212 if (err)
0213 pr_err("Firmware is not ready to run!\n");
0214 return 0;
0215 }
0216 EXPORT_SYMBOL_GPL(rtl8723_download_fw);
0217
0218 bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw,
0219 struct sk_buff *skb)
0220 {
0221 struct rtl_priv *rtlpriv = rtl_priv(hw);
0222 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
0223 struct rtl8192_tx_ring *ring;
0224 struct rtl_tx_desc *pdesc;
0225 struct sk_buff *pskb = NULL;
0226 unsigned long flags;
0227
0228 ring = &rtlpci->tx_ring[BEACON_QUEUE];
0229
0230 pskb = __skb_dequeue(&ring->queue);
0231 kfree_skb(pskb);
0232 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
0233
0234 pdesc = &ring->desc[0];
0235 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
0236
0237 __skb_queue_tail(&ring->queue, skb);
0238
0239 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
0240
0241 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
0242
0243 return true;
0244 }
0245 EXPORT_SYMBOL_GPL(rtl8723_cmd_send_packet);