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 } 582