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