root/drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _rtl8723be_check_fw_read_last_h2c
  2. _rtl8723be_fill_h2c_command
  3. rtl8723be_fill_h2c_cmd
  4. rtl8723be_set_fw_pwrmode_cmd
  5. rtl8723be_set_fw_media_status_rpt_cmd
  6. rtl8723be_set_fw_rsvdpagepkt
  7. rtl8723be_set_p2p_ctw_period_cmd
  8. rtl8723be_set_p2p_ps_offload_cmd

   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 "reg.h"
   9 #include "def.h"
  10 #include "fw.h"
  11 #include "../rtl8723com/fw_common.h"
  12 
  13 static bool _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
  14                                               u8 boxnum)
  15 {
  16         struct rtl_priv *rtlpriv = rtl_priv(hw);
  17         u8 val_hmetfr;
  18         bool result = false;
  19 
  20         val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
  21         if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
  22                 result = true;
  23         return result;
  24 }
  25 
  26 static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
  27                                         u32 cmd_len, u8 *p_cmdbuffer)
  28 {
  29         struct rtl_priv *rtlpriv = rtl_priv(hw);
  30         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  31         u8 boxnum;
  32         u16 box_reg = 0, box_extreg = 0;
  33         u8 u1b_tmp;
  34         bool isfw_read = false;
  35         u8 buf_index = 0;
  36         bool bwrite_sucess = false;
  37         u8 wait_h2c_limmit = 100;
  38         u8 wait_writeh2c_limmit = 100;
  39         u8 boxcontent[4], boxextcontent[4];
  40         u32 h2c_waitcounter = 0;
  41         unsigned long flag;
  42         u8 idx;
  43 
  44         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
  45 
  46         while (true) {
  47                 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
  48                 if (rtlhal->h2c_setinprogress) {
  49                         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
  50                                  "H2C set in progress! Wait to set..element_id(%d).\n",
  51                                  element_id);
  52 
  53                         while (rtlhal->h2c_setinprogress) {
  54                                 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
  55                                                        flag);
  56                                 h2c_waitcounter++;
  57                                 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
  58                                          "Wait 100 us (%d times)...\n",
  59                                          h2c_waitcounter);
  60                                 udelay(100);
  61 
  62                                 if (h2c_waitcounter > 1000)
  63                                         return;
  64                                 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
  65                                                   flag);
  66                         }
  67                         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
  68                 } else {
  69                         rtlhal->h2c_setinprogress = true;
  70                         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
  71                         break;
  72                 }
  73         }
  74 
  75         while (!bwrite_sucess) {
  76                 wait_writeh2c_limmit--;
  77                 if (wait_writeh2c_limmit == 0) {
  78                         pr_err("Write H2C fail because no trigger for FW INT!\n");
  79                         break;
  80                 }
  81 
  82                 boxnum = rtlhal->last_hmeboxnum;
  83                 switch (boxnum) {
  84                 case 0:
  85                         box_reg = REG_HMEBOX_0;
  86                         box_extreg = REG_HMEBOX_EXT_0;
  87                         break;
  88                 case 1:
  89                         box_reg = REG_HMEBOX_1;
  90                         box_extreg = REG_HMEBOX_EXT_1;
  91                         break;
  92                 case 2:
  93                         box_reg = REG_HMEBOX_2;
  94                         box_extreg = REG_HMEBOX_EXT_2;
  95                         break;
  96                 case 3:
  97                         box_reg = REG_HMEBOX_3;
  98                         box_extreg = REG_HMEBOX_EXT_3;
  99                         break;
 100                 default:
 101                         pr_err("switch case %#x not processed\n",
 102                                boxnum);
 103                         break;
 104                 }
 105 
 106                 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum);
 107                 while (!isfw_read) {
 108                         wait_h2c_limmit--;
 109                         if (wait_h2c_limmit == 0) {
 110                                 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 111                                          "Waiting too long for FW read clear HMEBox(%d)!\n",
 112                                          boxnum);
 113                                 break;
 114                         }
 115 
 116                         udelay(10);
 117 
 118                         isfw_read = _rtl8723be_check_fw_read_last_h2c(hw,
 119                                                                 boxnum);
 120                         u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
 121                         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 122                                  "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
 123                                  boxnum, u1b_tmp);
 124                 }
 125 
 126                 if (!isfw_read) {
 127                         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 128                                  "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
 129                                  boxnum);
 130                         break;
 131                 }
 132 
 133                 memset(boxcontent, 0, sizeof(boxcontent));
 134                 memset(boxextcontent, 0, sizeof(boxextcontent));
 135                 boxcontent[0] = element_id;
 136                 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 137                          "Write element_id box_reg(%4x) = %2x\n",
 138                           box_reg, element_id);
 139 
 140                 switch (cmd_len) {
 141                 case 1:
 142                 case 2:
 143                 case 3:
 144                         /*boxcontent[0] &= ~(BIT(7));*/
 145                         memcpy((u8 *)(boxcontent) + 1,
 146                                p_cmdbuffer + buf_index, cmd_len);
 147 
 148                         for (idx = 0; idx < 4; idx++) {
 149                                 rtl_write_byte(rtlpriv, box_reg + idx,
 150                                                boxcontent[idx]);
 151                         }
 152                         break;
 153                 case 4:
 154                 case 5:
 155                 case 6:
 156                 case 7:
 157                         /*boxcontent[0] |= (BIT(7));*/
 158                         memcpy((u8 *)(boxextcontent),
 159                                p_cmdbuffer + buf_index+3, cmd_len-3);
 160                         memcpy((u8 *)(boxcontent) + 1,
 161                                p_cmdbuffer + buf_index, 3);
 162 
 163                         for (idx = 0; idx < 4; idx++) {
 164                                 rtl_write_byte(rtlpriv, box_extreg + idx,
 165                                                boxextcontent[idx]);
 166                         }
 167 
 168                         for (idx = 0; idx < 4; idx++) {
 169                                 rtl_write_byte(rtlpriv, box_reg + idx,
 170                                                boxcontent[idx]);
 171                         }
 172                         break;
 173                 default:
 174                         pr_err("switch case %#x not processed\n",
 175                                cmd_len);
 176                         break;
 177                 }
 178 
 179                 bwrite_sucess = true;
 180 
 181                 rtlhal->last_hmeboxnum = boxnum + 1;
 182                 if (rtlhal->last_hmeboxnum == 4)
 183                         rtlhal->last_hmeboxnum = 0;
 184 
 185                 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 186                          "pHalData->last_hmeboxnum  = %d\n",
 187                           rtlhal->last_hmeboxnum);
 188         }
 189 
 190         spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
 191         rtlhal->h2c_setinprogress = false;
 192         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
 193 
 194         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
 195 }
 196 
 197 void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
 198                             u32 cmd_len, u8 *p_cmdbuffer)
 199 {
 200         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 201         u32 tmp_cmdbuf[2];
 202 
 203         if (!rtlhal->fw_ready) {
 204                 WARN_ONCE(true,
 205                           "rtl8723be: error H2C cmd because of Fw download fail!!!\n");
 206                 return;
 207         }
 208 
 209         memset(tmp_cmdbuf, 0, 8);
 210         memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
 211         _rtl8723be_fill_h2c_command(hw, element_id, cmd_len,
 212                                     (u8 *)&tmp_cmdbuf);
 213         return;
 214 }
 215 
 216 void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
 217 {
 218         struct rtl_priv *rtlpriv = rtl_priv(hw);
 219         u8 u1_h2c_set_pwrmode[H2C_PWEMODE_LENGTH] = { 0 };
 220         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 221         u8 rlbm, power_state = 0, byte5 = 0;
 222         u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
 223         struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
 224         bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
 225                             btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
 226         bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
 227                           btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
 228 
 229         if (bt_ctrl_lps)
 230                 mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
 231 
 232         RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
 233                  mode, bt_ctrl_lps);
 234 
 235         switch (mode) {
 236         case FW_PS_MIN_MODE:
 237                 rlbm = 0;
 238                 awake_intvl = 2;
 239                 break;
 240         case FW_PS_MAX_MODE:
 241                 rlbm = 1;
 242                 awake_intvl = 2;
 243                 break;
 244         case FW_PS_DTIM_MODE:
 245                 rlbm = 2;
 246                 awake_intvl = ppsc->reg_max_lps_awakeintvl;
 247                 /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
 248                  * is only used in swlps.
 249                  */
 250                 break;
 251         default:
 252                 rlbm = 2;
 253                 awake_intvl = 4;
 254                 break;
 255         }
 256 
 257         if (rtlpriv->mac80211.p2p) {
 258                 awake_intvl = 2;
 259                 rlbm = 1;
 260         }
 261 
 262         if (mode == FW_PS_ACTIVE_MODE) {
 263                 byte5 = 0x40;
 264                 power_state = FW_PWR_STATE_ACTIVE;
 265         } else {
 266                 if (bt_ctrl_lps) {
 267                         byte5 = btc_ops->btc_get_lps_val(rtlpriv);
 268                         power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
 269 
 270                         if ((rlbm == 2) && (byte5 & BIT(4))) {
 271                                 /* Keep awake interval to 1 to prevent from
 272                                  * decreasing coex performance
 273                                  */
 274                                 awake_intvl = 2;
 275                                 rlbm = 2;
 276                         }
 277                 } else {
 278                         byte5 = 0x40;
 279                         power_state = FW_PWR_STATE_RF_OFF;
 280                 }
 281         }
 282 
 283         SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
 284         SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
 285         SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
 286                                          bt_ctrl_lps ? 0 : ppsc->smart_ps);
 287         SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
 288                                                awake_intvl);
 289         SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
 290         SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
 291         SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
 292 
 293         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
 294                       "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
 295                       u1_h2c_set_pwrmode, H2C_PWEMODE_LENGTH);
 296         if (rtlpriv->cfg->ops->get_btc_status())
 297                 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
 298                                              H2C_PWEMODE_LENGTH);
 299         rtl8723be_fill_h2c_cmd(hw, H2C_8723B_SETPWRMODE, H2C_PWEMODE_LENGTH,
 300                                u1_h2c_set_pwrmode);
 301 }
 302 
 303 void rtl8723be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
 304 {
 305         u8 parm[3] = { 0, 0, 0 };
 306         /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
 307          *          bit1=0-->update Media Status to MACID
 308          *          bit1=1-->update Media Status from MACID to MACID_End
 309          * parm[1]: MACID, if this is INFRA_STA, MacID = 0
 310          * parm[2]: MACID_End
 311         */
 312         SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
 313         SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
 314 
 315         rtl8723be_fill_h2c_cmd(hw, H2C_8723B_MSRRPT, 3, parm);
 316 }
 317 
 318 #define BEACON_PG               0 /* ->1 */
 319 #define PSPOLL_PG               2
 320 #define NULL_PG                 3
 321 #define PROBERSP_PG             4 /* ->5 */
 322 #define QOS_NULL_PG             6
 323 #define BT_QOS_NULL_PG  7
 324 
 325 #define TOTAL_RESERVED_PKT_LEN  1024    /* can be up to 1280 (tx_bndy=245) */
 326 
 327 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
 328         /* page 0 beacon */
 329         0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
 330         0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
 331         0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
 332         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 333         0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
 334         0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
 335         0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
 336         0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
 337         0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
 338         0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
 339         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 340         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 341         0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
 342         0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
 343         0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
 344         0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
 345 
 346         /* page 1 beacon */
 347         0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
 348         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 349         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 350         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 351         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 352         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 353         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 354         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 355         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 356         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 357         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 358         0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
 359         0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
 360         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 361         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 362         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 363 
 364         /* page 2  ps-poll */
 365         0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
 366         0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
 367         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 368         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 369         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 370         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 371         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 372         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 373         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 374         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 375         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 376         0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
 377         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
 378         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 379         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 380         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 381 
 382         /* page 3  null */
 383         0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
 384         0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
 385         0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
 386         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 387         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 388         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 389         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 390         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 391         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 392         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 393         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 394         0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
 395         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
 396         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 397         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 398         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 399 
 400         /* page 4  probe_resp */
 401         0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
 402         0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 403         0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
 404         0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
 405         0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
 406         0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
 407         0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
 408         0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
 409         0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
 410         0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
 411         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 412         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 413         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 414         0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
 415         0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 416         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 417 
 418         /* page 5  probe_resp */
 419         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 420         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 421         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 422         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 423         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 424         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 425         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 426         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 427         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 428         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 429         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 430         0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
 431         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
 432         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 433         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 434         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 435 
 436         /* page 6 qos null data */
 437         0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
 438         0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
 439         0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
 440         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 441         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 442         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 443         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 444         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 445         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 446         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 447         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 448         0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
 449         0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
 450         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 451         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 452         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 453 
 454         /* page 7 BT-qos null data */
 455         0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
 456         0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
 457         0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
 458         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 459         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 460         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 461         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 462         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 463         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 464         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 465         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 466         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 467         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 468         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 469         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 470         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 471 
 472 };
 473 
 474 void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
 475                                   bool b_dl_finished)
 476 {
 477         struct rtl_priv *rtlpriv = rtl_priv(hw);
 478         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 479         struct sk_buff *skb = NULL;
 480 
 481         u32 totalpacketlen;
 482         bool rtstatus;
 483         u8 u1rsvdpageloc[5] = { 0 };
 484         bool b_dlok = false;
 485 
 486         u8 *beacon;
 487         u8 *p_pspoll;
 488         u8 *nullfunc;
 489         u8 *p_probersp;
 490         u8 *qosnull;
 491         u8 *btqosnull;
 492         /*---------------------------------------------------------
 493          *                      (1) beacon
 494          *---------------------------------------------------------
 495          */
 496         beacon = &reserved_page_packet[BEACON_PG * 128];
 497         SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
 498         SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
 499 
 500         /*-------------------------------------------------------
 501          *                      (2) ps-poll
 502          *-------------------------------------------------------
 503          */
 504         p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
 505         SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
 506         SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
 507         SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
 508 
 509         SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
 510 
 511         /*--------------------------------------------------------
 512          *                      (3) null data
 513          *--------------------------------------------------------
 514          */
 515         nullfunc = &reserved_page_packet[NULL_PG * 128];
 516         SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
 517         SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
 518         SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
 519 
 520         SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
 521 
 522         /*---------------------------------------------------------
 523          *                      (4) probe response
 524          *---------------------------------------------------------
 525          */
 526         p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
 527         SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
 528         SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
 529         SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
 530 
 531         SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
 532 
 533         /*---------------------------------------------------------
 534          *                      (5) QoS Null
 535          *---------------------------------------------------------
 536          */
 537         qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
 538         SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
 539         SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
 540         SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
 541 
 542         SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
 543 
 544         /*---------------------------------------------------------
 545          *                      (5) QoS Null
 546          *---------------------------------------------------------
 547          */
 548         btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
 549         SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
 550         SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
 551         SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
 552 
 553         SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
 554 
 555         totalpacketlen = TOTAL_RESERVED_PKT_LEN;
 556 
 557         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 558                       "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
 559                       &reserved_page_packet[0], totalpacketlen);
 560         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
 561                       "rtl8723be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
 562                       u1rsvdpageloc, sizeof(u1rsvdpageloc));
 563 
 564         skb = dev_alloc_skb(totalpacketlen);
 565         if (!skb)
 566                 return;
 567         skb_put_data(skb, &reserved_page_packet, totalpacketlen);
 568 
 569         rtstatus = rtl_cmd_send_packet(hw, skb);
 570 
 571         if (rtstatus)
 572                 b_dlok = true;
 573 
 574         if (b_dlok) {
 575                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 576                          "Set RSVD page location to Fw.\n");
 577                 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
 578                               u1rsvdpageloc, sizeof(u1rsvdpageloc));
 579                 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RSVDPAGE,
 580                                        sizeof(u1rsvdpageloc), u1rsvdpageloc);
 581         } else
 582                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 583                          "Set RSVD page location to Fw FAIL!!!!!!.\n");
 584 }
 585 
 586 /*Should check FW support p2p or not.*/
 587 static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
 588                                              u8 ctwindow)
 589 {
 590         u8 u1_ctwindow_period[1] = { ctwindow};
 591 
 592         rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_CTW_CMD, 1,
 593                                u1_ctwindow_period);
 594 }
 595 
 596 void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
 597                                       u8 p2p_ps_state)
 598 {
 599         struct rtl_priv *rtlpriv = rtl_priv(hw);
 600         struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
 601         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 602         struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
 603         struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
 604         u8 i;
 605         u16 ctwindow;
 606         u32 start_time, tsf_low;
 607 
 608         switch (p2p_ps_state) {
 609         case P2P_PS_DISABLE:
 610                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
 611                 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
 612                 break;
 613         case P2P_PS_ENABLE:
 614                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
 615                 /* update CTWindow value. */
 616                 if (p2pinfo->ctwindow > 0) {
 617                         p2p_ps_offload->ctwindow_en = 1;
 618                         ctwindow = p2pinfo->ctwindow;
 619                         rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow);
 620                 }
 621                 /* hw only support 2 set of NoA */
 622                 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
 623                         /* To control the register setting
 624                          * for which NOA
 625                          */
 626                         rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
 627                         if (i == 0)
 628                                 p2p_ps_offload->noa0_en = 1;
 629                         else
 630                                 p2p_ps_offload->noa1_en = 1;
 631 
 632                         /* config P2P NoA Descriptor Register */
 633                         rtl_write_dword(rtlpriv, 0x5E0,
 634                                         p2pinfo->noa_duration[i]);
 635                         rtl_write_dword(rtlpriv, 0x5E4,
 636                                         p2pinfo->noa_interval[i]);
 637 
 638                         /*Get Current TSF value */
 639                         tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
 640 
 641                         start_time = p2pinfo->noa_start_time[i];
 642                         if (p2pinfo->noa_count_type[i] != 1) {
 643                                 while (start_time <= (tsf_low + (50 * 1024))) {
 644                                         start_time += p2pinfo->noa_interval[i];
 645                                         if (p2pinfo->noa_count_type[i] != 255)
 646                                                 p2pinfo->noa_count_type[i]--;
 647                                 }
 648                         }
 649                         rtl_write_dword(rtlpriv, 0x5E8, start_time);
 650                         rtl_write_dword(rtlpriv, 0x5EC,
 651                                         p2pinfo->noa_count_type[i]);
 652                 }
 653 
 654                 if ((p2pinfo->opp_ps == 1) ||
 655                     (p2pinfo->noa_num > 0)) {
 656                         /* rst p2p circuit */
 657                         rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
 658 
 659                         p2p_ps_offload->offload_en = 1;
 660 
 661                         if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
 662                                 p2p_ps_offload->role = 1;
 663                                 p2p_ps_offload->allstasleep = 0;
 664                         } else {
 665                                 p2p_ps_offload->role = 0;
 666                         }
 667                         p2p_ps_offload->discovery = 0;
 668                 }
 669                 break;
 670         case P2P_PS_SCAN:
 671                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
 672                 p2p_ps_offload->discovery = 1;
 673                 break;
 674         case P2P_PS_SCAN_DONE:
 675                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
 676                 p2p_ps_offload->discovery = 0;
 677                 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
 678                 break;
 679         default:
 680                 break;
 681         }
 682 
 683         rtl8723be_fill_h2c_cmd(hw, H2C_8723B_P2P_PS_OFFLOAD, 1,
 684                                (u8 *)p2p_ps_offload);
 685 }

/* [<][>][^][v][top][bottom][index][help] */