Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 2009-2012  Realtek Corporation.*/
0003 
0004 #include "../wifi.h"
0005 #include "../pci.h"
0006 #include "../base.h"
0007 #include "../efuse.h"
0008 #include "reg.h"
0009 #include "def.h"
0010 #include "fw.h"
0011 #include "sw.h"
0012 
0013 static bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
0014 {
0015     return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ?
0016         true : false;
0017 }
0018 
0019 static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
0020 {
0021     struct rtl_priv *rtlpriv = rtl_priv(hw);
0022     u8 tmp;
0023 
0024     if (enable) {
0025         tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0026         rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
0027         tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
0028         rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
0029         tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
0030         rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
0031     } else {
0032         tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
0033         rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
0034         /* Reserved for fw extension.
0035          * 0x81[7] is used for mac0 status ,
0036          * so don't write this reg here
0037          * rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);*/
0038     }
0039 }
0040 
0041 static void _rtl92d_write_fw(struct ieee80211_hw *hw,
0042                  enum version_8192d version, u8 *buffer, u32 size)
0043 {
0044     struct rtl_priv *rtlpriv = rtl_priv(hw);
0045     struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0046     u8 *bufferptr = buffer;
0047     u32 pagenums, remainsize;
0048     u32 page, offset;
0049 
0050     rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
0051     if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
0052         rtl_fill_dummy(bufferptr, &size);
0053     pagenums = size / FW_8192D_PAGE_SIZE;
0054     remainsize = size % FW_8192D_PAGE_SIZE;
0055     if (pagenums > 8)
0056         pr_err("Page numbers should not greater then 8\n");
0057     for (page = 0; page < pagenums; page++) {
0058         offset = page * FW_8192D_PAGE_SIZE;
0059         rtl_fw_page_write(hw, page, (bufferptr + offset),
0060                   FW_8192D_PAGE_SIZE);
0061     }
0062     if (remainsize) {
0063         offset = pagenums * FW_8192D_PAGE_SIZE;
0064         page = pagenums;
0065         rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
0066     }
0067 }
0068 
0069 static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
0070 {
0071     struct rtl_priv *rtlpriv = rtl_priv(hw);
0072     u32 counter = 0;
0073     u32 value32;
0074 
0075     do {
0076         value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0077     } while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) &&
0078          (!(value32 & FWDL_CHKSUM_RPT)));
0079     if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
0080         pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
0081                value32);
0082         return -EIO;
0083     }
0084     value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
0085     value32 |= MCUFWDL_RDY;
0086     rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
0087     return 0;
0088 }
0089 
0090 void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
0091 {
0092     struct rtl_priv *rtlpriv = rtl_priv(hw);
0093     u8 u1b_tmp;
0094     u8 delay = 100;
0095 
0096     /* Set (REG_HMETFR + 3) to  0x20 is reset 8051 */
0097     rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
0098     u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0099     while (u1b_tmp & BIT(2)) {
0100         delay--;
0101         if (delay == 0)
0102             break;
0103         udelay(50);
0104         u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
0105     }
0106     WARN_ONCE((delay <= 0), "rtl8192de: 8051 reset failed!\n");
0107     rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0108         "=====> 8051 reset success (%d)\n", delay);
0109 }
0110 
0111 static int _rtl92d_fw_init(struct ieee80211_hw *hw)
0112 {
0113     struct rtl_priv *rtlpriv = rtl_priv(hw);
0114     struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0115     u32 counter;
0116 
0117     rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
0118     /* polling for FW ready */
0119     counter = 0;
0120     do {
0121         if (rtlhal->interfaceindex == 0) {
0122             if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
0123                 MAC0_READY) {
0124                 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0125                     "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
0126                     rtl_read_byte(rtlpriv,
0127                               FW_MAC0_READY));
0128                 return 0;
0129             }
0130             udelay(5);
0131         } else {
0132             if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
0133                 MAC1_READY) {
0134                 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0135                     "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
0136                     rtl_read_byte(rtlpriv,
0137                               FW_MAC1_READY));
0138                 return 0;
0139             }
0140             udelay(5);
0141         }
0142     } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
0143 
0144     if (rtlhal->interfaceindex == 0) {
0145         rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0146             "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
0147             rtl_read_byte(rtlpriv, FW_MAC0_READY));
0148     } else {
0149         rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0150             "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
0151             rtl_read_byte(rtlpriv, FW_MAC1_READY));
0152     }
0153     rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0154         "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
0155         rtl_read_dword(rtlpriv, REG_MCUFWDL));
0156     return -1;
0157 }
0158 
0159 int rtl92d_download_fw(struct ieee80211_hw *hw)
0160 {
0161     struct rtl_priv *rtlpriv = rtl_priv(hw);
0162     struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0163     u8 *pfwheader;
0164     u8 *pfwdata;
0165     u32 fwsize;
0166     int err;
0167     enum version_8192d version = rtlhal->version;
0168     u8 value;
0169     u32 count;
0170     bool fw_downloaded = false, fwdl_in_process = false;
0171     unsigned long flags;
0172 
0173     if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
0174         return 1;
0175     fwsize = rtlhal->fwsize;
0176     pfwheader = rtlhal->pfirmware;
0177     pfwdata = rtlhal->pfirmware;
0178     rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
0179     rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
0180     rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
0181         "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
0182         rtlhal->fw_version, rtlhal->fw_subversion,
0183         GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
0184     if (IS_FW_HEADER_EXIST(pfwheader)) {
0185         rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
0186             "Shift 32 bytes for FW header!!\n");
0187         pfwdata = pfwdata + 32;
0188         fwsize = fwsize - 32;
0189     }
0190 
0191     spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
0192     fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
0193     if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
0194         fwdl_in_process = true;
0195     else
0196         fwdl_in_process = false;
0197     if (fw_downloaded) {
0198         spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0199         goto exit;
0200     } else if (fwdl_in_process) {
0201         spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0202         for (count = 0; count < 5000; count++) {
0203             udelay(500);
0204             spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
0205             fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
0206             if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
0207                 fwdl_in_process = true;
0208             else
0209                 fwdl_in_process = false;
0210             spin_unlock_irqrestore(&globalmutex_for_fwdownload,
0211                            flags);
0212             if (fw_downloaded)
0213                 goto exit;
0214             else if (!fwdl_in_process)
0215                 break;
0216             else
0217                 rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG,
0218                     "Wait for another mac download fw\n");
0219         }
0220         spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
0221         value = rtl_read_byte(rtlpriv, 0x1f);
0222         value |= BIT(5);
0223         rtl_write_byte(rtlpriv, 0x1f, value);
0224         spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0225     } else {
0226         value = rtl_read_byte(rtlpriv, 0x1f);
0227         value |= BIT(5);
0228         rtl_write_byte(rtlpriv, 0x1f, value);
0229         spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0230     }
0231 
0232     /* If 8051 is running in RAM code, driver should
0233      * inform Fw to reset by itself, or it will cause
0234      * download Fw fail.*/
0235     /* 8051 RAM code */
0236     if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
0237         rtl92d_firmware_selfreset(hw);
0238         rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
0239     }
0240     _rtl92d_enable_fw_download(hw, true);
0241     _rtl92d_write_fw(hw, version, pfwdata, fwsize);
0242     _rtl92d_enable_fw_download(hw, false);
0243     spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
0244     err = _rtl92d_fw_free_to_go(hw);
0245     /* download fw over,clear 0x1f[5] */
0246     value = rtl_read_byte(rtlpriv, 0x1f);
0247     value &= (~BIT(5));
0248     rtl_write_byte(rtlpriv, 0x1f, value);
0249     spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
0250     if (err)
0251         pr_err("fw is not ready to run!\n");
0252 exit:
0253     err = _rtl92d_fw_init(hw);
0254     return err;
0255 }
0256 
0257 static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
0258 {
0259     struct rtl_priv *rtlpriv = rtl_priv(hw);
0260     u8 val_hmetfr;
0261     bool result = false;
0262 
0263     val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
0264     if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
0265         result = true;
0266     return result;
0267 }
0268 
0269 static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
0270                   u8 element_id, u32 cmd_len, u8 *cmdbuffer)
0271 {
0272     struct rtl_priv *rtlpriv = rtl_priv(hw);
0273     struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0274     struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
0275     u8 boxnum;
0276     u16 box_reg = 0, box_extreg = 0;
0277     u8 u1b_tmp;
0278     bool isfw_read = false;
0279     u8 buf_index = 0;
0280     bool bwrite_success = false;
0281     u8 wait_h2c_limmit = 100;
0282     u8 wait_writeh2c_limmit = 100;
0283     u8 boxcontent[4], boxextcontent[2];
0284     u32 h2c_waitcounter = 0;
0285     unsigned long flag;
0286     u8 idx;
0287 
0288     if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
0289         rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0290             "Return as RF is off!!!\n");
0291         return;
0292     }
0293     rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
0294     while (true) {
0295         spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0296         if (rtlhal->h2c_setinprogress) {
0297             rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0298                 "H2C set in progress! Wait to set..element_id(%d)\n",
0299                 element_id);
0300 
0301             while (rtlhal->h2c_setinprogress) {
0302                 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
0303                                flag);
0304                 h2c_waitcounter++;
0305                 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0306                     "Wait 100 us (%d times)...\n",
0307                     h2c_waitcounter);
0308                 udelay(100);
0309 
0310                 if (h2c_waitcounter > 1000)
0311                     return;
0312 
0313                 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
0314                           flag);
0315             }
0316             spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0317         } else {
0318             rtlhal->h2c_setinprogress = true;
0319             spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0320             break;
0321         }
0322     }
0323     while (!bwrite_success) {
0324         wait_writeh2c_limmit--;
0325         if (wait_writeh2c_limmit == 0) {
0326             pr_err("Write H2C fail because no trigger for FW INT!\n");
0327             break;
0328         }
0329         boxnum = rtlhal->last_hmeboxnum;
0330         switch (boxnum) {
0331         case 0:
0332             box_reg = REG_HMEBOX_0;
0333             box_extreg = REG_HMEBOX_EXT_0;
0334             break;
0335         case 1:
0336             box_reg = REG_HMEBOX_1;
0337             box_extreg = REG_HMEBOX_EXT_1;
0338             break;
0339         case 2:
0340             box_reg = REG_HMEBOX_2;
0341             box_extreg = REG_HMEBOX_EXT_2;
0342             break;
0343         case 3:
0344             box_reg = REG_HMEBOX_3;
0345             box_extreg = REG_HMEBOX_EXT_3;
0346             break;
0347         default:
0348             pr_err("switch case %#x not processed\n",
0349                    boxnum);
0350             break;
0351         }
0352         isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
0353         while (!isfw_read) {
0354             wait_h2c_limmit--;
0355             if (wait_h2c_limmit == 0) {
0356                 rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0357                     "Waiting too long for FW read clear HMEBox(%d)!\n",
0358                     boxnum);
0359                 break;
0360             }
0361             udelay(10);
0362             isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
0363             u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
0364             rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0365                 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
0366                 boxnum, u1b_tmp);
0367         }
0368         if (!isfw_read) {
0369             rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0370                 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
0371                 boxnum);
0372             break;
0373         }
0374         memset(boxcontent, 0, sizeof(boxcontent));
0375         memset(boxextcontent, 0, sizeof(boxextcontent));
0376         boxcontent[0] = element_id;
0377         rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0378             "Write element_id box_reg(%4x) = %2x\n",
0379             box_reg, element_id);
0380         switch (cmd_len) {
0381         case 1:
0382             boxcontent[0] &= ~(BIT(7));
0383             memcpy(boxcontent + 1, cmdbuffer + buf_index, 1);
0384             for (idx = 0; idx < 4; idx++)
0385                 rtl_write_byte(rtlpriv, box_reg + idx,
0386                            boxcontent[idx]);
0387             break;
0388         case 2:
0389             boxcontent[0] &= ~(BIT(7));
0390             memcpy(boxcontent + 1, cmdbuffer + buf_index, 2);
0391             for (idx = 0; idx < 4; idx++)
0392                 rtl_write_byte(rtlpriv, box_reg + idx,
0393                            boxcontent[idx]);
0394             break;
0395         case 3:
0396             boxcontent[0] &= ~(BIT(7));
0397             memcpy(boxcontent + 1, cmdbuffer + buf_index, 3);
0398             for (idx = 0; idx < 4; idx++)
0399                 rtl_write_byte(rtlpriv, box_reg + idx,
0400                            boxcontent[idx]);
0401             break;
0402         case 4:
0403             boxcontent[0] |= (BIT(7));
0404             memcpy(boxextcontent, cmdbuffer + buf_index, 2);
0405             memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2);
0406             for (idx = 0; idx < 2; idx++)
0407                 rtl_write_byte(rtlpriv, box_extreg + idx,
0408                            boxextcontent[idx]);
0409             for (idx = 0; idx < 4; idx++)
0410                 rtl_write_byte(rtlpriv, box_reg + idx,
0411                            boxcontent[idx]);
0412             break;
0413         case 5:
0414             boxcontent[0] |= (BIT(7));
0415             memcpy(boxextcontent, cmdbuffer + buf_index, 2);
0416             memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3);
0417             for (idx = 0; idx < 2; idx++)
0418                 rtl_write_byte(rtlpriv, box_extreg + idx,
0419                            boxextcontent[idx]);
0420             for (idx = 0; idx < 4; idx++)
0421                 rtl_write_byte(rtlpriv, box_reg + idx,
0422                            boxcontent[idx]);
0423             break;
0424         default:
0425             pr_err("switch case %#x not processed\n",
0426                    cmd_len);
0427             break;
0428         }
0429         bwrite_success = true;
0430         rtlhal->last_hmeboxnum = boxnum + 1;
0431         if (rtlhal->last_hmeboxnum == 4)
0432             rtlhal->last_hmeboxnum = 0;
0433         rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD,
0434             "pHalData->last_hmeboxnum  = %d\n",
0435             rtlhal->last_hmeboxnum);
0436     }
0437     spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
0438     rtlhal->h2c_setinprogress = false;
0439     spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
0440     rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
0441 }
0442 
0443 void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
0444              u8 element_id, u32 cmd_len, u8 *cmdbuffer)
0445 {
0446     u32 tmp_cmdbuf[2];
0447 
0448     memset(tmp_cmdbuf, 0, 8);
0449     memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
0450     _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
0451     return;
0452 }
0453 
0454 static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
0455                     struct sk_buff *skb)
0456 {
0457     struct rtl_priv *rtlpriv = rtl_priv(hw);
0458     struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
0459     struct rtl8192_tx_ring *ring;
0460     struct rtl_tx_desc *pdesc;
0461     u8 idx = 0;
0462     unsigned long flags;
0463     struct sk_buff *pskb;
0464 
0465     ring = &rtlpci->tx_ring[BEACON_QUEUE];
0466     pskb = __skb_dequeue(&ring->queue);
0467     kfree_skb(pskb);
0468     spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
0469     pdesc = &ring->desc[idx];
0470     /* discard output from call below */
0471     rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN);
0472     rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
0473     __skb_queue_tail(&ring->queue, skb);
0474     spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
0475     rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
0476     return true;
0477 }
0478 
0479 #define BEACON_PG       0   /*->1 */
0480 #define PSPOLL_PG       2
0481 #define NULL_PG         3
0482 #define PROBERSP_PG     4   /*->5 */
0483 #define TOTAL_RESERVED_PKT_LEN  768
0484 
0485 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
0486     /* page 0 beacon */
0487     0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0488     0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0489     0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
0490     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0491     0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0492     0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0493     0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0494     0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0495     0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0496     0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0497     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0498     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0499     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0500     0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0501     0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0502     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0503 
0504     /* page 1 beacon */
0505     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0506     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0507     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0508     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0509     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0510     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0511     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0512     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0513     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0514     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0515     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0516     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0517     0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
0518     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0519     0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0520     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0521 
0522     /* page 2  ps-poll */
0523     0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
0524     0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0525     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0526     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0527     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0528     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0529     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0530     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0531     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0532     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0533     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0534     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0535     0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0536     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0537     0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0538     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0539 
0540     /* page 3  null */
0541     0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0542     0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0543     0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0544     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0545     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0546     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0547     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0548     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0549     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0550     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0551     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0552     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0553     0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
0554     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0555     0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0556     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0557 
0558     /* page 4  probe_resp */
0559     0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
0560     0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
0561     0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
0562     0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
0563     0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
0564     0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
0565     0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
0566     0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
0567     0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
0568     0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
0569     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0570     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0571     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0572     0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
0573     0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0574     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0575 
0576     /* page 5  probe_resp */
0577     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0578     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0579     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0580     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0581     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0582     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0583     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0584     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0585     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0586     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0587     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0588     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0589     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0590     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0591     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0592     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0593 };
0594 
0595 void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
0596 {
0597     struct rtl_priv *rtlpriv = rtl_priv(hw);
0598     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0599     struct sk_buff *skb = NULL;
0600     u32 totalpacketlen;
0601     bool rtstatus;
0602     u8 u1rsvdpageloc[3] = { 0 };
0603     bool dlok = false;
0604     u8 *beacon;
0605     u8 *p_pspoll;
0606     u8 *nullfunc;
0607     u8 *p_probersp;
0608     /*---------------------------------------------------------
0609                         (1) beacon
0610     ---------------------------------------------------------*/
0611     beacon = &reserved_page_packet[BEACON_PG * 128];
0612     SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
0613     SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
0614     /*-------------------------------------------------------
0615                         (2) ps-poll
0616     --------------------------------------------------------*/
0617     p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
0618     SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
0619     SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
0620     SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
0621     SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
0622     /*--------------------------------------------------------
0623                         (3) null data
0624     ---------------------------------------------------------*/
0625     nullfunc = &reserved_page_packet[NULL_PG * 128];
0626     SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
0627     SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
0628     SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
0629     SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
0630     /*---------------------------------------------------------
0631                         (4) probe response
0632     ----------------------------------------------------------*/
0633     p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
0634     SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
0635     SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
0636     SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
0637     SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
0638     totalpacketlen = TOTAL_RESERVED_PKT_LEN;
0639     RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
0640               "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
0641               &reserved_page_packet[0], totalpacketlen);
0642     RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0643               "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
0644               u1rsvdpageloc, 3);
0645     skb = dev_alloc_skb(totalpacketlen);
0646     if (!skb) {
0647         dlok = false;
0648     } else {
0649         skb_put_data(skb, &reserved_page_packet, totalpacketlen);
0650         rtstatus = _rtl92d_cmd_send_packet(hw, skb);
0651 
0652         if (rtstatus)
0653             dlok = true;
0654     }
0655     if (dlok) {
0656         rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0657             "Set RSVD page location to Fw\n");
0658         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
0659                   "H2C_RSVDPAGE", u1rsvdpageloc, 3);
0660         rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
0661             sizeof(u1rsvdpageloc), u1rsvdpageloc);
0662     } else
0663         rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
0664             "Set RSVD page location to Fw FAIL!!!!!!\n");
0665 }
0666 
0667 void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
0668 {
0669     u8 u1_joinbssrpt_parm[1] = {0};
0670 
0671     SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
0672     rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
0673 }