1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012 Realtek Corporation.*/
3
4 #include "../wifi.h"
5 #include "../pci.h"
6 #include "../base.h"
7 #include "../core.h"
8 #include "reg.h"
9 #include "def.h"
10 #include "fw.h"
11 #include "../rtl8723com/fw_common.h"
12
_rtl8723e_check_fw_read_last_h2c(struct ieee80211_hw * hw,u8 boxnum)13 static bool _rtl8723e_check_fw_read_last_h2c(struct ieee80211_hw *hw,
14 u8 boxnum)
15 {
16 struct rtl_priv *rtlpriv = rtl_priv(hw);
17 u8 val_hmetfr, val_mcutst_1;
18 bool result = false;
19
20 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
21 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
22
23 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
24 result = true;
25 return result;
26 }
27
_rtl8723e_fill_h2c_command(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)28 static void _rtl8723e_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
29 u32 cmd_len, u8 *cmdbuffer)
30 {
31 struct rtl_priv *rtlpriv = rtl_priv(hw);
32 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
33 u8 boxnum;
34 u16 box_reg = 0, box_extreg = 0;
35 u8 u1b_tmp;
36 bool isfw_read = false;
37 u8 buf_index = 0;
38 bool bwrite_sucess = false;
39 u8 wait_h2c_limmit = 100;
40 u8 wait_writeh2c_limmit = 100;
41 u8 boxcontent[4], boxextcontent[2];
42 u32 h2c_waitcounter = 0;
43 unsigned long flag;
44 u8 idx;
45
46 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
47
48 while (true) {
49 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
50 if (rtlhal->h2c_setinprogress) {
51 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
52 "H2C set in progress! Wait to set..element_id(%d).\n",
53 element_id);
54
55 while (rtlhal->h2c_setinprogress) {
56 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
57 flag);
58 h2c_waitcounter++;
59 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
60 "Wait 100 us (%d times)...\n",
61 h2c_waitcounter);
62 udelay(100);
63
64 if (h2c_waitcounter > 1000)
65 return;
66 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
67 flag);
68 }
69 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
70 } else {
71 rtlhal->h2c_setinprogress = true;
72 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
73 break;
74 }
75 }
76
77 while (!bwrite_sucess) {
78 wait_writeh2c_limmit--;
79 if (wait_writeh2c_limmit == 0) {
80 pr_err("Write H2C fail because no trigger for FW INT!\n");
81 break;
82 }
83
84 boxnum = rtlhal->last_hmeboxnum;
85 switch (boxnum) {
86 case 0:
87 box_reg = REG_HMEBOX_0;
88 box_extreg = REG_HMEBOX_EXT_0;
89 break;
90 case 1:
91 box_reg = REG_HMEBOX_1;
92 box_extreg = REG_HMEBOX_EXT_1;
93 break;
94 case 2:
95 box_reg = REG_HMEBOX_2;
96 box_extreg = REG_HMEBOX_EXT_2;
97 break;
98 case 3:
99 box_reg = REG_HMEBOX_3;
100 box_extreg = REG_HMEBOX_EXT_3;
101 break;
102 default:
103 pr_err("switch case %#x not processed\n",
104 boxnum);
105 break;
106 }
107
108 isfw_read = _rtl8723e_check_fw_read_last_h2c(hw, boxnum);
109 while (!isfw_read) {
110
111 wait_h2c_limmit--;
112 if (wait_h2c_limmit == 0) {
113 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
114 "Waiting too long for FW read clear HMEBox(%d)!\n",
115 boxnum);
116 break;
117 }
118
119 udelay(10);
120
121 isfw_read = _rtl8723e_check_fw_read_last_h2c(hw,
122 boxnum);
123 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
124 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
125 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
126 boxnum, u1b_tmp);
127 }
128
129 if (!isfw_read) {
130 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
131 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
132 boxnum);
133 break;
134 }
135
136 memset(boxcontent, 0, sizeof(boxcontent));
137 memset(boxextcontent, 0, sizeof(boxextcontent));
138 boxcontent[0] = element_id;
139 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
140 "Write element_id box_reg(%4x) = %2x\n",
141 box_reg, element_id);
142
143 switch (cmd_len) {
144 case 1:
145 boxcontent[0] &= ~(BIT(7));
146 memcpy((u8 *)(boxcontent) + 1,
147 cmdbuffer + buf_index, 1);
148
149 for (idx = 0; idx < 4; idx++) {
150 rtl_write_byte(rtlpriv, box_reg + idx,
151 boxcontent[idx]);
152 }
153 break;
154 case 2:
155 boxcontent[0] &= ~(BIT(7));
156 memcpy((u8 *)(boxcontent) + 1,
157 cmdbuffer + buf_index, 2);
158
159 for (idx = 0; idx < 4; idx++) {
160 rtl_write_byte(rtlpriv, box_reg + idx,
161 boxcontent[idx]);
162 }
163 break;
164 case 3:
165 boxcontent[0] &= ~(BIT(7));
166 memcpy((u8 *)(boxcontent) + 1,
167 cmdbuffer + buf_index, 3);
168
169 for (idx = 0; idx < 4; idx++) {
170 rtl_write_byte(rtlpriv, box_reg + idx,
171 boxcontent[idx]);
172 }
173 break;
174 case 4:
175 boxcontent[0] |= (BIT(7));
176 memcpy((u8 *)(boxextcontent),
177 cmdbuffer + buf_index, 2);
178 memcpy((u8 *)(boxcontent) + 1,
179 cmdbuffer + buf_index + 2, 2);
180
181 for (idx = 0; idx < 2; idx++) {
182 rtl_write_byte(rtlpriv, box_extreg + idx,
183 boxextcontent[idx]);
184 }
185
186 for (idx = 0; idx < 4; idx++) {
187 rtl_write_byte(rtlpriv, box_reg + idx,
188 boxcontent[idx]);
189 }
190 break;
191 case 5:
192 boxcontent[0] |= (BIT(7));
193 memcpy((u8 *)(boxextcontent),
194 cmdbuffer + buf_index, 2);
195 memcpy((u8 *)(boxcontent) + 1,
196 cmdbuffer + buf_index + 2, 3);
197
198 for (idx = 0; idx < 2; idx++) {
199 rtl_write_byte(rtlpriv, box_extreg + idx,
200 boxextcontent[idx]);
201 }
202
203 for (idx = 0; idx < 4; idx++) {
204 rtl_write_byte(rtlpriv, box_reg + idx,
205 boxcontent[idx]);
206 }
207 break;
208 default:
209 pr_err("switch case %#x not processed\n",
210 cmd_len);
211 break;
212 }
213
214 bwrite_sucess = true;
215
216 rtlhal->last_hmeboxnum = boxnum + 1;
217 if (rtlhal->last_hmeboxnum == 4)
218 rtlhal->last_hmeboxnum = 0;
219
220 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
221 "pHalData->last_hmeboxnum = %d\n",
222 rtlhal->last_hmeboxnum);
223 }
224
225 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
226 rtlhal->h2c_setinprogress = false;
227 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
228
229 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
230 }
231
rtl8723e_fill_h2c_cmd(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)232 void rtl8723e_fill_h2c_cmd(struct ieee80211_hw *hw,
233 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
234 {
235 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
236 u32 tmp_cmdbuf[2];
237
238 if (!rtlhal->fw_ready) {
239 WARN_ONCE(true,
240 "rtl8723ae: error H2C cmd because of Fw download fail!!!\n");
241 return;
242 }
243 memset(tmp_cmdbuf, 0, 8);
244 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
245 _rtl8723e_fill_h2c_command(hw, element_id, cmd_len,
246 (u8 *)&tmp_cmdbuf);
247 }
248
rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw * hw,u8 mode)249 void rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
250 {
251 struct rtl_priv *rtlpriv = rtl_priv(hw);
252 u8 u1_h2c_set_pwrmode[3] = { 0 };
253 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
254
255 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
256
257 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
258 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
259 (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
260 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
261 ppsc->reg_max_lps_awakeintvl);
262
263 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
264 "rtl8723e_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
265 u1_h2c_set_pwrmode, 3);
266 rtl8723e_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
267 }
268
269 #define BEACON_PG 0 /* ->1 */
270 #define PSPOLL_PG 2
271 #define NULL_PG 3
272 #define PROBERSP_PG 4 /* ->5 */
273
274 #define TOTAL_RESERVED_PKT_LEN 768
275
276 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
277 /* page 0 beacon */
278 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
279 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
280 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
283 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
284 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
285 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
286 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
287 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
288 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
292 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294
295 /* page 1 beacon */
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312
313 /* page 2 ps-poll */
314 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
315 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
328 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330
331 /* page 3 null */
332 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
333 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
334 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
346 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348
349 /* page 4 probe_resp */
350 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
351 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
352 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
353 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
354 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
355 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
356 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
357 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
358 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
359 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
360 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
364 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366
367 /* page 5 probe_resp */
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 };
385
rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw * hw,bool b_dl_finished)386 void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
387 {
388 struct rtl_priv *rtlpriv = rtl_priv(hw);
389 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
390 struct sk_buff *skb = NULL;
391 u32 totalpacketlen;
392 bool rtstatus;
393 u8 u1rsvdpageloc[3] = { 0 };
394 bool b_dlok = false;
395 u8 *beacon;
396 u8 *p_pspoll;
397 u8 *nullfunc;
398 u8 *p_probersp;
399
400 /*---------------------------------------------------------
401 * (1) beacon
402 *---------------------------------------------------------
403 */
404 beacon = &reserved_page_packet[BEACON_PG * 128];
405 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
406 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
407
408 /*-------------------------------------------------------
409 * (2) ps-poll
410 *--------------------------------------------------------
411 */
412 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
413 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
414 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
415 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
416
417 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
418
419 /*--------------------------------------------------------
420 * (3) null data
421 *---------------------------------------------------------
422 */
423 nullfunc = &reserved_page_packet[NULL_PG * 128];
424 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
425 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
426 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
427
428 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
429
430 /*---------------------------------------------------------
431 * (4) probe response
432 *----------------------------------------------------------
433 */
434 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
435 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
436 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
437 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
438
439 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
440
441 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
442
443 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
444 "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
445 &reserved_page_packet[0], totalpacketlen);
446 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
447 "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
448 u1rsvdpageloc, 3);
449
450 skb = dev_alloc_skb(totalpacketlen);
451 if (!skb)
452 return;
453 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
454
455 rtstatus = rtl_cmd_send_packet(hw, skb);
456
457 if (rtstatus)
458 b_dlok = true;
459
460 if (b_dlok) {
461 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
462 "Set RSVD page location to Fw.\n");
463 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
464 "H2C_RSVDPAGE:\n",
465 u1rsvdpageloc, 3);
466 rtl8723e_fill_h2c_cmd(hw, H2C_RSVDPAGE,
467 sizeof(u1rsvdpageloc), u1rsvdpageloc);
468 } else
469 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
470 "Set RSVD page location to Fw FAIL!!!!!!.\n");
471 }
472
rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw * hw,u8 mstatus)473 void rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
474 {
475 u8 u1_joinbssrpt_parm[1] = { 0 };
476
477 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
478
479 rtl8723e_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
480 }
481
rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw * hw,u8 ctwindow)482 static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
483 u8 ctwindow)
484 {
485 u8 u1_ctwindow_period[1] = { ctwindow};
486
487 rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
488
489 }
490
rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw * hw,u8 p2p_ps_state)491 void rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
492 {
493 struct rtl_priv *rtlpriv = rtl_priv(hw);
494 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
495 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
496 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
497 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
498 u8 i;
499 u16 ctwindow;
500 u32 start_time, tsf_low;
501
502 switch (p2p_ps_state) {
503 case P2P_PS_DISABLE:
504 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
505 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
506 break;
507 case P2P_PS_ENABLE:
508 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
509 /* update CTWindow value. */
510 if (p2pinfo->ctwindow > 0) {
511 p2p_ps_offload->ctwindow_en = 1;
512 ctwindow = p2pinfo->ctwindow;
513 rtl8723e_set_p2p_ctw_period_cmd(hw, ctwindow);
514 }
515
516 /* hw only support 2 set of NoA */
517 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
518 /* To control the register setting for which NOA*/
519 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
520 if (i == 0)
521 p2p_ps_offload->noa0_en = 1;
522 else
523 p2p_ps_offload->noa1_en = 1;
524
525 /* config P2P NoA Descriptor Register */
526 rtl_write_dword(rtlpriv, 0x5E0,
527 p2pinfo->noa_duration[i]);
528 rtl_write_dword(rtlpriv, 0x5E4,
529 p2pinfo->noa_interval[i]);
530
531 /*Get Current TSF value */
532 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
533
534 start_time = p2pinfo->noa_start_time[i];
535 if (p2pinfo->noa_count_type[i] != 1) {
536 while (start_time <=
537 (tsf_low+(50*1024))) {
538 start_time +=
539 p2pinfo->noa_interval[i];
540 if (p2pinfo->noa_count_type[i] != 255)
541 p2pinfo->noa_count_type[i]--;
542 }
543 }
544 rtl_write_dword(rtlpriv, 0x5E8, start_time);
545 rtl_write_dword(rtlpriv, 0x5EC,
546 p2pinfo->noa_count_type[i]);
547
548 }
549
550 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
551 /* rst p2p circuit */
552 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
553
554 p2p_ps_offload->offload_en = 1;
555
556 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
557 p2p_ps_offload->role = 1;
558 p2p_ps_offload->allstasleep = 0;
559 } else {
560 p2p_ps_offload->role = 0;
561 }
562
563 p2p_ps_offload->discovery = 0;
564 }
565 break;
566 case P2P_PS_SCAN:
567 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
568 p2p_ps_offload->discovery = 1;
569 break;
570 case P2P_PS_SCAN_DONE:
571 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
572 p2p_ps_offload->discovery = 0;
573 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
574 break;
575 default:
576 break;
577 }
578
579 rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
580
581 }
582