fw.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009-2014 Realtek Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * The full GNU General Public License is included in this distribution in the
  15. * file called LICENSE.
  16. *
  17. * Contact Information:
  18. * wlanfae <wlanfae@realtek.com>
  19. * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20. * Hsinchu 300, Taiwan.
  21. *
  22. * Larry Finger <Larry.Finger@lwfinger.net>
  23. *
  24. *****************************************************************************/
  25. #include "../wifi.h"
  26. #include "../pci.h"
  27. #include "../base.h"
  28. #include "../core.h"
  29. #include "../efuse.h"
  30. #include "reg.h"
  31. #include "def.h"
  32. #include "fw.h"
  33. #include "dm.h"
  34. static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable)
  35. {
  36. struct rtl_priv *rtlpriv = rtl_priv(hw);
  37. u8 tmp;
  38. if (enable) {
  39. rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05);
  40. tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
  41. rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
  42. } else {
  43. tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
  44. rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
  45. }
  46. }
  47. static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
  48. enum version_8192e version,
  49. u8 *buffer, u32 size)
  50. {
  51. struct rtl_priv *rtlpriv = rtl_priv(hw);
  52. u8 *bufferptr = (u8 *)buffer;
  53. u32 pagenums, remainsize;
  54. u32 page, offset;
  55. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "FW size is %d bytes,\n", size);
  56. rtl_fill_dummy(bufferptr, &size);
  57. pagenums = size / FW_8192C_PAGE_SIZE;
  58. remainsize = size % FW_8192C_PAGE_SIZE;
  59. if (pagenums > 8)
  60. pr_err("Page numbers should not greater then 8\n");
  61. for (page = 0; page < pagenums; page++) {
  62. offset = page * FW_8192C_PAGE_SIZE;
  63. rtl_fw_page_write(hw, page, (bufferptr + offset),
  64. FW_8192C_PAGE_SIZE);
  65. udelay(2);
  66. }
  67. if (remainsize) {
  68. offset = pagenums * FW_8192C_PAGE_SIZE;
  69. page = pagenums;
  70. rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
  71. }
  72. }
  73. static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw)
  74. {
  75. struct rtl_priv *rtlpriv = rtl_priv(hw);
  76. int err = -EIO;
  77. u32 counter = 0;
  78. u32 value32;
  79. do {
  80. value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
  81. } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
  82. (!(value32 & FWDL_CHKSUM_RPT)));
  83. if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
  84. pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
  85. value32);
  86. goto exit;
  87. }
  88. value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
  89. value32 |= MCUFWDL_RDY;
  90. value32 &= ~WINTINI_RDY;
  91. rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
  92. rtl92ee_firmware_selfreset(hw);
  93. counter = 0;
  94. do {
  95. value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
  96. if (value32 & WINTINI_RDY)
  97. return 0;
  98. udelay(FW_8192C_POLLING_DELAY*10);
  99. } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
  100. pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n",
  101. value32, counter);
  102. exit:
  103. return err;
  104. }
  105. int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
  106. {
  107. struct rtl_priv *rtlpriv = rtl_priv(hw);
  108. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  109. struct rtlwifi_firmware_header *pfwheader;
  110. u8 *pfwdata;
  111. u32 fwsize;
  112. int err;
  113. enum version_8192e version = rtlhal->version;
  114. if (!rtlhal->pfirmware)
  115. return 1;
  116. pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
  117. rtlhal->fw_version = le16_to_cpu(pfwheader->version);
  118. rtlhal->fw_subversion = pfwheader->subversion;
  119. pfwdata = (u8 *)rtlhal->pfirmware;
  120. fwsize = rtlhal->fwsize;
  121. RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
  122. "normal Firmware SIZE %d\n" , fwsize);
  123. if (IS_FW_HEADER_EXIST(pfwheader)) {
  124. RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
  125. "Firmware Version(%d), Signature(%#x),Size(%d)\n",
  126. pfwheader->version, pfwheader->signature,
  127. (int)sizeof(struct rtlwifi_firmware_header));
  128. pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
  129. fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
  130. } else {
  131. RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
  132. "Firmware no Header, Signature(%#x)\n",
  133. pfwheader->signature);
  134. }
  135. if (rtlhal->mac_func_enable) {
  136. if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
  137. rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
  138. rtl92ee_firmware_selfreset(hw);
  139. }
  140. }
  141. _rtl92ee_enable_fw_download(hw, true);
  142. _rtl92ee_write_fw(hw, version, pfwdata, fwsize);
  143. _rtl92ee_enable_fw_download(hw, false);
  144. err = _rtl92ee_fw_free_to_go(hw);
  145. return 0;
  146. }
  147. static bool _rtl92ee_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
  148. {
  149. struct rtl_priv *rtlpriv = rtl_priv(hw);
  150. u8 val_hmetfr;
  151. bool result = false;
  152. val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
  153. if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
  154. result = true;
  155. return result;
  156. }
  157. static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
  158. u32 cmd_len, u8 *cmdbuffer)
  159. {
  160. struct rtl_priv *rtlpriv = rtl_priv(hw);
  161. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  162. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  163. u8 boxnum;
  164. u16 box_reg = 0, box_extreg = 0;
  165. u8 u1b_tmp;
  166. bool isfw_read = false;
  167. u8 buf_index = 0;
  168. bool bwrite_sucess = false;
  169. u8 wait_h2c_limmit = 100;
  170. u8 boxcontent[4], boxextcontent[4];
  171. u32 h2c_waitcounter = 0;
  172. unsigned long flag;
  173. u8 idx;
  174. if (ppsc->dot11_psmode != EACTIVE ||
  175. ppsc->inactive_pwrstate == ERFOFF) {
  176. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
  177. "FillH2CCommand8192E(): Return because RF is off!!!\n");
  178. return;
  179. }
  180. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , "come in\n");
  181. /* 1. Prevent race condition in setting H2C cmd.
  182. * (copy from MgntActSet_RF_State().)
  183. */
  184. while (true) {
  185. spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
  186. if (rtlhal->h2c_setinprogress) {
  187. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
  188. "H2C set in progress! Wait to set..element_id(%d).\n",
  189. element_id);
  190. while (rtlhal->h2c_setinprogress) {
  191. spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
  192. flag);
  193. h2c_waitcounter++;
  194. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
  195. "Wait 100 us (%d times)...\n",
  196. h2c_waitcounter);
  197. udelay(100);
  198. if (h2c_waitcounter > 1000)
  199. return;
  200. spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
  201. flag);
  202. }
  203. spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
  204. } else {
  205. rtlhal->h2c_setinprogress = true;
  206. spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
  207. break;
  208. }
  209. }
  210. while (!bwrite_sucess) {
  211. /* 2. Find the last BOX number which has been writen. */
  212. boxnum = rtlhal->last_hmeboxnum;
  213. switch (boxnum) {
  214. case 0:
  215. box_reg = REG_HMEBOX_0;
  216. box_extreg = REG_HMEBOX_EXT_0;
  217. break;
  218. case 1:
  219. box_reg = REG_HMEBOX_1;
  220. box_extreg = REG_HMEBOX_EXT_1;
  221. break;
  222. case 2:
  223. box_reg = REG_HMEBOX_2;
  224. box_extreg = REG_HMEBOX_EXT_2;
  225. break;
  226. case 3:
  227. box_reg = REG_HMEBOX_3;
  228. box_extreg = REG_HMEBOX_EXT_3;
  229. break;
  230. default:
  231. RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
  232. "switch case %#x not processed\n", boxnum);
  233. break;
  234. }
  235. /* 3. Check if the box content is empty. */
  236. isfw_read = false;
  237. u1b_tmp = rtl_read_byte(rtlpriv, REG_CR);
  238. if (u1b_tmp != 0xea) {
  239. isfw_read = true;
  240. } else {
  241. if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xea ||
  242. rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xea)
  243. rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xff);
  244. }
  245. if (isfw_read) {
  246. wait_h2c_limmit = 100;
  247. isfw_read = _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
  248. while (!isfw_read) {
  249. wait_h2c_limmit--;
  250. if (wait_h2c_limmit == 0) {
  251. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
  252. "Waiting too long for FW read clear HMEBox(%d)!!!\n",
  253. boxnum);
  254. break;
  255. }
  256. udelay(10);
  257. isfw_read =
  258. _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
  259. u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
  260. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
  261. "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
  262. boxnum, u1b_tmp);
  263. }
  264. }
  265. /* If Fw has not read the last
  266. * H2C cmd, break and give up this H2C.
  267. */
  268. if (!isfw_read) {
  269. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
  270. "Write H2C reg BOX[%d] fail,Fw don't read.\n",
  271. boxnum);
  272. break;
  273. }
  274. /* 4. Fill the H2C cmd into box */
  275. memset(boxcontent, 0, sizeof(boxcontent));
  276. memset(boxextcontent, 0, sizeof(boxextcontent));
  277. boxcontent[0] = element_id;
  278. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
  279. "Write element_id box_reg(%4x) = %2x\n",
  280. box_reg, element_id);
  281. switch (cmd_len) {
  282. case 1:
  283. case 2:
  284. case 3:
  285. /*boxcontent[0] &= ~(BIT(7));*/
  286. memcpy((u8 *)(boxcontent) + 1,
  287. cmdbuffer + buf_index, cmd_len);
  288. for (idx = 0; idx < 4; idx++) {
  289. rtl_write_byte(rtlpriv, box_reg + idx,
  290. boxcontent[idx]);
  291. }
  292. break;
  293. case 4:
  294. case 5:
  295. case 6:
  296. case 7:
  297. /*boxcontent[0] |= (BIT(7));*/
  298. memcpy((u8 *)(boxextcontent),
  299. cmdbuffer + buf_index+3, cmd_len-3);
  300. memcpy((u8 *)(boxcontent) + 1,
  301. cmdbuffer + buf_index, 3);
  302. for (idx = 0; idx < 4; idx++) {
  303. rtl_write_byte(rtlpriv, box_extreg + idx,
  304. boxextcontent[idx]);
  305. }
  306. for (idx = 0; idx < 4; idx++) {
  307. rtl_write_byte(rtlpriv, box_reg + idx,
  308. boxcontent[idx]);
  309. }
  310. break;
  311. default:
  312. RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
  313. "switch case %#x not processed\n", cmd_len);
  314. break;
  315. }
  316. bwrite_sucess = true;
  317. rtlhal->last_hmeboxnum = boxnum + 1;
  318. if (rtlhal->last_hmeboxnum == 4)
  319. rtlhal->last_hmeboxnum = 0;
  320. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
  321. "pHalData->last_hmeboxnum = %d\n",
  322. rtlhal->last_hmeboxnum);
  323. }
  324. spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
  325. rtlhal->h2c_setinprogress = false;
  326. spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
  327. RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , "go out\n");
  328. }
  329. void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw,
  330. u8 element_id, u32 cmd_len, u8 *cmdbuffer)
  331. {
  332. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  333. u32 tmp_cmdbuf[2];
  334. if (!rtlhal->fw_ready) {
  335. WARN_ONCE(true,
  336. "rtl8192ee: error H2C cmd because of Fw download fail!!!\n");
  337. return;
  338. }
  339. memset(tmp_cmdbuf, 0, 8);
  340. memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
  341. _rtl92ee_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
  342. }
  343. void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw)
  344. {
  345. u8 u1b_tmp;
  346. struct rtl_priv *rtlpriv = rtl_priv(hw);
  347. u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
  348. rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
  349. u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
  350. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
  351. udelay(50);
  352. u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
  353. rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0)));
  354. u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
  355. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2)));
  356. RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD ,
  357. " _8051Reset92E(): 8051 reset success .\n");
  358. }
  359. void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
  360. {
  361. struct rtl_priv *rtlpriv = rtl_priv(hw);
  362. u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 };
  363. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  364. u8 rlbm, power_state = 0, byte5 = 0;
  365. u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
  366. struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
  367. bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
  368. btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
  369. bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
  370. btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
  371. if (bt_ctrl_lps)
  372. mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
  373. RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
  374. mode, bt_ctrl_lps);
  375. switch (mode) {
  376. case FW_PS_MIN_MODE:
  377. rlbm = 0;
  378. awake_intvl = 2;
  379. break;
  380. case FW_PS_MAX_MODE:
  381. rlbm = 1;
  382. awake_intvl = 2;
  383. break;
  384. case FW_PS_DTIM_MODE:
  385. rlbm = 2;
  386. awake_intvl = ppsc->reg_max_lps_awakeintvl;
  387. /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
  388. * is only used in swlps.
  389. */
  390. break;
  391. default:
  392. rlbm = 2;
  393. awake_intvl = 4;
  394. break;
  395. }
  396. if (rtlpriv->mac80211.p2p) {
  397. awake_intvl = 2;
  398. rlbm = 1;
  399. }
  400. if (mode == FW_PS_ACTIVE_MODE) {
  401. byte5 = 0x40;
  402. power_state = FW_PWR_STATE_ACTIVE;
  403. } else {
  404. if (bt_ctrl_lps) {
  405. byte5 = btc_ops->btc_get_lps_val(rtlpriv);
  406. power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
  407. if ((rlbm == 2) && (byte5 & BIT(4))) {
  408. /* Keep awake interval to 1 to prevent from
  409. * decreasing coex performance
  410. */
  411. awake_intvl = 2;
  412. rlbm = 2;
  413. }
  414. } else {
  415. byte5 = 0x40;
  416. power_state = FW_PWR_STATE_RF_OFF;
  417. }
  418. }
  419. SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
  420. SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
  421. SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
  422. bt_ctrl_lps ? 0 :
  423. ((rtlpriv->mac80211.p2p) ?
  424. ppsc->smart_ps : 1));
  425. SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
  426. awake_intvl);
  427. SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
  428. SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
  429. SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
  430. RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
  431. "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
  432. u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH);
  433. if (rtlpriv->cfg->ops->get_btc_status())
  434. btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
  435. H2C_92E_PWEMODE_LENGTH);
  436. rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH,
  437. u1_h2c_set_pwrmode);
  438. }
  439. void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
  440. {
  441. u8 parm[3] = { 0 , 0 , 0 };
  442. /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
  443. * bit1=0-->update Media Status to MACID
  444. * bit1=1-->update Media Status from MACID to MACID_End
  445. * parm[1]: MACID, if this is INFRA_STA, MacID = 0
  446. * parm[2]: MACID_End
  447. */
  448. SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
  449. SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
  450. rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
  451. }
  452. #define BEACON_PG 0 /* ->1 */
  453. #define PSPOLL_PG 2
  454. #define NULL_PG 3
  455. #define PROBERSP_PG 4 /* ->5 */
  456. #define QOS_NULL_PG 6
  457. #define BT_QOS_NULL_PG 7
  458. #define TOTAL_RESERVED_PKT_LEN 1024
  459. static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
  460. /* page 0 beacon */
  461. 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
  462. 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
  463. 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
  464. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  465. 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
  466. 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
  467. 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
  468. 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
  469. 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
  470. 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
  471. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  472. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  473. 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
  474. 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
  475. 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
  476. 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
  477. /* page 1 beacon */
  478. 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
  479. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  480. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  481. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  482. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  483. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  484. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  485. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  486. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  487. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  488. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  489. 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
  490. 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
  491. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  492. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  493. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  494. /* page 2 ps-poll */
  495. 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
  496. 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
  497. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  498. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  499. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  500. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  501. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  502. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  503. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  504. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  505. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  506. 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
  507. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  508. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  509. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  510. 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  511. /* page 3 null */
  512. 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
  513. 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
  514. 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
  515. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  516. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  517. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  518. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  519. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  520. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  521. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  522. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  523. 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
  524. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  525. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  526. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  527. 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  528. /* page 4 probe_resp */
  529. 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
  530. 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
  531. 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
  532. 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
  533. 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
  534. 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
  535. 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
  536. 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
  537. 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
  538. 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
  539. 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  540. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  541. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  542. 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
  543. 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  544. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  545. /* page 5 probe_resp */
  546. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  547. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  548. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  549. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  550. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  551. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  552. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  553. 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
  554. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  555. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  556. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  557. 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  558. /* page 6 qos null data */
  559. 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
  560. 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
  561. 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
  562. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  563. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  564. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  565. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  566. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  567. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  568. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  569. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  570. 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
  571. 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
  572. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  573. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  574. 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  575. /* page 7 BT-qos null data */
  576. 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
  577. 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
  578. 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
  579. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  580. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  581. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  582. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  583. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  584. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  585. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  586. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  587. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  588. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  589. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  590. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  591. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  592. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  593. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  594. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  595. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  596. };
  597. void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
  598. {
  599. struct rtl_priv *rtlpriv = rtl_priv(hw);
  600. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  601. struct sk_buff *skb = NULL;
  602. bool rtstatus;
  603. u32 totalpacketlen;
  604. u8 u1rsvdpageloc[5] = { 0 };
  605. bool b_dlok = false;
  606. u8 *beacon;
  607. u8 *p_pspoll;
  608. u8 *nullfunc;
  609. u8 *p_probersp;
  610. u8 *qosnull;
  611. u8 *btqosnull;
  612. /*---------------------------------------------------------
  613. * (1) beacon
  614. *---------------------------------------------------------
  615. */
  616. beacon = &reserved_page_packet[BEACON_PG * 128];
  617. SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
  618. SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
  619. /*-------------------------------------------------------
  620. * (2) ps-poll
  621. *--------------------------------------------------------
  622. */
  623. p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
  624. SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
  625. SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
  626. SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
  627. SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
  628. /*--------------------------------------------------------
  629. * (3) null data
  630. *---------------------------------------------------------
  631. */
  632. nullfunc = &reserved_page_packet[NULL_PG * 128];
  633. SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
  634. SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
  635. SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
  636. SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
  637. /*---------------------------------------------------------
  638. * (4) probe response
  639. *----------------------------------------------------------
  640. */
  641. p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
  642. SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
  643. SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
  644. SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
  645. SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
  646. /*---------------------------------------------------------
  647. * (5) QoS null data
  648. *----------------------------------------------------------
  649. */
  650. qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
  651. SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
  652. SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
  653. SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
  654. SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
  655. /*---------------------------------------------------------
  656. * (6) BT QoS null data
  657. *----------------------------------------------------------
  658. */
  659. btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
  660. SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
  661. SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
  662. SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
  663. SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
  664. totalpacketlen = TOTAL_RESERVED_PKT_LEN;
  665. RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
  666. "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
  667. &reserved_page_packet[0], totalpacketlen);
  668. RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
  669. "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
  670. u1rsvdpageloc, 3);
  671. skb = dev_alloc_skb(totalpacketlen);
  672. if (!skb)
  673. return;
  674. skb_put_data(skb, &reserved_page_packet, totalpacketlen);
  675. rtstatus = rtl_cmd_send_packet(hw, skb);
  676. if (rtstatus)
  677. b_dlok = true;
  678. if (b_dlok) {
  679. RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
  680. "Set RSVD page location to Fw.\n");
  681. RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
  682. "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
  683. rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE,
  684. sizeof(u1rsvdpageloc), u1rsvdpageloc);
  685. } else {
  686. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  687. "Set RSVD page location to Fw FAIL!!!!!!.\n");
  688. }
  689. }
  690. /*Shoud check FW support p2p or not.*/
  691. static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
  692. {
  693. u8 u1_ctwindow_period[1] = {ctwindow};
  694. rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
  695. }
  696. void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
  697. {
  698. struct rtl_priv *rtlpriv = rtl_priv(hw);
  699. struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
  700. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  701. struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
  702. struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
  703. u8 i;
  704. u16 ctwindow;
  705. u32 start_time, tsf_low;
  706. switch (p2p_ps_state) {
  707. case P2P_PS_DISABLE:
  708. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_DISABLE\n");
  709. memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
  710. break;
  711. case P2P_PS_ENABLE:
  712. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_ENABLE\n");
  713. /* update CTWindow value. */
  714. if (p2pinfo->ctwindow > 0) {
  715. p2p_ps_offload->ctwindow_en = 1;
  716. ctwindow = p2pinfo->ctwindow;
  717. rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow);
  718. }
  719. /* hw only support 2 set of NoA */
  720. for (i = 0 ; i < p2pinfo->noa_num ; i++) {
  721. /* To control the register setting for which NOA*/
  722. rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
  723. if (i == 0)
  724. p2p_ps_offload->noa0_en = 1;
  725. else
  726. p2p_ps_offload->noa1_en = 1;
  727. /* config P2P NoA Descriptor Register */
  728. rtl_write_dword(rtlpriv, 0x5E0,
  729. p2pinfo->noa_duration[i]);
  730. rtl_write_dword(rtlpriv, 0x5E4,
  731. p2pinfo->noa_interval[i]);
  732. /*Get Current TSF value */
  733. tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
  734. start_time = p2pinfo->noa_start_time[i];
  735. if (p2pinfo->noa_count_type[i] != 1) {
  736. while (start_time <= (tsf_low + (50 * 1024))) {
  737. start_time += p2pinfo->noa_interval[i];
  738. if (p2pinfo->noa_count_type[i] != 255)
  739. p2pinfo->noa_count_type[i]--;
  740. }
  741. }
  742. rtl_write_dword(rtlpriv, 0x5E8, start_time);
  743. rtl_write_dword(rtlpriv, 0x5EC,
  744. p2pinfo->noa_count_type[i]);
  745. }
  746. if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
  747. /* rst p2p circuit */
  748. rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
  749. p2p_ps_offload->offload_en = 1;
  750. if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
  751. p2p_ps_offload->role = 1;
  752. p2p_ps_offload->allstasleep = 0;
  753. } else {
  754. p2p_ps_offload->role = 0;
  755. }
  756. p2p_ps_offload->discovery = 0;
  757. }
  758. break;
  759. case P2P_PS_SCAN:
  760. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN\n");
  761. p2p_ps_offload->discovery = 1;
  762. break;
  763. case P2P_PS_SCAN_DONE:
  764. RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN_DONE\n");
  765. p2p_ps_offload->discovery = 0;
  766. p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
  767. break;
  768. default:
  769. break;
  770. }
  771. rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1,
  772. (u8 *)p2p_ps_offload);
  773. }
  774. void rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw,
  775. u8 *cmd_buf, u8 cmd_len)
  776. {
  777. u8 rate = cmd_buf[0] & 0x3F;
  778. bool collision_state = cmd_buf[3] & BIT(0);
  779. rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state);
  780. }