Merge tag 'libnvdimm-for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm...
[deliverable/linux.git] / drivers / net / wireless / realtek / rtlwifi / rtl8723be / fw.c
CommitLineData
a619d1ab
LF
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
557f9331 29#include "../core.h"
a619d1ab
LF
30#include "reg.h"
31#include "def.h"
32#include "fw.h"
33#include "../rtl8723com/fw_common.h"
34
35static bool _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
36 u8 boxnum)
37{
38 struct rtl_priv *rtlpriv = rtl_priv(hw);
39 u8 val_hmetfr;
40 bool result = false;
41
42 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
43 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
44 result = true;
45 return result;
46}
47
48static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
49 u32 cmd_len, u8 *p_cmdbuffer)
50{
51 struct rtl_priv *rtlpriv = rtl_priv(hw);
52 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
53 u8 boxnum;
54 u16 box_reg = 0, box_extreg = 0;
55 u8 u1b_tmp;
56 bool isfw_read = false;
57 u8 buf_index = 0;
58 bool bwrite_sucess = false;
5c99f04f
LF
59 u8 wait_h2c_limmit = 100;
60 u8 wait_writeh2c_limmit = 100;
a619d1ab
LF
61 u8 boxcontent[4], boxextcontent[4];
62 u32 h2c_waitcounter = 0;
63 unsigned long flag;
64 u8 idx;
65
66 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
67
68 while (true) {
69 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
70 if (rtlhal->h2c_setinprogress) {
71 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
5c99f04f
LF
72 "H2C set in progress! Wait to set..element_id(%d).\n",
73 element_id);
a619d1ab
LF
74
75 while (rtlhal->h2c_setinprogress) {
76 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
77 flag);
78 h2c_waitcounter++;
79 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
80 "Wait 100 us (%d times)...\n",
81 h2c_waitcounter);
82 udelay(100);
83
84 if (h2c_waitcounter > 1000)
85 return;
86 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
87 flag);
88 }
89 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
90 } else {
91 rtlhal->h2c_setinprogress = true;
92 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
93 break;
94 }
95 }
5c99f04f 96
a619d1ab 97 while (!bwrite_sucess) {
5c99f04f
LF
98 wait_writeh2c_limmit--;
99 if (wait_writeh2c_limmit == 0) {
a619d1ab 100 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
5c99f04f 101 "Write H2C fail because no trigger for FW INT!\n");
a619d1ab
LF
102 break;
103 }
5c99f04f 104
a619d1ab
LF
105 boxnum = rtlhal->last_hmeboxnum;
106 switch (boxnum) {
107 case 0:
108 box_reg = REG_HMEBOX_0;
109 box_extreg = REG_HMEBOX_EXT_0;
110 break;
111 case 1:
112 box_reg = REG_HMEBOX_1;
113 box_extreg = REG_HMEBOX_EXT_1;
114 break;
115 case 2:
116 box_reg = REG_HMEBOX_2;
117 box_extreg = REG_HMEBOX_EXT_2;
118 break;
119 case 3:
120 box_reg = REG_HMEBOX_3;
121 box_extreg = REG_HMEBOX_EXT_3;
122 break;
123 default:
124 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
5c99f04f 125 "switch case not process\n");
a619d1ab
LF
126 break;
127 }
5c99f04f 128
a619d1ab
LF
129 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum);
130 while (!isfw_read) {
5c99f04f
LF
131 wait_h2c_limmit--;
132 if (wait_h2c_limmit == 0) {
a619d1ab 133 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
5c99f04f
LF
134 "Waiting too long for FW read clear HMEBox(%d)!\n",
135 boxnum);
a619d1ab
LF
136 break;
137 }
5c99f04f 138
a619d1ab
LF
139 udelay(10);
140
141 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw,
142 boxnum);
143 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
144 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
5c99f04f 145 "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
a619d1ab
LF
146 boxnum, u1b_tmp);
147 }
5c99f04f 148
a619d1ab
LF
149 if (!isfw_read) {
150 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
5c99f04f
LF
151 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
152 boxnum);
a619d1ab
LF
153 break;
154 }
5c99f04f 155
a619d1ab
LF
156 memset(boxcontent, 0, sizeof(boxcontent));
157 memset(boxextcontent, 0, sizeof(boxextcontent));
158 boxcontent[0] = element_id;
159 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
160 "Write element_id box_reg(%4x) = %2x\n",
5c99f04f 161 box_reg, element_id);
a619d1ab
LF
162
163 switch (cmd_len) {
164 case 1:
165 case 2:
166 case 3:
167 /*boxcontent[0] &= ~(BIT(7));*/
168 memcpy((u8 *)(boxcontent) + 1,
169 p_cmdbuffer + buf_index, cmd_len);
170
171 for (idx = 0; idx < 4; idx++) {
172 rtl_write_byte(rtlpriv, box_reg + idx,
173 boxcontent[idx]);
174 }
175 break;
176 case 4:
177 case 5:
178 case 6:
179 case 7:
180 /*boxcontent[0] |= (BIT(7));*/
181 memcpy((u8 *)(boxextcontent),
182 p_cmdbuffer + buf_index+3, cmd_len-3);
183 memcpy((u8 *)(boxcontent) + 1,
184 p_cmdbuffer + buf_index, 3);
185
186 for (idx = 0; idx < 4; idx++) {
187 rtl_write_byte(rtlpriv, box_extreg + idx,
188 boxextcontent[idx]);
189 }
5c99f04f 190
a619d1ab
LF
191 for (idx = 0; idx < 4; idx++) {
192 rtl_write_byte(rtlpriv, box_reg + idx,
193 boxcontent[idx]);
194 }
195 break;
196 default:
197 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
198 "switch case not process\n");
199 break;
200 }
5c99f04f 201
a619d1ab
LF
202 bwrite_sucess = true;
203
204 rtlhal->last_hmeboxnum = boxnum + 1;
205 if (rtlhal->last_hmeboxnum == 4)
206 rtlhal->last_hmeboxnum = 0;
207
208 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
209 "pHalData->last_hmeboxnum = %d\n",
5c99f04f 210 rtlhal->last_hmeboxnum);
a619d1ab 211 }
5c99f04f 212
a619d1ab
LF
213 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
214 rtlhal->h2c_setinprogress = false;
215 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
216
217 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
218}
219
220void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
221 u32 cmd_len, u8 *p_cmdbuffer)
222{
223 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
224 u32 tmp_cmdbuf[2];
225
226 if (!rtlhal->fw_ready) {
227 RT_ASSERT(false,
228 "return H2C cmd because of Fw download fail!!!\n");
229 return;
230 }
5c99f04f 231
a619d1ab
LF
232 memset(tmp_cmdbuf, 0, 8);
233 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
234 _rtl8723be_fill_h2c_command(hw, element_id, cmd_len,
235 (u8 *)&tmp_cmdbuf);
236 return;
237}
238
239void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
240{
241 struct rtl_priv *rtlpriv = rtl_priv(hw);
5c99f04f 242 u8 u1_h2c_set_pwrmode[H2C_PWEMODE_LENGTH] = { 0 };
a619d1ab
LF
243 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
244 u8 rlbm, power_state = 0;
245 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
246
247 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
5c99f04f 248 rlbm = 0;/*YJ,temp,120316. FW now not support RLBM=2.*/
a619d1ab
LF
249 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
250 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
251 (rtlpriv->mac80211.p2p) ?
5c99f04f 252 ppsc->smart_ps : 1);
a619d1ab
LF
253 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
254 ppsc->reg_max_lps_awakeintvl);
255 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
256 if (mode == FW_PS_ACTIVE_MODE)
257 power_state |= FW_PWR_STATE_ACTIVE;
258 else
259 power_state |= FW_PWR_STATE_RF_OFF;
260 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
261
262 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
263 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
5c99f04f
LF
264 u1_h2c_set_pwrmode, H2C_PWEMODE_LENGTH);
265 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_SETPWRMODE, H2C_PWEMODE_LENGTH,
a619d1ab
LF
266 u1_h2c_set_pwrmode);
267}
268
5c99f04f 269void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
a619d1ab 270{
5c99f04f
LF
271 u8 parm[3] = { 0, 0, 0 };
272 /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
273 * bit1=0-->update Media Status to MACID
274 * bit1=1-->update Media Status from MACID to MACID_End
275 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
276 * parm[2]: MACID_End
277 */
278 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
279 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
280
281 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_MSRRPT, 3, parm);
a619d1ab 282}
5c99f04f 283
a619d1ab
LF
284#define BEACON_PG 0 /* ->1 */
285#define PSPOLL_PG 2
286#define NULL_PG 3
287#define PROBERSP_PG 4 /* ->5 */
288
289#define TOTAL_RESERVED_PKT_LEN 768
290
291static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
292 /* page 0 beacon */
293 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
294 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
295 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
298 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
299 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
300 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
301 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
302 0x09, 0x03, 0xFF, 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, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
306 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
307 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
308 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
309
310 /* page 1 beacon */
311 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327
328 /* page 2 ps-poll */
329 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
330 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345
346 /* page 3 null */
347 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
348 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
349 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363
364 /* page 4 probe_resp */
365 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
366 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
367 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
368 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
369 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
370 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
371 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
372 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
373 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
374 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
375 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
379 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381
382 /* page 5 probe_resp */
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399};
400
401void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
5c99f04f 402 bool b_dl_finished)
a619d1ab
LF
403{
404 struct rtl_priv *rtlpriv = rtl_priv(hw);
405 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
406 struct sk_buff *skb = NULL;
407
408 u32 totalpacketlen;
409 bool rtstatus;
410 u8 u1rsvdpageloc[5] = { 0 };
5c99f04f 411 bool b_dlok = false;
a619d1ab
LF
412
413 u8 *beacon;
414 u8 *p_pspoll;
415 u8 *nullfunc;
416 u8 *p_probersp;
417 /*---------------------------------------------------------
418 * (1) beacon
419 *---------------------------------------------------------
420 */
421 beacon = &reserved_page_packet[BEACON_PG * 128];
422 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
423 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
424
425 /*-------------------------------------------------------
426 * (2) ps-poll
427 *-------------------------------------------------------
428 */
429 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
430 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
431 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
432 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
433
434 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
435
436 /*--------------------------------------------------------
437 * (3) null data
438 *--------------------------------------------------------
439 */
440 nullfunc = &reserved_page_packet[NULL_PG * 128];
441 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
442 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
443 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
444
445 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
446
447 /*---------------------------------------------------------
448 * (4) probe response
449 *---------------------------------------------------------
450 */
451 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
452 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
453 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
454 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
455
456 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
457
458 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
459
460 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
5c99f04f 461 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
a619d1ab
LF
462 &reserved_page_packet[0], totalpacketlen);
463 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
5c99f04f
LF
464 "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
465 u1rsvdpageloc, 3);
a619d1ab
LF
466
467 skb = dev_alloc_skb(totalpacketlen);
468 memcpy((u8 *)skb_put(skb, totalpacketlen),
469 &reserved_page_packet, totalpacketlen);
470
557f9331 471 rtstatus = rtl_cmd_send_packet(hw, skb);
a619d1ab
LF
472
473 if (rtstatus)
5c99f04f 474 b_dlok = true;
a619d1ab 475
5c99f04f 476 if (b_dlok) {
a619d1ab
LF
477 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
478 "Set RSVD page location to Fw.\n");
479 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
480 u1rsvdpageloc, 3);
5c99f04f 481 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RSVDPAGE,
a619d1ab 482 sizeof(u1rsvdpageloc), u1rsvdpageloc);
5c99f04f 483 } else
a619d1ab
LF
484 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
485 "Set RSVD page location to Fw FAIL!!!!!!.\n");
a619d1ab
LF
486}
487
488/*Should check FW support p2p or not.*/
489static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
490 u8 ctwindow)
491{
5c99f04f 492 u8 u1_ctwindow_period[1] = { ctwindow};
a619d1ab 493
5c99f04f 494 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_CTW_CMD, 1,
a619d1ab
LF
495 u1_ctwindow_period);
496}
497
498void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
499 u8 p2p_ps_state)
500{
501 struct rtl_priv *rtlpriv = rtl_priv(hw);
502 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
503 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
504 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
505 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
506 u8 i;
507 u16 ctwindow;
508 u32 start_time, tsf_low;
509
510 switch (p2p_ps_state) {
511 case P2P_PS_DISABLE:
512 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
5c99f04f 513 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
a619d1ab
LF
514 break;
515 case P2P_PS_ENABLE:
516 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
517 /* update CTWindow value. */
518 if (p2pinfo->ctwindow > 0) {
519 p2p_ps_offload->ctwindow_en = 1;
520 ctwindow = p2pinfo->ctwindow;
521 rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow);
522 }
523 /* hw only support 2 set of NoA */
5c99f04f 524 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
a619d1ab
LF
525 /* To control the register setting
526 * for which NOA
527 */
528 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
529 if (i == 0)
530 p2p_ps_offload->noa0_en = 1;
531 else
532 p2p_ps_offload->noa1_en = 1;
533
534 /* config P2P NoA Descriptor Register */
535 rtl_write_dword(rtlpriv, 0x5E0,
536 p2pinfo->noa_duration[i]);
537 rtl_write_dword(rtlpriv, 0x5E4,
538 p2pinfo->noa_interval[i]);
539
540 /*Get Current TSF value */
541 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
542
543 start_time = p2pinfo->noa_start_time[i];
544 if (p2pinfo->noa_count_type[i] != 1) {
545 while (start_time <= (tsf_low + (50 * 1024))) {
546 start_time += p2pinfo->noa_interval[i];
547 if (p2pinfo->noa_count_type[i] != 255)
548 p2pinfo->noa_count_type[i]--;
549 }
550 }
551 rtl_write_dword(rtlpriv, 0x5E8, start_time);
552 rtl_write_dword(rtlpriv, 0x5EC,
553 p2pinfo->noa_count_type[i]);
554 }
5c99f04f 555
a619d1ab
LF
556 if ((p2pinfo->opp_ps == 1) ||
557 (p2pinfo->noa_num > 0)) {
558 /* rst p2p circuit */
559 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
560
561 p2p_ps_offload->offload_en = 1;
562
563 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
564 p2p_ps_offload->role = 1;
565 p2p_ps_offload->allstasleep = 0;
566 } else {
567 p2p_ps_offload->role = 0;
568 }
569 p2p_ps_offload->discovery = 0;
570 }
571 break;
572 case P2P_PS_SCAN:
573 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
574 p2p_ps_offload->discovery = 1;
575 break;
576 case P2P_PS_SCAN_DONE:
577 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
578 p2p_ps_offload->discovery = 0;
579 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
580 break;
581 default:
582 break;
583 }
5c99f04f
LF
584
585 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_OFFLOAD, 1,
a619d1ab
LF
586 (u8 *)p2p_ps_offload);
587}
588
5c99f04f
LF
589static void _rtl8723be_c2h_content_parsing(struct ieee80211_hw *hw,
590 u8 c2h_cmd_id,
591 u8 c2h_cmd_len, u8 *tmp_buf)
a619d1ab 592{
5c99f04f 593 struct rtl_priv *rtlpriv = rtl_priv(hw);
a619d1ab 594
5c99f04f
LF
595 switch (c2h_cmd_id) {
596 case C2H_8723B_DBG:
597 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
598 "[C2H], C2H_8723BE_DBG!!\n");
599 break;
600 case C2H_8723B_TX_REPORT:
601 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
602 "[C2H], C2H_8723BE_TX_REPORT!\n");
603 break;
604 case C2H_8723B_BT_INFO:
605 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
606 "[C2H], C2H_8723BE_BT_INFO!!\n");
607 rtlpriv->btcoexist.btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
608 c2h_cmd_len);
609 break;
610 case C2H_8723B_BT_MP:
611 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
612 "[C2H], C2H_8723BE_BT_MP!!\n");
613 break;
614 default:
615 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
ad480137 616 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
5c99f04f
LF
617 break;
618 }
a619d1ab
LF
619}
620
5c99f04f 621void rtl8723be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
a619d1ab 622{
5c99f04f
LF
623 struct rtl_priv *rtlpriv = rtl_priv(hw);
624 u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
625 u8 *tmp_buf = NULL;
626
627 c2h_cmd_id = buffer[0];
628 c2h_cmd_seq = buffer[1];
629 c2h_cmd_len = len - 2;
630 tmp_buf = buffer + 2;
631
632 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
633 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
634 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
a619d1ab 635
5c99f04f
LF
636 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
637 "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
a619d1ab 638
5c99f04f 639 _rtl8723be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
a619d1ab 640}
This page took 0.164539 seconds and 5 git commands to generate.