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

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

DEFINITIONS

This source file includes following definitions.
  1. _rtl8723e_check_fw_read_last_h2c
  2. _rtl8723e_fill_h2c_command
  3. rtl8723e_fill_h2c_cmd
  4. rtl8723e_set_fw_pwrmode_cmd
  5. rtl8723e_set_fw_rsvdpagepkt
  6. rtl8723e_set_fw_joinbss_report_cmd
  7. rtl8723e_set_p2p_ctw_period_cmd
  8. rtl8723e_set_p2p_ps_offload_cmd

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2009-2012  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 _rtl8723e_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, val_mcutst_1;
  18         bool result = false;
  19 
  20         val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
  21         val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
  22 
  23         if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
  24                 result = true;
  25         return result;
  26 }
  27 
  28 static void _rtl8723e_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
  29                                        u32 cmd_len, u8 *cmdbuffer)
  30 {
  31         struct rtl_priv *rtlpriv = rtl_priv(hw);
  32         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  33         u8 boxnum;
  34         u16 box_reg = 0, box_extreg = 0;
  35         u8 u1b_tmp;
  36         bool isfw_read = false;
  37         u8 buf_index = 0;
  38         bool bwrite_sucess = false;
  39         u8 wait_h2c_limmit = 100;
  40         u8 wait_writeh2c_limmit = 100;
  41         u8 boxcontent[4], boxextcontent[2];
  42         u32 h2c_waitcounter = 0;
  43         unsigned long flag;
  44         u8 idx;
  45 
  46         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
  47 
  48         while (true) {
  49                 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
  50                 if (rtlhal->h2c_setinprogress) {
  51                         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
  52                                  "H2C set in progress! Wait to set..element_id(%d).\n",
  53                                  element_id);
  54 
  55                         while (rtlhal->h2c_setinprogress) {
  56                                 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
  57                                                        flag);
  58                                 h2c_waitcounter++;
  59                                 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
  60                                          "Wait 100 us (%d times)...\n",
  61                                           h2c_waitcounter);
  62                                 udelay(100);
  63 
  64                                 if (h2c_waitcounter > 1000)
  65                                         return;
  66                                 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
  67                                                   flag);
  68                         }
  69                         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
  70                 } else {
  71                         rtlhal->h2c_setinprogress = true;
  72                         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
  73                         break;
  74                 }
  75         }
  76 
  77         while (!bwrite_sucess) {
  78                 wait_writeh2c_limmit--;
  79                 if (wait_writeh2c_limmit == 0) {
  80                         pr_err("Write H2C fail because no trigger for FW INT!\n");
  81                         break;
  82                 }
  83 
  84                 boxnum = rtlhal->last_hmeboxnum;
  85                 switch (boxnum) {
  86                 case 0:
  87                         box_reg = REG_HMEBOX_0;
  88                         box_extreg = REG_HMEBOX_EXT_0;
  89                         break;
  90                 case 1:
  91                         box_reg = REG_HMEBOX_1;
  92                         box_extreg = REG_HMEBOX_EXT_1;
  93                         break;
  94                 case 2:
  95                         box_reg = REG_HMEBOX_2;
  96                         box_extreg = REG_HMEBOX_EXT_2;
  97                         break;
  98                 case 3:
  99                         box_reg = REG_HMEBOX_3;
 100                         box_extreg = REG_HMEBOX_EXT_3;
 101                         break;
 102                 default:
 103                         pr_err("switch case %#x not processed\n",
 104                                boxnum);
 105                         break;
 106                 }
 107 
 108                 isfw_read = _rtl8723e_check_fw_read_last_h2c(hw, boxnum);
 109                 while (!isfw_read) {
 110 
 111                         wait_h2c_limmit--;
 112                         if (wait_h2c_limmit == 0) {
 113                                 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 114                                          "Waiting too long for FW read clear HMEBox(%d)!\n",
 115                                          boxnum);
 116                                 break;
 117                         }
 118 
 119                         udelay(10);
 120 
 121                         isfw_read = _rtl8723e_check_fw_read_last_h2c(hw,
 122                                                                 boxnum);
 123                         u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
 124                         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 125                                  "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
 126                                  boxnum, u1b_tmp);
 127                 }
 128 
 129                 if (!isfw_read) {
 130                         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 131                                  "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
 132                                  boxnum);
 133                         break;
 134                 }
 135 
 136                 memset(boxcontent, 0, sizeof(boxcontent));
 137                 memset(boxextcontent, 0, sizeof(boxextcontent));
 138                 boxcontent[0] = element_id;
 139                 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 140                          "Write element_id box_reg(%4x) = %2x\n",
 141                           box_reg, element_id);
 142 
 143                 switch (cmd_len) {
 144                 case 1:
 145                         boxcontent[0] &= ~(BIT(7));
 146                         memcpy((u8 *)(boxcontent) + 1,
 147                                cmdbuffer + buf_index, 1);
 148 
 149                         for (idx = 0; idx < 4; idx++) {
 150                                 rtl_write_byte(rtlpriv, box_reg + idx,
 151                                                boxcontent[idx]);
 152                         }
 153                         break;
 154                 case 2:
 155                         boxcontent[0] &= ~(BIT(7));
 156                         memcpy((u8 *)(boxcontent) + 1,
 157                                cmdbuffer + buf_index, 2);
 158 
 159                         for (idx = 0; idx < 4; idx++) {
 160                                 rtl_write_byte(rtlpriv, box_reg + idx,
 161                                                boxcontent[idx]);
 162                         }
 163                         break;
 164                 case 3:
 165                         boxcontent[0] &= ~(BIT(7));
 166                         memcpy((u8 *)(boxcontent) + 1,
 167                                cmdbuffer + buf_index, 3);
 168 
 169                         for (idx = 0; idx < 4; idx++) {
 170                                 rtl_write_byte(rtlpriv, box_reg + idx,
 171                                                boxcontent[idx]);
 172                         }
 173                         break;
 174                 case 4:
 175                         boxcontent[0] |= (BIT(7));
 176                         memcpy((u8 *)(boxextcontent),
 177                                cmdbuffer + buf_index, 2);
 178                         memcpy((u8 *)(boxcontent) + 1,
 179                                cmdbuffer + buf_index + 2, 2);
 180 
 181                         for (idx = 0; idx < 2; idx++) {
 182                                 rtl_write_byte(rtlpriv, box_extreg + idx,
 183                                                boxextcontent[idx]);
 184                         }
 185 
 186                         for (idx = 0; idx < 4; idx++) {
 187                                 rtl_write_byte(rtlpriv, box_reg + idx,
 188                                                boxcontent[idx]);
 189                         }
 190                         break;
 191                 case 5:
 192                         boxcontent[0] |= (BIT(7));
 193                         memcpy((u8 *)(boxextcontent),
 194                                cmdbuffer + buf_index, 2);
 195                         memcpy((u8 *)(boxcontent) + 1,
 196                                cmdbuffer + buf_index + 2, 3);
 197 
 198                         for (idx = 0; idx < 2; idx++) {
 199                                 rtl_write_byte(rtlpriv, box_extreg + idx,
 200                                                boxextcontent[idx]);
 201                         }
 202 
 203                         for (idx = 0; idx < 4; idx++) {
 204                                 rtl_write_byte(rtlpriv, box_reg + idx,
 205                                                boxcontent[idx]);
 206                         }
 207                         break;
 208                 default:
 209                         pr_err("switch case %#x not processed\n",
 210                                cmd_len);
 211                         break;
 212                 }
 213 
 214                 bwrite_sucess = true;
 215 
 216                 rtlhal->last_hmeboxnum = boxnum + 1;
 217                 if (rtlhal->last_hmeboxnum == 4)
 218                         rtlhal->last_hmeboxnum = 0;
 219 
 220                 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
 221                          "pHalData->last_hmeboxnum  = %d\n",
 222                           rtlhal->last_hmeboxnum);
 223         }
 224 
 225         spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
 226         rtlhal->h2c_setinprogress = false;
 227         spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
 228 
 229         RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
 230 }
 231 
 232 void rtl8723e_fill_h2c_cmd(struct ieee80211_hw *hw,
 233                            u8 element_id, u32 cmd_len, u8 *cmdbuffer)
 234 {
 235         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 236         u32 tmp_cmdbuf[2];
 237 
 238         if (!rtlhal->fw_ready) {
 239                 WARN_ONCE(true,
 240                           "rtl8723ae: error H2C cmd because of Fw download fail!!!\n");
 241                 return;
 242         }
 243         memset(tmp_cmdbuf, 0, 8);
 244         memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
 245         _rtl8723e_fill_h2c_command(hw, element_id, cmd_len,
 246                                    (u8 *)&tmp_cmdbuf);
 247 }
 248 
 249 void rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
 250 {
 251         struct rtl_priv *rtlpriv = rtl_priv(hw);
 252         u8 u1_h2c_set_pwrmode[3] = { 0 };
 253         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 254 
 255         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
 256 
 257         SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
 258         SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
 259                 (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
 260         SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
 261                                               ppsc->reg_max_lps_awakeintvl);
 262 
 263         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
 264                       "rtl8723e_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
 265                       u1_h2c_set_pwrmode, 3);
 266         rtl8723e_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
 267 }
 268 
 269 #define BEACON_PG               0 /* ->1 */
 270 #define PSPOLL_PG               2
 271 #define NULL_PG                 3
 272 #define PROBERSP_PG             4 /* ->5 */
 273 
 274 #define TOTAL_RESERVED_PKT_LEN  768
 275 
 276 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
 277         /* page 0 beacon */
 278         0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
 279         0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 280         0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
 281         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 282         0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
 283         0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
 284         0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
 285         0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
 286         0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
 287         0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
 288         0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 289         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 290         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 291         0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
 292         0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 293         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 294 
 295         /* page 1 beacon */
 296         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 297         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 298         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 299         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 300         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 301         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 302         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 303         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 304         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 305         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 306         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 307         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 308         0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
 309         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 310         0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 311         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 312 
 313         /* page 2  ps-poll */
 314         0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
 315         0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 316         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 317         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 318         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 319         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 320         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 321         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 322         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 323         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 324         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 325         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 326         0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
 327         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 328         0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 329         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 330 
 331         /* page 3  null */
 332         0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
 333         0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 334         0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
 335         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 336         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 337         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 338         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 339         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 340         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 341         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 342         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 343         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 344         0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
 345         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 346         0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 347         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 348 
 349         /* page 4  probe_resp */
 350         0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
 351         0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
 352         0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
 353         0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
 354         0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
 355         0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
 356         0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
 357         0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
 358         0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
 359         0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
 360         0x03, 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         0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
 364         0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 365         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 366 
 367         /* page 5  probe_resp */
 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         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 377         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 378         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 379         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 380         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 381         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 382         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 383         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 384 };
 385 
 386 void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
 387 {
 388         struct rtl_priv *rtlpriv = rtl_priv(hw);
 389         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 390         struct sk_buff *skb = NULL;
 391         u32 totalpacketlen;
 392         bool rtstatus;
 393         u8 u1rsvdpageloc[3] = { 0 };
 394         bool b_dlok = false;
 395         u8 *beacon;
 396         u8 *p_pspoll;
 397         u8 *nullfunc;
 398         u8 *p_probersp;
 399 
 400         /*---------------------------------------------------------
 401          *                      (1) beacon
 402          *---------------------------------------------------------
 403          */
 404         beacon = &reserved_page_packet[BEACON_PG * 128];
 405         SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
 406         SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
 407 
 408         /*-------------------------------------------------------
 409          *                      (2) ps-poll
 410          *--------------------------------------------------------
 411          */
 412         p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
 413         SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
 414         SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
 415         SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
 416 
 417         SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
 418 
 419         /*--------------------------------------------------------
 420          *                      (3) null data
 421          *---------------------------------------------------------
 422          */
 423         nullfunc = &reserved_page_packet[NULL_PG * 128];
 424         SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
 425         SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
 426         SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
 427 
 428         SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
 429 
 430         /*---------------------------------------------------------
 431          *                      (4) probe response
 432          *----------------------------------------------------------
 433          */
 434         p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
 435         SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
 436         SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
 437         SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
 438 
 439         SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
 440 
 441         totalpacketlen = TOTAL_RESERVED_PKT_LEN;
 442 
 443         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
 444                       "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
 445                       &reserved_page_packet[0], totalpacketlen);
 446         RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
 447                       "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
 448                       u1rsvdpageloc, 3);
 449 
 450         skb = dev_alloc_skb(totalpacketlen);
 451         if (!skb)
 452                 return;
 453         skb_put_data(skb, &reserved_page_packet, totalpacketlen);
 454 
 455         rtstatus = rtl_cmd_send_packet(hw, skb);
 456 
 457         if (rtstatus)
 458                 b_dlok = true;
 459 
 460         if (b_dlok) {
 461                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 462                          "Set RSVD page location to Fw.\n");
 463                 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
 464                               "H2C_RSVDPAGE:\n",
 465                               u1rsvdpageloc, 3);
 466                 rtl8723e_fill_h2c_cmd(hw, H2C_RSVDPAGE,
 467                                       sizeof(u1rsvdpageloc), u1rsvdpageloc);
 468         } else
 469                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 470                          "Set RSVD page location to Fw FAIL!!!!!!.\n");
 471 }
 472 
 473 void rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
 474 {
 475         u8 u1_joinbssrpt_parm[1] = { 0 };
 476 
 477         SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
 478 
 479         rtl8723e_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
 480 }
 481 
 482 static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
 483                                             u8 ctwindow)
 484 {
 485         u8 u1_ctwindow_period[1] = { ctwindow};
 486 
 487         rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
 488 
 489 }
 490 
 491 void rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
 492 {
 493         struct rtl_priv *rtlpriv = rtl_priv(hw);
 494         struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
 495         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 496         struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
 497         struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
 498         u8      i;
 499         u16     ctwindow;
 500         u32     start_time, tsf_low;
 501 
 502         switch (p2p_ps_state) {
 503         case P2P_PS_DISABLE:
 504                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
 505                 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
 506                 break;
 507         case P2P_PS_ENABLE:
 508                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
 509                 /* update CTWindow value. */
 510                 if (p2pinfo->ctwindow > 0) {
 511                         p2p_ps_offload->ctwindow_en = 1;
 512                         ctwindow = p2pinfo->ctwindow;
 513                         rtl8723e_set_p2p_ctw_period_cmd(hw, ctwindow);
 514                 }
 515 
 516                 /* hw only support 2 set of NoA */
 517                 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
 518                         /* To control the register setting for which NOA*/
 519                         rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
 520                         if (i == 0)
 521                                 p2p_ps_offload->noa0_en = 1;
 522                         else
 523                                 p2p_ps_offload->noa1_en = 1;
 524 
 525                         /* config P2P NoA Descriptor Register */
 526                         rtl_write_dword(rtlpriv, 0x5E0,
 527                                         p2pinfo->noa_duration[i]);
 528                         rtl_write_dword(rtlpriv, 0x5E4,
 529                                         p2pinfo->noa_interval[i]);
 530 
 531                         /*Get Current TSF value */
 532                         tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
 533 
 534                         start_time = p2pinfo->noa_start_time[i];
 535                         if (p2pinfo->noa_count_type[i] != 1) {
 536                                 while (start_time <=
 537                                         (tsf_low+(50*1024))) {
 538                                         start_time +=
 539                                                 p2pinfo->noa_interval[i];
 540                                         if (p2pinfo->noa_count_type[i] != 255)
 541                                                 p2pinfo->noa_count_type[i]--;
 542                                 }
 543                         }
 544                         rtl_write_dword(rtlpriv, 0x5E8, start_time);
 545                         rtl_write_dword(rtlpriv, 0x5EC,
 546                                 p2pinfo->noa_count_type[i]);
 547 
 548                 }
 549 
 550                 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
 551                         /* rst p2p circuit */
 552                         rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
 553 
 554                         p2p_ps_offload->offload_en = 1;
 555 
 556                         if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
 557                                 p2p_ps_offload->role = 1;
 558                                 p2p_ps_offload->allstasleep = 0;
 559                         } else {
 560                                 p2p_ps_offload->role = 0;
 561                         }
 562 
 563                         p2p_ps_offload->discovery = 0;
 564                 }
 565                 break;
 566         case P2P_PS_SCAN:
 567                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
 568                 p2p_ps_offload->discovery = 1;
 569                 break;
 570         case P2P_PS_SCAN_DONE:
 571                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
 572                 p2p_ps_offload->discovery = 0;
 573                 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
 574                 break;
 575         default:
 576                 break;
 577         }
 578 
 579         rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
 580 
 581 }

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