]> Git Repo - linux.git/blob - drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
net: bgmac: Fix return value check for fixed_phy_register()
[linux.git] / drivers / net / wireless / realtek / rtlwifi / rtl8192ee / fw.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2014  Realtek Corporation.*/
3
4 #include "../wifi.h"
5 #include "../pci.h"
6 #include "../base.h"
7 #include "../core.h"
8 #include "../efuse.h"
9 #include "reg.h"
10 #include "def.h"
11 #include "fw.h"
12 #include "dm.h"
13
14 static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable)
15 {
16         struct rtl_priv *rtlpriv = rtl_priv(hw);
17         u8 tmp;
18
19         if (enable) {
20                 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05);
21
22                 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
23                 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
24         } else {
25                 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
26                 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
27         }
28 }
29
30 static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
31                               enum version_8192e version,
32                               u8 *buffer, u32 size)
33 {
34         struct rtl_priv *rtlpriv = rtl_priv(hw);
35         u8 *bufferptr = (u8 *)buffer;
36         u32 pagenums, remainsize;
37         u32 page, offset;
38
39         rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
40
41         rtl_fill_dummy(bufferptr, &size);
42
43         pagenums = size / FW_8192C_PAGE_SIZE;
44         remainsize = size % FW_8192C_PAGE_SIZE;
45
46         if (pagenums > 8)
47                 pr_err("Page numbers should not greater then 8\n");
48
49         for (page = 0; page < pagenums; page++) {
50                 offset = page * FW_8192C_PAGE_SIZE;
51                 rtl_fw_page_write(hw, page, (bufferptr + offset),
52                                   FW_8192C_PAGE_SIZE);
53                 udelay(2);
54         }
55
56         if (remainsize) {
57                 offset = pagenums * FW_8192C_PAGE_SIZE;
58                 page = pagenums;
59                 rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
60         }
61 }
62
63 static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw)
64 {
65         struct rtl_priv *rtlpriv = rtl_priv(hw);
66         int err = -EIO;
67         u32 counter = 0;
68         u32 value32;
69
70         do {
71                 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
72         } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
73                  (!(value32 & FWDL_CHKSUM_RPT)));
74
75         if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
76                 pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
77                        value32);
78                 goto exit;
79         }
80         value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
81         value32 |= MCUFWDL_RDY;
82         value32 &= ~WINTINI_RDY;
83         rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
84
85         rtl92ee_firmware_selfreset(hw);
86         counter = 0;
87
88         do {
89                 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
90                 if (value32 & WINTINI_RDY)
91                         return 0;
92
93                 udelay(FW_8192C_POLLING_DELAY*10);
94
95         } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
96
97         pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n",
98                value32, counter);
99
100 exit:
101         return err;
102 }
103
104 int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
105 {
106         struct rtl_priv *rtlpriv = rtl_priv(hw);
107         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
108         struct rtlwifi_firmware_header *pfwheader;
109         u8 *pfwdata;
110         u32 fwsize;
111         enum version_8192e version = rtlhal->version;
112
113         if (!rtlhal->pfirmware)
114                 return 1;
115
116         pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
117         rtlhal->fw_version = le16_to_cpu(pfwheader->version);
118         rtlhal->fw_subversion = pfwheader->subversion;
119         pfwdata = (u8 *)rtlhal->pfirmware;
120         fwsize = rtlhal->fwsize;
121         rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
122                 "normal Firmware SIZE %d\n", fwsize);
123
124         if (IS_FW_HEADER_EXIST(pfwheader)) {
125                 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
126                         "Firmware Version(%d), Signature(%#x),Size(%d)\n",
127                         pfwheader->version, pfwheader->signature,
128                         (int)sizeof(struct rtlwifi_firmware_header));
129
130                 pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
131                 fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
132         } else {
133                 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
134                         "Firmware no Header, Signature(%#x)\n",
135                         pfwheader->signature);
136         }
137
138         if (rtlhal->mac_func_enable) {
139                 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
140                         rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
141                         rtl92ee_firmware_selfreset(hw);
142                 }
143         }
144         _rtl92ee_enable_fw_download(hw, true);
145         _rtl92ee_write_fw(hw, version, pfwdata, fwsize);
146         _rtl92ee_enable_fw_download(hw, false);
147
148         return _rtl92ee_fw_free_to_go(hw);
149 }
150
151 static bool _rtl92ee_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
152 {
153         struct rtl_priv *rtlpriv = rtl_priv(hw);
154         u8 val_hmetfr;
155         bool result = false;
156
157         val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
158         if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
159                 result = true;
160         return result;
161 }
162
163 static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
164                                       u32 cmd_len, u8 *cmdbuffer)
165 {
166         struct rtl_priv *rtlpriv = rtl_priv(hw);
167         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
168         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
169         u8 boxnum;
170         u16 box_reg = 0, box_extreg = 0;
171         u8 u1b_tmp;
172         bool isfw_read = false;
173         u8 buf_index = 0;
174         bool bwrite_sucess = false;
175         u8 wait_h2c_limmit = 100;
176         u8 boxcontent[4], boxextcontent[4];
177         u32 h2c_waitcounter = 0;
178         unsigned long flag;
179         u8 idx;
180
181         if (ppsc->dot11_psmode != EACTIVE ||
182             ppsc->inactive_pwrstate == ERFOFF) {
183                 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
184                         "FillH2CCommand8192E(): Return because RF is off!!!\n");
185                 return;
186         }
187
188         rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
189
190         /* 1. Prevent race condition in setting H2C cmd.
191          * (copy from MgntActSet_RF_State().)
192          */
193         while (true) {
194                 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
195                 if (rtlhal->h2c_setinprogress) {
196                         rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
197                                 "H2C set in progress! Wait to set..element_id(%d).\n",
198                                 element_id);
199
200                         while (rtlhal->h2c_setinprogress) {
201                                 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
202                                                        flag);
203                                 h2c_waitcounter++;
204                                 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
205                                         "Wait 100 us (%d times)...\n",
206                                         h2c_waitcounter);
207                                 udelay(100);
208
209                                 if (h2c_waitcounter > 1000)
210                                         return;
211                                 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
212                                                   flag);
213                         }
214                         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
215                 } else {
216                         rtlhal->h2c_setinprogress = true;
217                         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
218                         break;
219                 }
220         }
221
222         while (!bwrite_sucess) {
223                 /* 2. Find the last BOX number which has been writen. */
224                 boxnum = rtlhal->last_hmeboxnum;
225                 switch (boxnum) {
226                 case 0:
227                         box_reg = REG_HMEBOX_0;
228                         box_extreg = REG_HMEBOX_EXT_0;
229                         break;
230                 case 1:
231                         box_reg = REG_HMEBOX_1;
232                         box_extreg = REG_HMEBOX_EXT_1;
233                         break;
234                 case 2:
235                         box_reg = REG_HMEBOX_2;
236                         box_extreg = REG_HMEBOX_EXT_2;
237                         break;
238                 case 3:
239                         box_reg = REG_HMEBOX_3;
240                         box_extreg = REG_HMEBOX_EXT_3;
241                         break;
242                 default:
243                         rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
244                                 "switch case %#x not processed\n", boxnum);
245                         break;
246                 }
247
248                 /* 3. Check if the box content is empty. */
249                 isfw_read = false;
250                 u1b_tmp = rtl_read_byte(rtlpriv, REG_CR);
251
252                 if (u1b_tmp != 0xea) {
253                         isfw_read = true;
254                 } else {
255                         if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xea ||
256                             rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xea)
257                                 rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xff);
258                 }
259
260                 if (isfw_read) {
261                         wait_h2c_limmit = 100;
262                         isfw_read = _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
263                         while (!isfw_read) {
264                                 wait_h2c_limmit--;
265                                 if (wait_h2c_limmit == 0) {
266                                         rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
267                                                 "Waiting too long for FW read clear HMEBox(%d)!!!\n",
268                                                 boxnum);
269                                         break;
270                                 }
271                                 udelay(10);
272                                 isfw_read =
273                                   _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
274                                 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
275                                 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
276                                         "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
277                                         boxnum, u1b_tmp);
278                         }
279                 }
280
281                 /* If Fw has not read the last
282                  * H2C cmd, break and give up this H2C.
283                  */
284                 if (!isfw_read) {
285                         rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
286                                 "Write H2C reg BOX[%d] fail,Fw don't read.\n",
287                                 boxnum);
288                         break;
289                 }
290                 /* 4. Fill the H2C cmd into box */
291                 memset(boxcontent, 0, sizeof(boxcontent));
292                 memset(boxextcontent, 0, sizeof(boxextcontent));
293                 boxcontent[0] = element_id;
294                 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
295                         "Write element_id box_reg(%4x) = %2x\n",
296                         box_reg, element_id);
297
298                 switch (cmd_len) {
299                 case 1:
300                 case 2:
301                 case 3:
302                         /*boxcontent[0] &= ~(BIT(7));*/
303                         memcpy((u8 *)(boxcontent) + 1,
304                                cmdbuffer + buf_index, cmd_len);
305
306                         for (idx = 0; idx < 4; idx++) {
307                                 rtl_write_byte(rtlpriv, box_reg + idx,
308                                                boxcontent[idx]);
309                         }
310                         break;
311                 case 4:
312                 case 5:
313                 case 6:
314                 case 7:
315                         /*boxcontent[0] |= (BIT(7));*/
316                         memcpy((u8 *)(boxextcontent),
317                                cmdbuffer + buf_index+3, cmd_len-3);
318                         memcpy((u8 *)(boxcontent) + 1,
319                                cmdbuffer + buf_index, 3);
320
321                         for (idx = 0; idx < 4; idx++) {
322                                 rtl_write_byte(rtlpriv, box_extreg + idx,
323                                                boxextcontent[idx]);
324                         }
325
326                         for (idx = 0; idx < 4; idx++) {
327                                 rtl_write_byte(rtlpriv, box_reg + idx,
328                                                boxcontent[idx]);
329                         }
330                         break;
331                 default:
332                         rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
333                                 "switch case %#x not processed\n", cmd_len);
334                         break;
335                 }
336
337                 bwrite_sucess = true;
338
339                 rtlhal->last_hmeboxnum = boxnum + 1;
340                 if (rtlhal->last_hmeboxnum == 4)
341                         rtlhal->last_hmeboxnum = 0;
342
343                 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
344                         "pHalData->last_hmeboxnum  = %d\n",
345                         rtlhal->last_hmeboxnum);
346         }
347
348         spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
349         rtlhal->h2c_setinprogress = false;
350         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
351
352         rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
353 }
354
355 void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw,
356                           u8 element_id, u32 cmd_len, u8 *cmdbuffer)
357 {
358         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
359         u32 tmp_cmdbuf[2];
360
361         if (!rtlhal->fw_ready) {
362                 WARN_ONCE(true,
363                           "rtl8192ee: error H2C cmd because of Fw download fail!!!\n");
364                 return;
365         }
366
367         memset(tmp_cmdbuf, 0, 8);
368         memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
369         _rtl92ee_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
370 }
371
372 void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw)
373 {
374         u8 u1b_tmp;
375         struct rtl_priv *rtlpriv = rtl_priv(hw);
376
377         u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
378         rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
379
380         u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
381         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
382
383         udelay(50);
384
385         u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
386         rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0)));
387
388         u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
389         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2)));
390
391         rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
392                 "  _8051Reset92E(): 8051 reset success .\n");
393 }
394
395 void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
396 {
397         struct rtl_priv *rtlpriv = rtl_priv(hw);
398         u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 };
399         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
400         u8 rlbm, power_state = 0, byte5 = 0;
401         u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
402         struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
403         bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
404                             btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
405         bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
406                           btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
407
408         if (bt_ctrl_lps)
409                 mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
410
411         rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
412                 mode, bt_ctrl_lps);
413
414         switch (mode) {
415         case FW_PS_MIN_MODE:
416                 rlbm = 0;
417                 awake_intvl = 2;
418                 break;
419         case FW_PS_MAX_MODE:
420                 rlbm = 1;
421                 awake_intvl = 2;
422                 break;
423         case FW_PS_DTIM_MODE:
424                 rlbm = 2;
425                 awake_intvl = ppsc->reg_max_lps_awakeintvl;
426                 /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
427                  * is only used in swlps.
428                  */
429                 break;
430         default:
431                 rlbm = 2;
432                 awake_intvl = 4;
433                 break;
434         }
435
436         if (rtlpriv->mac80211.p2p) {
437                 awake_intvl = 2;
438                 rlbm = 1;
439         }
440
441         if (mode == FW_PS_ACTIVE_MODE) {
442                 byte5 = 0x40;
443                 power_state = FW_PWR_STATE_ACTIVE;
444         } else {
445                 if (bt_ctrl_lps) {
446                         byte5 = btc_ops->btc_get_lps_val(rtlpriv);
447                         power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
448
449                         if ((rlbm == 2) && (byte5 & BIT(4))) {
450                                 /* Keep awake interval to 1 to prevent from
451                                  * decreasing coex performance
452                                  */
453                                 awake_intvl = 2;
454                                 rlbm = 2;
455                         }
456                 } else {
457                         byte5 = 0x40;
458                         power_state = FW_PWR_STATE_RF_OFF;
459                 }
460         }
461
462         SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
463         SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
464         SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
465                                          bt_ctrl_lps ? 0 :
466                                          ((rtlpriv->mac80211.p2p) ?
467                                           ppsc->smart_ps : 1));
468         SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
469                                                awake_intvl);
470         SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
471         SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
472         SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
473
474         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
475                       "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
476                       u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH);
477         if (rtlpriv->cfg->ops->get_btc_status())
478                 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
479                                              H2C_92E_PWEMODE_LENGTH);
480         rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH,
481                              u1_h2c_set_pwrmode);
482 }
483
484 void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
485 {
486         u8 parm[3] = { 0 , 0 , 0 };
487         /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
488          *          bit1=0-->update Media Status to MACID
489          *          bit1=1-->update Media Status from MACID to MACID_End
490          * parm[1]: MACID, if this is INFRA_STA, MacID = 0
491          * parm[2]: MACID_End
492          */
493
494         SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
495         SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
496
497         rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
498 }
499
500 #define BEACON_PG               0 /* ->1 */
501 #define PSPOLL_PG               2
502 #define NULL_PG                 3
503 #define PROBERSP_PG             4 /* ->5 */
504 #define QOS_NULL_PG             6
505 #define BT_QOS_NULL_PG  7
506
507 #define TOTAL_RESERVED_PKT_LEN  1024
508
509 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
510         /* page 0 beacon */
511         0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
512         0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
513         0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
514         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515         0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
516         0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
517         0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
518         0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
519         0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
520         0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
521         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523         0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
524         0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
525         0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
526         0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
527
528         /* page 1 beacon */
529         0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
530         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540         0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
541         0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
542         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545
546         /* page 2  ps-poll */
547         0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
548         0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
549         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558         0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
559         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
560         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563
564         /* page 3  null */
565         0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
566         0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
567         0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
568         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576         0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
577         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
578         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581
582         /* page 4  probe_resp */
583         0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
584         0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
585         0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
586         0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
587         0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
588         0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
589         0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
590         0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
591         0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
592         0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
593         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596         0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
597         0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599
600         /* page 5  probe_resp */
601         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608         0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
609         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
610         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613
614         /* page 6 qos null data */
615         0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
616         0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
617         0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
618         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626         0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
627         0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
628         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631
632         /* page 7 BT-qos null data */
633         0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
634         0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
635         0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
636         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 };
654
655 void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
656 {
657         struct rtl_priv *rtlpriv = rtl_priv(hw);
658         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
659         struct sk_buff *skb = NULL;
660         bool rtstatus;
661         u32 totalpacketlen;
662         u8 u1rsvdpageloc[5] = { 0 };
663         bool b_dlok = false;
664
665         u8 *beacon;
666         u8 *p_pspoll;
667         u8 *nullfunc;
668         u8 *p_probersp;
669         u8 *qosnull;
670         u8 *btqosnull;
671         /*---------------------------------------------------------
672          *                      (1) beacon
673          *---------------------------------------------------------
674          */
675         beacon = &reserved_page_packet[BEACON_PG * 128];
676         SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
677         SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
678
679         /*-------------------------------------------------------
680          *                      (2) ps-poll
681          *--------------------------------------------------------
682          */
683         p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
684         SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
685         SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
686         SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
687
688         SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
689
690         /*--------------------------------------------------------
691          *                      (3) null data
692          *---------------------------------------------------------
693          */
694         nullfunc = &reserved_page_packet[NULL_PG * 128];
695         SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
696         SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
697         SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
698
699         SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
700
701         /*---------------------------------------------------------
702          *                      (4) probe response
703          *----------------------------------------------------------
704          */
705         p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
706         SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
707         SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
708         SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
709
710         SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
711
712         /*---------------------------------------------------------
713          *                      (5) QoS null data
714          *----------------------------------------------------------
715          */
716         qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
717         SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
718         SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
719         SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
720
721         SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
722
723         /*---------------------------------------------------------
724          *                      (6) BT QoS null data
725          *----------------------------------------------------------
726          */
727         btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
728         SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
729         SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
730         SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
731
732         SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
733
734         totalpacketlen = TOTAL_RESERVED_PKT_LEN;
735
736         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
737                       "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
738                       &reserved_page_packet[0], totalpacketlen);
739         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
740                       "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
741                       u1rsvdpageloc, 3);
742
743         skb = dev_alloc_skb(totalpacketlen);
744         if (!skb)
745                 return;
746         skb_put_data(skb, &reserved_page_packet, totalpacketlen);
747
748         rtstatus = rtl_cmd_send_packet(hw, skb);
749         if (rtstatus)
750                 b_dlok = true;
751
752         if (b_dlok) {
753                 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
754                         "Set RSVD page location to Fw.\n");
755                 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
756                               "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
757                 rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE,
758                                      sizeof(u1rsvdpageloc), u1rsvdpageloc);
759         } else {
760                 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
761                         "Set RSVD page location to Fw FAIL!!!!!!.\n");
762         }
763 }
764
765 /*Shoud check FW support p2p or not.*/
766 static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
767 {
768         u8 u1_ctwindow_period[1] = {ctwindow};
769
770         rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
771 }
772
773 void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
774 {
775         struct rtl_priv *rtlpriv = rtl_priv(hw);
776         struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
777         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
778         struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
779         struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
780         u8 i;
781         u16 ctwindow;
782         u32 start_time, tsf_low;
783
784         switch (p2p_ps_state) {
785         case P2P_PS_DISABLE:
786                 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
787                 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
788                 break;
789         case P2P_PS_ENABLE:
790                 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
791                 /* update CTWindow value. */
792                 if (p2pinfo->ctwindow > 0) {
793                         p2p_ps_offload->ctwindow_en = 1;
794                         ctwindow = p2pinfo->ctwindow;
795                         rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow);
796                 }
797                 /* hw only support 2 set of NoA */
798                 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
799                         /* To control the register setting for which NOA*/
800                         rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
801                         if (i == 0)
802                                 p2p_ps_offload->noa0_en = 1;
803                         else
804                                 p2p_ps_offload->noa1_en = 1;
805                         /* config P2P NoA Descriptor Register */
806                         rtl_write_dword(rtlpriv, 0x5E0,
807                                         p2pinfo->noa_duration[i]);
808                         rtl_write_dword(rtlpriv, 0x5E4,
809                                         p2pinfo->noa_interval[i]);
810
811                         /*Get Current TSF value */
812                         tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
813
814                         start_time = p2pinfo->noa_start_time[i];
815                         if (p2pinfo->noa_count_type[i] != 1) {
816                                 while (start_time <= (tsf_low + (50 * 1024))) {
817                                         start_time += p2pinfo->noa_interval[i];
818                                         if (p2pinfo->noa_count_type[i] != 255)
819                                                 p2pinfo->noa_count_type[i]--;
820                                 }
821                         }
822                         rtl_write_dword(rtlpriv, 0x5E8, start_time);
823                         rtl_write_dword(rtlpriv, 0x5EC,
824                                         p2pinfo->noa_count_type[i]);
825                 }
826                 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
827                         /* rst p2p circuit */
828                         rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
829                         p2p_ps_offload->offload_en = 1;
830
831                         if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
832                                 p2p_ps_offload->role = 1;
833                                 p2p_ps_offload->allstasleep = 0;
834                         } else {
835                                 p2p_ps_offload->role = 0;
836                         }
837                         p2p_ps_offload->discovery = 0;
838                 }
839                 break;
840         case P2P_PS_SCAN:
841                 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
842                 p2p_ps_offload->discovery = 1;
843                 break;
844         case P2P_PS_SCAN_DONE:
845                 rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
846                 p2p_ps_offload->discovery = 0;
847                 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
848                 break;
849         default:
850                 break;
851         }
852         rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1,
853                              (u8 *)p2p_ps_offload);
854 }
855
856 void rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw,
857                                    u8 *cmd_buf, u8 cmd_len)
858 {
859         u8 rate = cmd_buf[0] & 0x3F;
860         bool collision_state = cmd_buf[3] & BIT(0);
861
862         rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state);
863 }
This page took 0.082932 seconds and 4 git commands to generate.