aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/def.h5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.c260
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.h18
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/Makefile1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c540
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h106
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h3
11 files changed, 142 insertions, 805 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
index 8c110356dff9..debe261a7eeb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
@@ -46,11 +46,6 @@
46#define E_CUT_VERSION BIT(14) 46#define E_CUT_VERSION BIT(14)
47#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) 47#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28))
48 48
49enum version_8723e {
50 VERSION_TEST_UMC_CHIP_8723 = 0x0081,
51 VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089,
52 VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089,
53};
54 49
55/* MASK */ 50/* MASK */
56#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) 51#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2))
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
index ba1502b172a6..728b7563ad36 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c
@@ -34,199 +34,7 @@
34#include "reg.h" 34#include "reg.h"
35#include "def.h" 35#include "def.h"
36#include "fw.h" 36#include "fw.h"
37 37#include "../rtl8723com/fw_common.h"
38static void _rtl8723ae_enable_fw_download(struct ieee80211_hw *hw, bool enable)
39{
40 struct rtl_priv *rtlpriv = rtl_priv(hw);
41 u8 tmp;
42 if (enable) {
43 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
44 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
45
46 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
47 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
48
49 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
50 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
51 } else {
52 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
53 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
54
55 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
56 }
57}
58
59static void _rtl8723ae_fw_block_write(struct ieee80211_hw *hw,
60 const u8 *buffer, u32 size)
61{
62 struct rtl_priv *rtlpriv = rtl_priv(hw);
63 u32 blockSize = sizeof(u32);
64 u8 *bufferPtr = (u8 *) buffer;
65 u32 *pu4BytePtr = (u32 *) buffer;
66 u32 i, offset, blockCount, remainSize;
67
68 blockCount = size / blockSize;
69 remainSize = size % blockSize;
70
71 for (i = 0; i < blockCount; i++) {
72 offset = i * blockSize;
73 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
74 *(pu4BytePtr + i));
75 }
76
77 if (remainSize) {
78 offset = blockCount * blockSize;
79 bufferPtr += offset;
80 for (i = 0; i < remainSize; i++) {
81 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
82 offset + i), *(bufferPtr + i));
83 }
84 }
85}
86
87static void _rtl8723ae_fw_page_write(struct ieee80211_hw *hw,
88 u32 page, const u8 *buffer, u32 size)
89{
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 u8 value8;
92 u8 u8page = (u8) (page & 0x07);
93
94 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
95
96 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
97 _rtl8723ae_fw_block_write(hw, buffer, size);
98}
99
100static void _rtl8723ae_write_fw(struct ieee80211_hw *hw,
101 enum version_8723e version, u8 *buffer,
102 u32 size)
103{
104 struct rtl_priv *rtlpriv = rtl_priv(hw);
105 u8 *bufferPtr = (u8 *) buffer;
106 u32 page_nums, remain_size;
107 u32 page, offset;
108
109 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
110
111 page_nums = size / FW_8192C_PAGE_SIZE;
112 remain_size = size % FW_8192C_PAGE_SIZE;
113
114 if (page_nums > 6) {
115 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
116 "Page numbers should not be greater then 6\n");
117 }
118
119 for (page = 0; page < page_nums; page++) {
120 offset = page * FW_8192C_PAGE_SIZE;
121 _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset),
122 FW_8192C_PAGE_SIZE);
123 }
124
125 if (remain_size) {
126 offset = page_nums * FW_8192C_PAGE_SIZE;
127 page = page_nums;
128 _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset),
129 remain_size);
130 }
131
132 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n");
133}
134
135static int _rtl8723ae_fw_free_to_go(struct ieee80211_hw *hw)
136{
137 struct rtl_priv *rtlpriv = rtl_priv(hw);
138 int err = -EIO;
139 u32 counter = 0;
140 u32 value32;
141
142 do {
143 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
144 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
145 (!(value32 & FWDL_ChkSum_rpt)));
146
147 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
148 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
149 "chksum report faill ! REG_MCUFWDL:0x%08x .\n",
150 value32);
151 goto exit;
152 }
153
154 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
155 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
156
157 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
158 value32 |= MCUFWDL_RDY;
159 value32 &= ~WINTINI_RDY;
160 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
161
162 counter = 0;
163
164 do {
165 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
166 if (value32 & WINTINI_RDY) {
167 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
168 "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n",
169 value32);
170 err = 0;
171 goto exit;
172 }
173
174 mdelay(FW_8192C_POLLING_DELAY);
175
176 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
177
178 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
179 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32);
180
181exit:
182 return err;
183}
184
185int rtl8723ae_download_fw(struct ieee80211_hw *hw)
186{
187 struct rtl_priv *rtlpriv = rtl_priv(hw);
188 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
189 struct rtl8723ae_firmware_header *pfwheader;
190 u8 *pfwdata;
191 u32 fwsize;
192 int err;
193 enum version_8723e version = rtlhal->version;
194
195 if (!rtlhal->pfirmware)
196 return 1;
197
198 pfwheader = (struct rtl8723ae_firmware_header *)rtlhal->pfirmware;
199 pfwdata = (u8 *) rtlhal->pfirmware;
200 fwsize = rtlhal->fwsize;
201
202 if (IS_FW_HEADER_EXIST(pfwheader)) {
203 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
204 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
205 pfwheader->version, pfwheader->signature,
206 (int)sizeof(struct rtl8723ae_firmware_header));
207
208 pfwdata = pfwdata + sizeof(struct rtl8723ae_firmware_header);
209 fwsize = fwsize - sizeof(struct rtl8723ae_firmware_header);
210 }
211
212 if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) {
213 rtl8723ae_firmware_selfreset(hw);
214 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
215 }
216 _rtl8723ae_enable_fw_download(hw, true);
217 _rtl8723ae_write_fw(hw, version, pfwdata, fwsize);
218 _rtl8723ae_enable_fw_download(hw, false);
219
220 err = _rtl8723ae_fw_free_to_go(hw);
221 if (err) {
222 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
223 "Firmware is not ready to run!\n");
224 } else {
225 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
226 "Firmware is ready to run!\n");
227 }
228 return 0;
229}
230 38
231static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) 39static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
232{ 40{
@@ -463,50 +271,6 @@ void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw,
463 return; 271 return;
464} 272}
465 273
466void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw)
467{
468 u8 u1tmp;
469 u8 delay = 100;
470 struct rtl_priv *rtlpriv = rtl_priv(hw);
471
472 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
473 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
474
475 while (u1tmp & BIT(2)) {
476 delay--;
477 if (delay == 0)
478 break;
479 udelay(50);
480 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
481 }
482 if (delay == 0) {
483 u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
484 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2)));
485 }
486}
487
488void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
489{
490 struct rtl_priv *rtlpriv = rtl_priv(hw);
491 u8 u1_h2c_set_pwrmode[3] = { 0 };
492 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
493
494 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
495
496 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
497 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
498 (rtlpriv->mac80211.p2p) ?
499 ppsc->smart_ps : 1);
500 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
501 ppsc->reg_max_lps_awakeintvl);
502
503 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
504 "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
505 u1_h2c_set_pwrmode, 3);
506 rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
507
508}
509
510static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw, 274static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw,
511 struct sk_buff *skb) 275 struct sk_buff *skb)
512{ 276{
@@ -812,7 +576,6 @@ void rtl8723ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
812 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); 576 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
813 577
814 p2p_ps_offload->offload_en = 1; 578 p2p_ps_offload->offload_en = 1;
815
816 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { 579 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
817 p2p_ps_offload->role = 1; 580 p2p_ps_offload->role = 1;
818 p2p_ps_offload->allstasleep = 0; 581 p2p_ps_offload->allstasleep = 0;
@@ -836,3 +599,24 @@ void rtl8723ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
836 } 599 }
837 rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload); 600 rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
838} 601}
602
603void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
604{
605 struct rtl_priv *rtlpriv = rtl_priv(hw);
606 u8 u1_h2c_set_pwrmode[3] = { 0 };
607 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
608
609 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
610
611 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
612 SET_H2CCMD_PWRMODE_PARM_SMART_PS_23A(u1_h2c_set_pwrmode,
613 (rtlpriv->mac80211.p2p) ?
614 ppsc->smart_ps : 1);
615 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
616 ppsc->reg_max_lps_awakeintvl);
617
618 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
619 "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
620 u1_h2c_set_pwrmode, 3);
621 rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
622}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
index ed3b795e6980..d355b85dd9fe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h
@@ -34,7 +34,7 @@
34#define FW_8192C_END_ADDRESS 0x3FFF 34#define FW_8192C_END_ADDRESS 0x3FFF
35#define FW_8192C_PAGE_SIZE 4096 35#define FW_8192C_PAGE_SIZE 4096
36#define FW_8192C_POLLING_DELAY 5 36#define FW_8192C_POLLING_DELAY 5
37#define FW_8192C_POLLING_TIMEOUT_COUNT 1000 37#define FW_8192C_POLLING_TIMEOUT_COUNT 6000
38 38
39#define BEACON_PG 0 39#define BEACON_PG 0
40#define PSPOLL_PG 2 40#define PSPOLL_PG 2
@@ -65,21 +65,9 @@ struct rtl8723ae_firmware_header {
65 u32 rsvd5; 65 u32 rsvd5;
66}; 66};
67 67
68enum rtl8192c_h2c_cmd {
69 H2C_AP_OFFLOAD = 0,
70 H2C_SETPWRMODE = 1,
71 H2C_JOINBSSRPT = 2,
72 H2C_RSVDPAGE = 3,
73 H2C_RSSI_REPORT = 4,
74 H2C_P2P_PS_CTW_CMD = 5,
75 H2C_P2P_PS_OFFLOAD = 6,
76 H2C_RA_MASK = 7,
77 MAX_H2CCMD
78};
79
80#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ 68#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
81 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) 69 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
82#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ 70#define SET_H2CCMD_PWRMODE_PARM_SMART_PS_23A(__ph2ccmd, __val) \
83 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) 71 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
84#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ 72#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
85 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) 73 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
@@ -92,10 +80,8 @@ enum rtl8192c_h2c_cmd {
92#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ 80#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
93 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) 81 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
94 82
95int rtl8723ae_download_fw(struct ieee80211_hw *hw);
96void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, 83void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
97 u32 cmd_len, u8 *p_cmdbuffer); 84 u32 cmd_len, u8 *p_cmdbuffer);
98void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
99void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); 85void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
100void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); 86void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
101void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); 87void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
index 3d092e4b0b7f..48fee1be78c2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c
@@ -31,6 +31,8 @@
31#include "../pci.h" 31#include "../pci.h"
32#include "dm.h" 32#include "dm.h"
33#include "fw.h" 33#include "fw.h"
34#include "../rtl8723com/fw_common.h"
35#include "../rtl8723com/fw_common.h"
34#include "phy.h" 36#include "phy.h"
35#include "reg.h" 37#include "reg.h"
36#include "hal_btc.h" 38#include "hal_btc.h"
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
index 8b64b1cd3176..5d534df8d90c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
@@ -32,6 +32,7 @@
32#include "phy.h" 32#include "phy.h"
33#include "../rtl8723com/phy_common.h" 33#include "../rtl8723com/phy_common.h"
34#include "fw.h" 34#include "fw.h"
35#include "../rtl8723com/fw_common.h"
35#include "reg.h" 36#include "reg.h"
36#include "def.h" 37#include "def.h"
37 38
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index 914b36f72d55..7eff1c51539c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -39,6 +39,7 @@
39#include "phy.h" 39#include "phy.h"
40#include "dm.h" 40#include "dm.h"
41#include "fw.h" 41#include "fw.h"
42#include "../rtl8723com/fw_common.h"
42#include "led.h" 43#include "led.h"
43#include "hw.h" 44#include "hw.h"
44#include "pwrseqcmd.h" 45#include "pwrseqcmd.h"
@@ -890,7 +891,7 @@ int rtl8723ae_hw_init(struct ieee80211_hw *hw)
890 return err; 891 return err;
891 } 892 }
892 893
893 err = rtl8723ae_download_fw(hw); 894 err = rtl8723_download_fw(hw, false);
894 if (err) { 895 if (err) {
895 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 896 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
896 "Failed to download FW. Init HW without FW now..\n"); 897 "Failed to download FW. Init HW without FW now..\n");
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
index 0b97c9acebaa..1087a3bd07fa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
@@ -40,6 +40,8 @@
40#include "../rtl8723com/phy_common.h" 40#include "../rtl8723com/phy_common.h"
41#include "dm.h" 41#include "dm.h"
42#include "hw.h" 42#include "hw.h"
43#include "fw.h"
44#include "../rtl8723com/fw_common.h"
43#include "sw.h" 45#include "sw.h"
44#include "trx.h" 46#include "trx.h"
45#include "led.h" 47#include "led.h"
@@ -194,6 +196,11 @@ void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw)
194 } 196 }
195} 197}
196 198
199static bool is_fw_header(struct rtl92c_firmware_header *hdr)
200{
201 return (hdr->signature & 0xfff0) == 0x2300;
202}
203
197static struct rtl_hal_ops rtl8723ae_hal_ops = { 204static struct rtl_hal_ops rtl8723ae_hal_ops = {
198 .init_sw_vars = rtl8723ae_init_sw_vars, 205 .init_sw_vars = rtl8723ae_init_sw_vars,
199 .deinit_sw_vars = rtl8723ae_deinit_sw_vars, 206 .deinit_sw_vars = rtl8723ae_deinit_sw_vars,
@@ -239,6 +246,7 @@ static struct rtl_hal_ops rtl8723ae_hal_ops = {
239 .c2h_command_handle = rtl_8723e_c2h_command_handle, 246 .c2h_command_handle = rtl_8723e_c2h_command_handle,
240 .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify, 247 .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify,
241 .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps, 248 .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps,
249 .is_fw_header = is_fw_header,
242}; 250};
243 251
244static struct rtl_mod_params rtl8723ae_mod_params = { 252static struct rtl_mod_params rtl8723ae_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/Makefile b/drivers/net/wireless/rtlwifi/rtl8723com/Makefile
index 00673c692e6b..97c7eaceb430 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/Makefile
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/Makefile
@@ -1,5 +1,6 @@
1rtl8723-common-objs := \ 1rtl8723-common-objs := \
2 main.o \ 2 main.o \
3 fw_common.o \
3 phy_common.o 4 phy_common.o
4 5
5obj-$(CONFIG_RTL8723_COMMON) += rtl8723-common.o 6obj-$(CONFIG_RTL8723_COMMON) += rtl8723-common.o
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c
index 83ca4e25ee50..32c390ffc7d2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c
@@ -24,126 +24,11 @@
24 *****************************************************************************/ 24 *****************************************************************************/
25 25
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
27#include "fw_common.h" 29#include "fw_common.h"
28#include <linux/module.h> 30#include <linux/module.h>
29 31
30#define BEACON_PG 0 /* ->1 */
31#define PSPOLL_PG 2
32#define NULL_PG 3
33#define PROBERSP_PG 4 /* ->5 */
34
35#define TOTAL_RESERVED_PKT_LEN 768
36
37static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
38 /* page 0 beacon */
39 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
40 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
41 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
44 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
45 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
46 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
47 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
48 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
52 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
53 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
54 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
55
56 /* page 1 beacon */
57 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73
74 /* page 2 ps-poll */
75 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
76 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91
92 /* page 3 null */
93 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
94 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
95 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109
110 /* page 4 probe_resp */
111 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
112 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
113 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
114 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
115 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
116 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
117 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
118 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
119 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
120 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
121 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
125 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127
128 /* page 5 probe_resp */
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145};
146
147void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable) 32void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable)
148{ 33{
149 struct rtl_priv *rtlpriv = rtl_priv(hw); 34 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -226,7 +111,7 @@ static void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
226} 111}
227 112
228void rtl8723_write_fw(struct ieee80211_hw *hw, 113void rtl8723_write_fw(struct ieee80211_hw *hw,
229 enum version_8723be version, 114 enum version_8723e version,
230 u8 *buffer, u32 size) 115 u8 *buffer, u32 size)
231{ 116{
232 struct rtl_priv *rtlpriv = rtl_priv(hw); 117 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -236,7 +121,7 @@ void rtl8723_write_fw(struct ieee80211_hw *hw,
236 121
237 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size); 122 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
238 123
239 _rtl8723be_fill_dummy(bufferptr, &size); 124 rtl8723_fill_dummy(bufferptr, &size);
240 125
241 pagenums = size / FW_8192C_PAGE_SIZE; 126 pagenums = size / FW_8192C_PAGE_SIZE;
242 remainsize = size % FW_8192C_PAGE_SIZE; 127 remainsize = size % FW_8192C_PAGE_SIZE;
@@ -319,15 +204,14 @@ int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be)
319 204
320 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { 205 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
321 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 206 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
322 "chksum report faill ! REG_MCUFWDL:0x%08x .\n", 207 "chksum report fail ! REG_MCUFWDL:0x%08x .\n",
323 value32); 208 value32);
324 goto exit; 209 goto exit;
325 } 210 }
326 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, 211 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
327 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32); 212 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
328 213
329 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); 214 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL) | MCUFWDL_RDY;
330 value32 |= MCUFWDL_RDY;
331 value32 &= ~WINTINI_RDY; 215 value32 &= ~WINTINI_RDY;
332 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); 216 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
333 217
@@ -378,8 +262,8 @@ int rtl8723_download_fw(struct ieee80211_hw *hw,
378 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 262 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
379 "normal Firmware SIZE %d\n", fwsize); 263 "normal Firmware SIZE %d\n", fwsize);
380 264
381 if (IS_FW_HEADER_EXIST(pfwheader)) { 265 if (rtlpriv->cfg->ops->is_fw_header(pfwheader)) {
382 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, 266 RT_TRACE(rtlpriv, COMP_FW, DBG_EMERG,
383 "Firmware Version(%d), Signature(%#x), Size(%d)\n", 267 "Firmware Version(%d), Signature(%#x), Size(%d)\n",
384 pfwheader->version, pfwheader->signature, 268 pfwheader->version, pfwheader->signature,
385 (int)sizeof(struct rtl92c_firmware_header)); 269 (int)sizeof(struct rtl92c_firmware_header));
@@ -394,9 +278,9 @@ int rtl8723_download_fw(struct ieee80211_hw *hw,
394 else 278 else
395 rtl8723ae_firmware_selfreset(hw); 279 rtl8723ae_firmware_selfreset(hw);
396 } 280 }
397 rtl8723_enable_fw_download(hw, is_8723be); 281 rtl8723_enable_fw_download(hw, true);
398 rtl8723_write_fw(hw, version, pfwdata, fwsize); 282 rtl8723_write_fw(hw, version, pfwdata, fwsize);
399 rtl8723_enable_fw_download(hw, is_8723be); 283 rtl8723_enable_fw_download(hw, false);
400 284
401 err = rtl8723_fw_free_to_go(hw, is_8723be); 285 err = rtl8723_fw_free_to_go(hw, is_8723be);
402 if (err) { 286 if (err) {
@@ -410,219 +294,6 @@ int rtl8723_download_fw(struct ieee80211_hw *hw,
410} 294}
411EXPORT_SYMBOL_GPL(rtl8723_download_fw); 295EXPORT_SYMBOL_GPL(rtl8723_download_fw);
412 296
413bool rtl8723_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
414{
415 struct rtl_priv *rtlpriv = rtl_priv(hw);
416 u8 val_hmetfr, val_mcutst_1;
417 bool result = false;
418
419 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
420 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
421
422 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
423 result = true;
424 return result;
425}
426EXPORT_SYMBOL_GPL(rtl8723_check_fw_read_last_h2c);
427
428void rtl8723_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
429 u32 cmd_len, u8 *p_cmdbuffer)
430{
431 struct rtl_priv *rtlpriv = rtl_priv(hw);
432 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
433 u8 boxnum;
434 u16 box_reg = 0, box_extreg = 0;
435 u8 u1b_tmp;
436 bool isfw_read = false;
437 u8 buf_index = 0;
438 bool bwrite_sucess = false;
439 u8 wait_h2c_limit = 100;
440 u8 wait_writeh2c_limit = 100;
441 u8 boxcontent[4], boxextcontent[4];
442 u32 h2c_waitcounter = 0;
443 unsigned long flag;
444 u8 idx;
445
446 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
447
448 while (true) {
449 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
450 if (rtlhal->h2c_setinprogress) {
451 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
452 "H2C set in progress! Wait to set.."
453 "element_id(%d).\n", element_id);
454
455 while (rtlhal->h2c_setinprogress) {
456 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
457 flag);
458 h2c_waitcounter++;
459 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
460 "Wait 100 us (%d times)...\n",
461 h2c_waitcounter);
462 udelay(100);
463
464 if (h2c_waitcounter > 1000)
465 return;
466 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
467 flag);
468 }
469 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
470 } else {
471 rtlhal->h2c_setinprogress = true;
472 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
473 break;
474 }
475 }
476 while (!bwrite_sucess) {
477 wait_writeh2c_limit--;
478 if (wait_writeh2c_limit == 0) {
479 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
480 "Write H2C fail because no trigger "
481 "for FW INT!\n");
482 break;
483 }
484 boxnum = rtlhal->last_hmeboxnum;
485 switch (boxnum) {
486 case 0:
487 box_reg = REG_HMEBOX_0;
488 box_extreg = REG_HMEBOX_EXT_0;
489 break;
490 case 1:
491 box_reg = REG_HMEBOX_1;
492 box_extreg = REG_HMEBOX_EXT_1;
493 break;
494 case 2:
495 box_reg = REG_HMEBOX_2;
496 box_extreg = REG_HMEBOX_EXT_2;
497 break;
498 case 3:
499 box_reg = REG_HMEBOX_3;
500 box_extreg = REG_HMEBOX_EXT_3;
501 break;
502 default:
503 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
504 "switch case not processed\n");
505 break;
506 }
507 isfw_read = rtl8723_check_fw_read_last_h2c(hw, boxnum);
508 while (!isfw_read) {
509 wait_h2c_limit--;
510 if (wait_h2c_limit == 0) {
511 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
512 "Waiting too long for FW read "
513 "clear HMEBox(%d)!\n", boxnum);
514 break;
515 }
516 udelay(10);
517
518 isfw_read = rtl8723_check_fw_read_last_h2c(hw,
519 boxnum);
520 }
521 if (!isfw_read) {
522 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
523 "Write H2C register BOX[%d] fail!!!!! "
524 "Fw do not read.\n", boxnum);
525 break;
526 }
527 memset(boxcontent, 0, sizeof(boxcontent));
528 memset(boxextcontent, 0, sizeof(boxextcontent));
529 boxcontent[0] = element_id;
530 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
531 "Write element_id box_reg(%4x) = %2x\n",
532 box_reg, element_id);
533
534 switch (cmd_len) {
535 case 1:
536 case 2:
537 case 3:
538 /*boxcontent[0] &= ~(BIT(7));*/
539 memcpy((u8 *)(boxcontent) + 1,
540 p_cmdbuffer + buf_index, cmd_len);
541
542 for (idx = 0; idx < 4; idx++) {
543 rtl_write_byte(rtlpriv, box_reg + idx,
544 boxcontent[idx]);
545 }
546 break;
547 case 4:
548 case 5:
549 case 6:
550 case 7:
551 /*boxcontent[0] |= (BIT(7));*/
552 memcpy((u8 *)(boxextcontent),
553 p_cmdbuffer + buf_index+3, cmd_len-3);
554 memcpy((u8 *)(boxcontent) + 1,
555 p_cmdbuffer + buf_index, 3);
556
557 for (idx = 0; idx < 4; idx++) {
558 rtl_write_byte(rtlpriv, box_extreg + idx,
559 boxextcontent[idx]);
560 }
561 for (idx = 0; idx < 4; idx++) {
562 rtl_write_byte(rtlpriv, box_reg + idx,
563 boxcontent[idx]);
564 }
565 break;
566 default:
567 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
568 "switch case not process\n");
569 break;
570 }
571 bwrite_sucess = true;
572
573 rtlhal->last_hmeboxnum = boxnum + 1;
574 if (rtlhal->last_hmeboxnum == 4)
575 rtlhal->last_hmeboxnum = 0;
576
577 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
578 "pHalData->last_hmeboxnum = %d\n",
579 rtlhal->last_hmeboxnum);
580 }
581 if (!rtlpriv) {
582 pr_err("rtlpriv bad\n");
583 return;
584 }
585 if (!rtlhal) {
586 pr_err("rtlhal bad\n");
587 return;
588 }
589 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
590 rtlhal->h2c_setinprogress = false;
591 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
592
593 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
594}
595EXPORT_SYMBOL_GPL(rtl8723_fill_h2c_command);
596
597void rtl8723_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
598 u32 cmd_len, u8 *p_cmdbuffer)
599{
600 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
601 u32 tmp_cmdbuf[2];
602
603 if (!rtlhal->fw_ready) {
604 RT_ASSERT(false,
605 "return H2C cmd because of Fw download fail!!!\n");
606 return;
607 }
608 memset(tmp_cmdbuf, 0, 8);
609 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
610 rtl8723_fill_h2c_command(hw, element_id, cmd_len,
611 (u8 *)&tmp_cmdbuf);
612 return;
613}
614EXPORT_SYMBOL_GPL(rtl8723_fill_h2c_cmd);
615
616void rtl8723_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
617{
618 u8 u1_joinbssrpt_parm[1] = { 0 };
619
620 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
621
622 rtl8723_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
623}
624EXPORT_SYMBOL_GPL(rtl8723_set_fw_joinbss_report_cmd);
625
626bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw, 297bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw,
627 struct sk_buff *skb) 298 struct sk_buff *skb)
628{ 299{
@@ -656,194 +327,3 @@ bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw,
656 return true; 327 return true;
657} 328}
658EXPORT_SYMBOL_GPL(rtl8723_cmd_send_packet); 329EXPORT_SYMBOL_GPL(rtl8723_cmd_send_packet);
659
660void rtl8723_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
661{
662 struct rtl_priv *rtlpriv = rtl_priv(hw);
663 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
664 struct sk_buff *skb = NULL;
665
666 u32 totalpacketlen;
667 bool rtstatus;
668 u8 u1rsvdpageloc[5] = { 0 };
669 bool dlok = false;
670
671 u8 *beacon;
672 u8 *p_pspoll;
673 u8 *nullfunc;
674 u8 *p_probersp;
675 /*---------------------------------------------------------
676 * (1) beacon
677 *---------------------------------------------------------
678 */
679 beacon = &reserved_page_packet[BEACON_PG * 128];
680 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
681 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
682
683 /*-------------------------------------------------------
684 * (2) ps-poll
685 *-------------------------------------------------------
686 */
687 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
688 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
689 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
690 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
691
692 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
693
694 /*--------------------------------------------------------
695 * (3) null data
696 *--------------------------------------------------------
697 */
698 nullfunc = &reserved_page_packet[NULL_PG * 128];
699 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
700 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
701 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
702
703 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
704
705 /*---------------------------------------------------------
706 * (4) probe response
707 *---------------------------------------------------------
708 */
709 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
710 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
711 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
712 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
713
714 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
715
716 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
717
718 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
719 "rtl8723be_set_fw_rsvdpagepkt(): "
720 "HW_VAR_SET_TX_CMD: ALL\n",
721 &reserved_page_packet[0], totalpacketlen);
722 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
723 "rtl8723be_set_fw_rsvdpagepkt(): "
724 "HW_VAR_SET_TX_CMD: ALL\n", u1rsvdpageloc, 3);
725
726
727 skb = dev_alloc_skb(totalpacketlen);
728 memcpy((u8 *)skb_put(skb, totalpacketlen),
729 &reserved_page_packet, totalpacketlen);
730
731 rtstatus = rtl8723_cmd_send_packet(hw, skb);
732
733 if (rtstatus)
734 dlok = true;
735
736 if (dlok) {
737 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
738 "Set RSVD page location to Fw.\n");
739 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
740 u1rsvdpageloc, 3);
741 rtl8723_fill_h2c_cmd(hw, H2C_88E_RSVDPAGE,
742 sizeof(u1rsvdpageloc), u1rsvdpageloc);
743 } else {
744 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
745 "Set RSVD page location to Fw FAIL!!!!!!.\n");
746 }
747}
748EXPORT_SYMBOL_GPL(rtl8723_set_fw_rsvdpagepkt);
749
750/*Should check FW support p2p or not.*/
751void rtl8723_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
752{
753 u8 u1_ctwindow_period[1] = {ctwindow};
754
755 rtl8723_fill_h2c_cmd(hw, H2C_88E_P2P_PS_CTW_CMD, 1,
756 u1_ctwindow_period);
757}
758EXPORT_SYMBOL_GPL(rtl8723_set_p2p_ctw_period_cmd);
759
760void rtl8723_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
761{
762 struct rtl_priv *rtlpriv = rtl_priv(hw);
763 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
764 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
765 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
766 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
767 u8 i;
768 u16 ctwindow;
769 u32 start_time, tsf_low;
770
771 switch (p2p_ps_state) {
772 case P2P_PS_DISABLE:
773 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
774 memset(p2p_ps_offload, 0, sizeof(struct p2p_ps_offload_t *));
775 break;
776 case P2P_PS_ENABLE:
777 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
778 /* update CTWindow value. */
779 if (p2pinfo->ctwindow > 0) {
780 p2p_ps_offload->ctwindow_en = 1;
781 ctwindow = p2pinfo->ctwindow;
782 rtl8723_set_p2p_ctw_period_cmd(hw, ctwindow);
783 }
784 /* hw only support 2 set of NoA */
785 for (i = 0; i < p2pinfo->noa_num; i++) {
786 /* To control the register setting
787 * for which NOA
788 */
789 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
790 if (i == 0)
791 p2p_ps_offload->noa0_en = 1;
792 else
793 p2p_ps_offload->noa1_en = 1;
794
795 /* config P2P NoA Descriptor Register */
796 rtl_write_dword(rtlpriv, 0x5E0,
797 p2pinfo->noa_duration[i]);
798 rtl_write_dword(rtlpriv, 0x5E4,
799 p2pinfo->noa_interval[i]);
800
801 /*Get Current TSF value */
802 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
803
804 start_time = p2pinfo->noa_start_time[i];
805 if (p2pinfo->noa_count_type[i] != 1) {
806 while (start_time <= (tsf_low + (50 * 1024))) {
807 start_time += p2pinfo->noa_interval[i];
808 if (p2pinfo->noa_count_type[i] != 255)
809 p2pinfo->noa_count_type[i]--;
810 }
811 }
812 rtl_write_dword(rtlpriv, 0x5E8, start_time);
813 rtl_write_dword(rtlpriv, 0x5EC,
814 p2pinfo->noa_count_type[i]);
815 }
816 if ((p2pinfo->opp_ps == 1) ||
817 (p2pinfo->noa_num > 0)) {
818 /* rst p2p circuit */
819 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
820
821 p2p_ps_offload->offload_en = 1;
822
823 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
824 p2p_ps_offload->role = 1;
825 p2p_ps_offload->allstasleep = 0;
826 } else {
827 p2p_ps_offload->role = 0;
828 }
829 p2p_ps_offload->discovery = 0;
830 }
831 break;
832 case P2P_PS_SCAN:
833 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
834 p2p_ps_offload->discovery = 1;
835 break;
836 case P2P_PS_SCAN_DONE:
837 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
838 p2p_ps_offload->discovery = 0;
839 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
840 break;
841 default:
842 break;
843 }
844 rtl8723_fill_h2c_cmd(hw, H2C_88E_P2P_PS_OFFLOAD, 1,
845 (u8 *)p2p_ps_offload);
846}
847EXPORT_SYMBOL_GPL(rtl8723_set_p2p_ps_offload_cmd);
848
849#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h
index 0890e5deddfa..cf1cc5804d06 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h
@@ -24,27 +24,103 @@
24 *****************************************************************************/ 24 *****************************************************************************/
25 25
26#ifndef __FW_COMMON_H__ 26#ifndef __FW_COMMON_H__
27#define __FW_COMMON_H__#endif 27#define __FW_COMMON_H__
28 28
29#define REG_SYS_FUNC_EN 0x0002
30#define REG_MCUFWDL 0x0080
31#define FW_8192C_START_ADDRESS 0x1000
32#define FW_8192C_PAGE_SIZE 4096
33#define FW_8192C_POLLING_TIMEOUT_COUNT 6000
34#define FW_8192C_POLLING_DELAY 5
35
36#define MCUFWDL_RDY BIT(1)
37#define FWDL_CHKSUM_RPT BIT(2)
38#define WINTINI_RDY BIT(6)
39
40#define REG_RSV_CTRL 0x001C
41#define REG_HMETFR 0x01CC
42
43enum version_8723e {
44 VERSION_TEST_UMC_CHIP_8723 = 0x0081,
45 VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089,
46 VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089,
47 VERSION_TEST_CHIP_1T1R_8723B = 0x0106,
48 VERSION_NORMAL_SMIC_CHIP_1T1R_8723B = 0x010E,
49 VERSION_UNKNOWN = 0xFF,
50};
51
52enum rtl8723ae_h2c_cmd {
53 H2C_AP_OFFLOAD = 0,
54 H2C_SETPWRMODE = 1,
55 H2C_JOINBSSRPT = 2,
56 H2C_RSVDPAGE = 3,
57 H2C_RSSI_REPORT = 4,
58 H2C_P2P_PS_CTW_CMD = 5,
59 H2C_P2P_PS_OFFLOAD = 6,
60 H2C_RA_MASK = 7,
61 MAX_H2CCMD
62};
63
64enum rtl8723be_cmd {
65 H2C_8723BE_RSVDPAGE = 0,
66 H2C_8723BE_JOINBSSRPT = 1,
67 H2C_8723BE_SCAN = 2,
68 H2C_8723BE_KEEP_ALIVE_CTRL = 3,
69 H2C_8723BE_DISCONNECT_DECISION = 4,
70 H2C_8723BE_INIT_OFFLOAD = 6,
71 H2C_8723BE_AP_OFFLOAD = 8,
72 H2C_8723BE_BCN_RSVDPAGE = 9,
73 H2C_8723BE_PROBERSP_RSVDPAGE = 10,
74
75 H2C_8723BE_SETPWRMODE = 0x20,
76 H2C_8723BE_PS_TUNING_PARA = 0x21,
77 H2C_8723BE_PS_TUNING_PARA2 = 0x22,
78 H2C_8723BE_PS_LPS_PARA = 0x23,
79 H2C_8723BE_P2P_PS_OFFLOAD = 0x24,
80
81 H2C_8723BE_WO_WLAN = 0x80,
82 H2C_8723BE_REMOTE_WAKE_CTRL = 0x81,
83 H2C_8723BE_AOAC_GLOBAL_INFO = 0x82,
84 H2C_8723BE_AOAC_RSVDPAGE = 0x83,
85 H2C_8723BE_RSSI_REPORT = 0x42,
86 H2C_8723BE_RA_MASK = 0x40,
87 H2C_8723BE_SELECTIVE_SUSPEND_ROF_CMD,
88 H2C_8723BE_P2P_PS_MODE,
89 H2C_8723BE_PSD_RESULT,
90 /*Not defined CTW CMD for P2P yet*/
91 H2C_8723BE_P2P_PS_CTW_CMD,
92 MAX_8723BE_H2CCMD
93};
94
95struct rtl92c_firmware_header {
96 u16 signature;
97 u8 category;
98 u8 function;
99 u16 version;
100 u8 subversion;
101 u8 rsvd1;
102 u8 month;
103 u8 date;
104 u8 hour;
105 u8 minute;
106 u16 ramcodesize;
107 u16 rsvd2;
108 u32 svnindex;
109 u32 rsvd3;
110 u32 rsvd4;
111 u32 rsvd5;
112};
113
114void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
115void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw);
29void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable); 116void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable);
30void rtl8723_fw_block_write(struct ieee80211_hw *hw, 117void rtl8723_fw_block_write(struct ieee80211_hw *hw,
31 const u8 *buffer, u32 size); 118 const u8 *buffer, u32 size);
32void rtl8723_fw_page_write(struct ieee80211_hw *hw, 119void rtl8723_fw_page_write(struct ieee80211_hw *hw,
33 u32 page, const u8 *buffer, u32 size); 120 u32 page, const u8 *buffer, u32 size);
34void rtl8723_write_fw(struct ieee80211_hw *hw, 121void rtl8723_write_fw(struct ieee80211_hw *hw,
35 enum version_8723be version, 122 enum version_8723e version,
36 u8 *buffer, u32 size); 123 u8 *buffer, u32 size);
37int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be); 124int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be);
38int rtl8723_download_fw(struct ieee80211_hw *hw, 125int rtl8723_download_fw(struct ieee80211_hw *hw, bool is_8723be);
39 bool buse_wake_on_wlan_fw, bool is_8723be); 126#endif
40bool rtl8723_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum);
41void rtl8723_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
42 u32 cmd_len, u8 *p_cmdbuffer);
43void rtl8723_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
44 u32 cmd_len, u8 *p_cmdbuffer);
45void rtl8723_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
46bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw,
47 struct sk_buff *skb);
48void rtl8723_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished);
49void rtl8723_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow);
50void rtl8723_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 3f52bf8abe00..2304c7f23361 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1712,6 +1712,8 @@ struct rtl_tcb_desc {
1712 bool btx_enable_sw_calc_duration; 1712 bool btx_enable_sw_calc_duration;
1713}; 1713};
1714 1714
1715struct rtl92c_firmware_header;
1716
1715struct rtl_hal_ops { 1717struct rtl_hal_ops {
1716 int (*init_sw_vars) (struct ieee80211_hw *hw); 1718 int (*init_sw_vars) (struct ieee80211_hw *hw);
1717 void (*deinit_sw_vars) (struct ieee80211_hw *hw); 1719 void (*deinit_sw_vars) (struct ieee80211_hw *hw);
@@ -1809,6 +1811,7 @@ struct rtl_hal_ops {
1809 void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id, 1811 void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,
1810 u32 cmd_len, u8 *p_cmdbuffer); 1812 u32 cmd_len, u8 *p_cmdbuffer);
1811 bool (*get_btc_status) (void); 1813 bool (*get_btc_status) (void);
1814 bool (*is_fw_header) (struct rtl92c_firmware_header *hdr);
1812}; 1815};
1813 1816
1814struct rtl_intf_ops { 1817struct rtl_intf_ops {