rtw_rm_fsm.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2017 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. *****************************************************************************/
  15. #include <drv_types.h>
  16. #include <hal_data.h>
  17. #include "rtw_rm_fsm.h"
  18. #ifdef CONFIG_RTW_80211K
  19. struct fsm_state {
  20. u8 *name;
  21. int(*fsm_func)(struct rm_obj *prm, enum RM_EV_ID evid);
  22. };
  23. static void rm_state_initial(struct rm_obj *prm);
  24. static void rm_state_goto(struct rm_obj *prm, enum RM_STATE rm_state);
  25. static void rm_state_run(struct rm_obj *prm, enum RM_EV_ID evid);
  26. static struct rm_event *rm_dequeue_ev(_queue *queue);
  27. static struct rm_obj *rm_dequeue_rm(_queue *queue);
  28. void rm_timer_callback(void *data)
  29. {
  30. int i;
  31. _adapter *padapter = (_adapter *)data;
  32. struct rm_priv *prmpriv = &padapter->rmpriv;
  33. struct rm_clock *pclock;
  34. /* deal with clock */
  35. for (i=0;i<RM_TIMER_NUM;i++) {
  36. pclock = &prmpriv->clock[i];
  37. if (pclock->prm == NULL
  38. ||(ATOMIC_READ(&(pclock->counter)) == 0))
  39. continue;
  40. ATOMIC_DEC(&(pclock->counter));
  41. if (ATOMIC_READ(&(pclock->counter)) == 0)
  42. rm_post_event(pclock->prm->psta->padapter,
  43. pclock->prm->rmid, prmpriv->clock[i].evid);
  44. }
  45. _set_timer(&prmpriv->rm_timer, CLOCK_UNIT);
  46. }
  47. int rtw_init_rm(_adapter *padapter)
  48. {
  49. struct rm_priv *prmpriv = &padapter->rmpriv;
  50. RTW_INFO("RM: %s\n",__func__);
  51. _rtw_init_queue(&(prmpriv->rm_queue));
  52. _rtw_init_queue(&(prmpriv->ev_queue));
  53. /* bit 0-7 */
  54. prmpriv->rm_en_cap_def[0] = 0
  55. /*| BIT(RM_LINK_MEAS_CAP_EN)*/
  56. | BIT(RM_NB_REP_CAP_EN)
  57. /*| BIT(RM_PARAL_MEAS_CAP_EN)*/
  58. | BIT(RM_REPEAT_MEAS_CAP_EN)
  59. | BIT(RM_BCN_PASSIVE_MEAS_CAP_EN)
  60. | BIT(RM_BCN_ACTIVE_MEAS_CAP_EN)
  61. | BIT(RM_BCN_TABLE_MEAS_CAP_EN)
  62. /*| BIT(RM_BCN_MEAS_REP_COND_CAP_EN)*/;
  63. /* bit 8-15 */
  64. prmpriv->rm_en_cap_def[1] = 0
  65. /*| BIT(RM_FRAME_MEAS_CAP_EN - 8)*/
  66. #ifdef CONFIG_RTW_ACS
  67. | BIT(RM_CH_LOAD_CAP_EN - 8)
  68. | BIT(RM_NOISE_HISTO_CAP_EN - 8)
  69. #endif
  70. /*| BIT(RM_STATIS_MEAS_CAP_EN - 8)*/
  71. /*| BIT(RM_LCI_MEAS_CAP_EN - 8)*/
  72. /*| BIT(RM_LCI_AMIMUTH_CAP_EN - 8)*/
  73. /*| BIT(RM_TRANS_STREAM_CAT_MEAS_CAP_EN - 8)*/
  74. /*| BIT(RM_TRIG_TRANS_STREAM_CAT_MEAS_CAP_EN - 8)*/;
  75. /* bit 16-23 */
  76. prmpriv->rm_en_cap_def[2] = 0
  77. /*| BIT(RM_AP_CH_REP_CAP_EN - 16)*/
  78. /*| BIT(RM_RM_MIB_CAP_EN - 16)*/
  79. /*| BIT(RM_OP_CH_MAX_MEAS_DUR0 - 16)*/
  80. /*| BIT(RM_OP_CH_MAX_MEAS_DUR1 - 16)*/
  81. /*| BIT(RM_OP_CH_MAX_MEAS_DUR2 - 16)*/
  82. /*| BIT(RM_NONOP_CH_MAX_MEAS_DUR0 - 16)*/
  83. /*| BIT(RM_NONOP_CH_MAX_MEAS_DUR1 - 16)*/
  84. /*| BIT(RM_NONOP_CH_MAX_MEAS_DUR2 - 16)*/;
  85. /* bit 24-31 */
  86. prmpriv->rm_en_cap_def[3] = 0
  87. /*| BIT(RM_MEAS_PILOT_CAP0 - 24)*/
  88. /*| BIT(RM_MEAS_PILOT_CAP1 - 24)*/
  89. /*| BIT(RM_MEAS_PILOT_CAP2 - 24)*/
  90. /*| BIT(RM_MEAS_PILOT_TRANS_INFO_CAP_EN - 24)*/
  91. /*| BIT(RM_NB_REP_TSF_OFFSET_CAP_EN - 24)*/
  92. | BIT(RM_RCPI_MEAS_CAP_EN - 24)
  93. | BIT(RM_RSNI_MEAS_CAP_EN - 24)
  94. /*| BIT(RM_BSS_AVG_ACCESS_DELAY_CAP_EN - 24)*/;
  95. /* bit 32-39 */
  96. prmpriv->rm_en_cap_def[4] = 0
  97. /*| BIT(RM_BSS_AVG_ACCESS_DELAY_CAP_EN - 32)*/
  98. /*| BIT(RM_AVALB_ADMIS_CAPACITY_CAP_EN - 32)*/
  99. /*| BIT(RM_ANT_CAP_EN - 32)*/;
  100. prmpriv->enable = _TRUE;
  101. /* clock timer */
  102. rtw_init_timer(&prmpriv->rm_timer,
  103. padapter, rm_timer_callback, padapter);
  104. _set_timer(&prmpriv->rm_timer, CLOCK_UNIT);
  105. return _SUCCESS;
  106. }
  107. int rtw_deinit_rm(_adapter *padapter)
  108. {
  109. struct rm_priv *prmpriv = &padapter->rmpriv;
  110. struct rm_obj *prm;
  111. struct rm_event *pev;
  112. RTW_INFO("RM: %s\n",__func__);
  113. prmpriv->enable = _FALSE;
  114. _cancel_timer_ex(&prmpriv->rm_timer);
  115. /* free all events and measurements */
  116. while((pev = rm_dequeue_ev(&prmpriv->ev_queue)) != NULL)
  117. rtw_mfree((void *)pev, sizeof(struct rm_event));
  118. while((prm = rm_dequeue_rm(&prmpriv->rm_queue)) != NULL)
  119. rm_state_run(prm, RM_EV_cancel);
  120. _rtw_deinit_queue(&(prmpriv->rm_queue));
  121. _rtw_deinit_queue(&(prmpriv->ev_queue));
  122. return _SUCCESS;
  123. }
  124. int rtw_free_rm_priv(_adapter *padapter)
  125. {
  126. return rtw_deinit_rm(padapter);
  127. }
  128. static int rm_enqueue_ev(_queue *queue, struct rm_event *obj, bool to_head)
  129. {
  130. _irqL irqL;
  131. if (obj == NULL)
  132. return _FAIL;
  133. _enter_critical(&queue->lock, &irqL);
  134. if (to_head)
  135. rtw_list_insert_head(&obj->list, &queue->queue);
  136. else
  137. rtw_list_insert_tail(&obj->list, &queue->queue);
  138. _exit_critical(&queue->lock, &irqL);
  139. return _SUCCESS;
  140. }
  141. static void rm_set_clock(struct rm_obj *prm, u32 ms, enum RM_EV_ID evid)
  142. {
  143. ATOMIC_SET(&(prm->pclock->counter), (ms/CLOCK_UNIT));
  144. prm->pclock->evid = evid;
  145. }
  146. static struct rm_clock *rm_alloc_clock(_adapter *padapter, struct rm_obj *prm)
  147. {
  148. int i;
  149. struct rm_priv *prmpriv = &padapter->rmpriv;
  150. struct rm_clock *pclock = NULL;
  151. for (i=0;i<RM_TIMER_NUM;i++) {
  152. pclock = &prmpriv->clock[i];
  153. if (pclock->prm == NULL) {
  154. pclock->prm = prm;
  155. ATOMIC_SET(&(pclock->counter), 0);
  156. pclock->evid = RM_EV_max;
  157. break;
  158. }
  159. }
  160. return pclock;
  161. }
  162. static void rm_cancel_clock(struct rm_obj *prm)
  163. {
  164. ATOMIC_SET(&(prm->pclock->counter), 0);
  165. prm->pclock->evid = RM_EV_max;
  166. }
  167. static void rm_free_clock(struct rm_clock *pclock)
  168. {
  169. pclock->prm = NULL;
  170. ATOMIC_SET(&(pclock->counter), 0);
  171. pclock->evid = RM_EV_max;
  172. }
  173. static int is_list_linked(const struct list_head *head)
  174. {
  175. return head->prev != NULL;
  176. }
  177. void rm_free_rmobj(struct rm_obj *prm)
  178. {
  179. if (is_list_linked(&prm->list))
  180. rtw_list_delete(&prm->list);
  181. if (prm->q.pssid)
  182. rtw_mfree(prm->q.pssid, strlen(prm->q.pssid)+1);
  183. if (prm->q.opt.bcn.req_start)
  184. rtw_mfree(prm->q.opt.bcn.req_start,
  185. prm->q.opt.bcn.req_len);
  186. if (prm->pclock)
  187. rm_free_clock(prm->pclock);
  188. rtw_mfree((void *)prm, sizeof(struct rm_obj));
  189. }
  190. struct rm_obj *rm_alloc_rmobj(_adapter *padapter)
  191. {
  192. struct rm_obj *prm;
  193. prm = (struct rm_obj *)rtw_malloc(sizeof(struct rm_obj));
  194. if (prm == NULL)
  195. return NULL;
  196. _rtw_memset(prm, 0, sizeof(struct rm_obj));
  197. /* alloc timer */
  198. if ((prm->pclock = rm_alloc_clock(padapter, prm)) == NULL) {
  199. rm_free_rmobj(prm);
  200. return NULL;
  201. }
  202. return prm;
  203. }
  204. int rm_enqueue_rmobj(_adapter *padapter, struct rm_obj *prm, bool to_head)
  205. {
  206. _irqL irqL;
  207. struct rm_priv *prmpriv = &padapter->rmpriv;
  208. _queue *queue = &prmpriv->rm_queue;
  209. if (prm == NULL)
  210. return _FAIL;
  211. _enter_critical(&queue->lock, &irqL);
  212. if (to_head)
  213. rtw_list_insert_head(&prm->list, &queue->queue);
  214. else
  215. rtw_list_insert_tail(&prm->list, &queue->queue);
  216. _exit_critical(&queue->lock, &irqL);
  217. rm_state_initial(prm);
  218. return _SUCCESS;
  219. }
  220. static struct rm_obj *rm_dequeue_rm(_queue *queue)
  221. {
  222. _irqL irqL;
  223. struct rm_obj *prm;
  224. _enter_critical(&queue->lock, &irqL);
  225. if (rtw_is_list_empty(&(queue->queue)))
  226. prm = NULL;
  227. else {
  228. prm = LIST_CONTAINOR(get_next(&(queue->queue)),
  229. struct rm_obj, list);
  230. /* rtw_list_delete(&prm->list); */
  231. }
  232. _exit_critical(&queue->lock, &irqL);
  233. return prm;
  234. }
  235. static struct rm_event *rm_dequeue_ev(_queue *queue)
  236. {
  237. _irqL irqL;
  238. struct rm_event *ev;
  239. _enter_critical(&queue->lock, &irqL);
  240. if (rtw_is_list_empty(&(queue->queue)))
  241. ev = NULL;
  242. else {
  243. ev = LIST_CONTAINOR(get_next(&(queue->queue)),
  244. struct rm_event, list);
  245. rtw_list_delete(&ev->list);
  246. }
  247. _exit_critical(&queue->lock, &irqL);
  248. return ev;
  249. }
  250. static struct rm_obj *_rm_get_rmobj(_queue *queue, u32 rmid)
  251. {
  252. _irqL irqL;
  253. _list *phead, *plist;
  254. struct rm_obj *prm = NULL;
  255. if (rmid == 0)
  256. return NULL;
  257. _enter_critical(&queue->lock, &irqL);
  258. phead = get_list_head(queue);
  259. plist = get_next(phead);
  260. while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
  261. prm = LIST_CONTAINOR(plist, struct rm_obj, list);
  262. if (rmid == (prm->rmid)) {
  263. _exit_critical(&queue->lock, &irqL);
  264. return prm;
  265. }
  266. plist = get_next(plist);
  267. }
  268. _exit_critical(&queue->lock, &irqL);
  269. return NULL;
  270. }
  271. struct sta_info *rm_get_psta(_adapter *padapter, u32 rmid)
  272. {
  273. struct rm_priv *prmpriv = &padapter->rmpriv;
  274. struct rm_obj *prm;
  275. prm = _rm_get_rmobj(&prmpriv->rm_queue, rmid);
  276. if (prm)
  277. return prm->psta;
  278. return NULL;
  279. }
  280. struct rm_obj *rm_get_rmobj(_adapter *padapter, u32 rmid)
  281. {
  282. struct rm_priv *prmpriv = &padapter->rmpriv;
  283. return _rm_get_rmobj(&prmpriv->rm_queue, rmid);
  284. }
  285. u8 rtw_rm_post_envent_cmd(_adapter *padapter, u32 rmid, u8 evid)
  286. {
  287. struct cmd_obj *pcmd;
  288. struct rm_event *pev;
  289. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  290. u8 res = _SUCCESS;
  291. pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
  292. if (pcmd == NULL) {
  293. res = _FAIL;
  294. goto exit;
  295. }
  296. pev = (struct rm_event*)rtw_zmalloc(sizeof(struct rm_event));
  297. if (pev == NULL) {
  298. rtw_mfree((u8 *) pcmd, sizeof(struct cmd_obj));
  299. res = _FAIL;
  300. goto exit;
  301. }
  302. pev->rmid = rmid;
  303. pev->evid = evid;
  304. init_h2fwcmd_w_parm_no_rsp(pcmd, pev, GEN_CMD_CODE(_RM_POST_EVENT));
  305. res = rtw_enqueue_cmd(pcmdpriv, pcmd);
  306. exit:
  307. return res;
  308. }
  309. int rm_post_event(_adapter *padapter, u32 rmid, enum RM_EV_ID evid)
  310. {
  311. if (padapter->rmpriv.enable == _FALSE)
  312. return _FALSE;
  313. RTW_INFO("RM: post asyn %s to rmid=%x\n", rm_event_name(evid), rmid);
  314. rtw_rm_post_envent_cmd(padapter, rmid, evid);
  315. return _SUCCESS;
  316. }
  317. int _rm_post_event(_adapter *padapter, u32 rmid, enum RM_EV_ID evid)
  318. {
  319. struct rm_priv *prmpriv = &padapter->rmpriv;
  320. struct rm_event *pev;
  321. if (evid >= RM_EV_max || rmid == 0)
  322. return _FALSE;
  323. pev = (struct rm_event *)rtw_malloc(sizeof(struct rm_event));
  324. if (pev == NULL)
  325. return _FALSE;
  326. pev->rmid = rmid;
  327. pev->evid = evid;
  328. RTW_INFO("RM: post sync %s to rmid=%x\n", rm_event_name(evid), rmid);
  329. rm_enqueue_ev(&prmpriv->ev_queue, pev, FALSE);
  330. return _SUCCESS;
  331. }
  332. static void rm_bcast_aid_handler(_adapter *padapter, struct rm_event *pev)
  333. {
  334. _irqL irqL;
  335. _list *phead, *plist;
  336. _queue *queue = &padapter->rmpriv.rm_queue;
  337. struct rm_obj *prm;
  338. _enter_critical(&queue->lock, &irqL);
  339. phead = get_list_head(queue);
  340. plist = get_next(phead);
  341. while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
  342. prm = LIST_CONTAINOR(plist, struct rm_obj, list);
  343. plist = get_next(plist);
  344. if (RM_GET_AID(pev->rmid) == RM_GET_AID(prm->rmid)) {
  345. _exit_critical(&queue->lock, &irqL);
  346. rm_state_run(prm, pev->evid);
  347. _enter_critical(&queue->lock, &irqL);
  348. }
  349. }
  350. _exit_critical(&queue->lock, &irqL);
  351. return;
  352. }
  353. /* main handler of RM (Resource Management) */
  354. void rm_handler(_adapter *padapter, struct rm_event *pe)
  355. {
  356. int i;
  357. struct rm_priv *prmpriv = &padapter->rmpriv;
  358. struct rm_obj *prm;
  359. struct rm_event *pev;
  360. /* dequeue event */
  361. while((pev = rm_dequeue_ev(&prmpriv->ev_queue)) != NULL)
  362. {
  363. if (RM_IS_ID_FOR_ALL(pev->rmid)) {
  364. /* apply to all aid mateched measurement */
  365. rm_bcast_aid_handler(padapter, pev);
  366. rtw_mfree((void *)pev, sizeof(struct rm_event));
  367. continue;
  368. }
  369. /* retrieve rmobj */
  370. prm = _rm_get_rmobj(&prmpriv->rm_queue, pev->rmid);
  371. if (prm == NULL) {
  372. RTW_ERR("RM: rmid=%x event=%s doesn't find rm obj\n",
  373. pev->rmid, rm_event_name(pev->evid));
  374. rtw_mfree((void *)pev, sizeof(struct rm_event));
  375. return;
  376. }
  377. /* run state machine */
  378. rm_state_run(prm, pev->evid);
  379. rtw_mfree((void *)pev, sizeof(struct rm_event));
  380. }
  381. }
  382. static int rm_issue_meas_req(struct rm_obj *prm)
  383. {
  384. switch (prm->q.action_code) {
  385. case RM_ACT_RADIO_MEAS_REQ:
  386. switch (prm->q.m_type) {
  387. case bcn_req:
  388. case ch_load_req:
  389. case noise_histo_req:
  390. issue_radio_meas_req(prm);
  391. break;
  392. default:
  393. break;
  394. } /* meas_type */
  395. break;
  396. case RM_ACT_NB_REP_REQ:
  397. /* issue neighbor request */
  398. issue_nb_req(prm);
  399. break;
  400. case RM_ACT_LINK_MEAS_REQ:
  401. default:
  402. return _FALSE;
  403. } /* action_code */
  404. return _SUCCESS;
  405. }
  406. /*
  407. * RM state machine
  408. */
  409. static int rm_state_idle(struct rm_obj *prm, enum RM_EV_ID evid)
  410. {
  411. _adapter *padapter = prm->psta->padapter;
  412. u8 val8;
  413. u32 val32;
  414. prm->p.category = RTW_WLAN_CATEGORY_RADIO_MEAS;
  415. switch (evid) {
  416. case RM_EV_state_in:
  417. switch (prm->q.action_code) {
  418. case RM_ACT_RADIO_MEAS_REQ:
  419. /* copy attrib from meas_req to meas_rep */
  420. prm->p.action_code = RM_ACT_RADIO_MEAS_REP;
  421. prm->p.diag_token = prm->q.diag_token;
  422. prm->p.e_id = _MEAS_RSP_IE_;
  423. prm->p.m_token = prm->q.m_token;
  424. prm->p.m_type = prm->q.m_type;
  425. prm->p.rpt = prm->q.rpt;
  426. prm->p.ch_num = prm->q.ch_num;
  427. prm->p.op_class = prm->q.op_class;
  428. if (prm->q.m_type == ch_load_req
  429. || prm->q.m_type == noise_histo_req) {
  430. /*
  431. * phydm measure current ch periodically
  432. * scan current ch is not necessary
  433. */
  434. val8 = padapter->mlmeextpriv.cur_channel;
  435. if (prm->q.ch_num == val8)
  436. prm->poll_mode = 1;
  437. }
  438. RTW_INFO("RM: rmid=%x %s switch in repeat=%u\n",
  439. prm->rmid, rm_type_req_name(prm->q.m_type),
  440. prm->q.rpt);
  441. break;
  442. case RM_ACT_NB_REP_REQ:
  443. prm->p.action_code = RM_ACT_NB_REP_RESP;
  444. RTW_INFO("RM: rmid=%x Neighbor request switch in\n",
  445. prm->rmid);
  446. break;
  447. case RM_ACT_LINK_MEAS_REQ:
  448. prm->p.action_code = RM_ACT_LINK_MEAS_REP;
  449. rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
  450. RTW_INFO("RM: rmid=%x Link meas switch in\n",
  451. prm->rmid);
  452. break;
  453. default:
  454. prm->p.action_code = prm->q.action_code;
  455. rm_set_rep_mode(prm, MEAS_REP_MOD_INCAP);
  456. RTW_INFO("RM: rmid=%x recv unknown action %d\n",
  457. prm->rmid,prm->p.action_code);
  458. break;
  459. } /* switch() */
  460. if (prm->rmid & RM_MASTER) {
  461. if (rm_issue_meas_req(prm) == _SUCCESS)
  462. rm_state_goto(prm, RM_ST_WAIT_MEAS);
  463. else
  464. rm_state_goto(prm, RM_ST_END);
  465. return _SUCCESS;
  466. } else {
  467. rm_state_goto(prm, RM_ST_DO_MEAS);
  468. return _SUCCESS;
  469. }
  470. if (prm->p.m_mode) {
  471. issue_null_reply(prm);
  472. rm_state_goto(prm, RM_ST_END);
  473. return _SUCCESS;
  474. }
  475. if (prm->q.rand_intvl) {
  476. /* get low tsf to generate random interval */
  477. val32 = rtw_read32(padapter, REG_TSFTR);
  478. val32 = val32 % prm->q.rand_intvl;
  479. RTW_INFO("RM: rmid=%x rand_intval=%d, rand=%d\n",
  480. prm->rmid, (int)prm->q.rand_intvl,val32);
  481. rm_set_clock(prm, prm->q.rand_intvl,
  482. RM_EV_delay_timer_expire);
  483. return _SUCCESS;
  484. }
  485. break;
  486. case RM_EV_delay_timer_expire:
  487. rm_state_goto(prm, RM_ST_DO_MEAS);
  488. break;
  489. case RM_EV_cancel:
  490. rm_state_goto(prm, RM_ST_END);
  491. break;
  492. case RM_EV_state_out:
  493. rm_cancel_clock(prm);
  494. break;
  495. default:
  496. break;
  497. }
  498. return _SUCCESS;
  499. }
  500. /* we do the measuring */
  501. static int rm_state_do_meas(struct rm_obj *prm, enum RM_EV_ID evid)
  502. {
  503. _adapter *padapter = prm->psta->padapter;
  504. u8 val8;
  505. u64 val64;
  506. switch (evid) {
  507. case RM_EV_state_in:
  508. if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
  509. switch (prm->q.m_type) {
  510. case bcn_req:
  511. if (prm->q.m_mode == bcn_req_bcn_table) {
  512. RTW_INFO("RM: rmid=%x Beacon table\n",
  513. prm->rmid);
  514. _rm_post_event(padapter, prm->rmid,
  515. RM_EV_survey_done);
  516. return _SUCCESS;
  517. }
  518. break;
  519. case ch_load_req:
  520. case noise_histo_req:
  521. if (prm->poll_mode)
  522. _rm_post_event(padapter, prm->rmid,
  523. RM_EV_survey_done);
  524. return _SUCCESS;
  525. default:
  526. rm_state_goto(prm, RM_ST_END);
  527. return _SUCCESS;
  528. }
  529. if (!ready_for_scan(prm)) {
  530. prm->wait_busy = RM_BUSY_TRAFFIC_TIMES;
  531. RTW_INFO("RM: wait busy traffic - %d\n",
  532. prm->wait_busy);
  533. rm_set_clock(prm, RM_WAIT_BUSY_TIMEOUT,
  534. RM_EV_busy_timer_expire);
  535. return _SUCCESS;
  536. }
  537. }
  538. _rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
  539. break;
  540. case RM_EV_start_meas:
  541. if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
  542. /* resotre measurement start time */
  543. prm->meas_start_time = rtw_hal_get_tsftr_by_port(padapter
  544. , rtw_hal_get_port(padapter));
  545. switch (prm->q.m_type) {
  546. case bcn_req:
  547. val8 = 1; /* Enable free run counter */
  548. rtw_hal_set_hwreg(padapter,
  549. HW_VAR_FREECNT, &val8);
  550. rm_sitesurvey(prm);
  551. break;
  552. case ch_load_req:
  553. case noise_histo_req:
  554. rm_sitesurvey(prm);
  555. break;
  556. default:
  557. rm_state_goto(prm, RM_ST_END);
  558. return _SUCCESS;
  559. break;
  560. }
  561. }
  562. /* handle measurement timeout */
  563. rm_set_clock(prm, RM_MEAS_TIMEOUT, RM_EV_meas_timer_expire);
  564. break;
  565. case RM_EV_survey_done:
  566. if (prm->q.action_code == RM_ACT_RADIO_MEAS_REQ) {
  567. switch (prm->q.m_type) {
  568. case bcn_req:
  569. rm_cancel_clock(prm);
  570. rm_state_goto(prm, RM_ST_SEND_REPORT);
  571. return _SUCCESS;
  572. case ch_load_req:
  573. case noise_histo_req:
  574. retrieve_radio_meas_result(prm);
  575. if (rm_radio_meas_report_cond(prm) == _SUCCESS)
  576. rm_state_goto(prm, RM_ST_SEND_REPORT);
  577. else
  578. rm_set_clock(prm, RM_COND_INTVL,
  579. RM_EV_retry_timer_expire);
  580. break;
  581. default:
  582. rm_state_goto(prm, RM_ST_END);
  583. return _SUCCESS;
  584. }
  585. }
  586. break;
  587. case RM_EV_meas_timer_expire:
  588. RTW_INFO("RM: rmid=%x measurement timeount\n",prm->rmid);
  589. rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
  590. issue_null_reply(prm);
  591. rm_state_goto(prm, RM_ST_END);
  592. break;
  593. case RM_EV_busy_timer_expire:
  594. if (!ready_for_scan(prm) && prm->wait_busy--) {
  595. RTW_INFO("RM: wait busy - %d\n",prm->wait_busy);
  596. rm_set_clock(prm, RM_WAIT_BUSY_TIMEOUT,
  597. RM_EV_busy_timer_expire);
  598. break;
  599. }
  600. else if (prm->wait_busy <= 0) {
  601. RTW_INFO("RM: wait busy timeout\n");
  602. rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
  603. issue_null_reply(prm);
  604. rm_state_goto(prm, RM_ST_END);
  605. return _SUCCESS;
  606. }
  607. _rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
  608. break;
  609. case RM_EV_request_timer_expire:
  610. rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
  611. issue_null_reply(prm);
  612. rm_state_goto(prm, RM_ST_END);
  613. break;
  614. case RM_EV_retry_timer_expire:
  615. /* expired due to meas condition mismatch, meas again */
  616. _rm_post_event(padapter, prm->rmid, RM_EV_start_meas);
  617. break;
  618. case RM_EV_cancel:
  619. rm_set_rep_mode(prm, MEAS_REP_MOD_REFUSE);
  620. issue_null_reply(prm);
  621. rm_state_goto(prm, RM_ST_END);
  622. break;
  623. case RM_EV_state_out:
  624. rm_cancel_clock(prm);
  625. /* resotre measurement end time */
  626. prm->meas_end_time = rtw_hal_get_tsftr_by_port(padapter
  627. , rtw_hal_get_port(padapter));
  628. val8 = 0; /* Disable free run counter */
  629. rtw_hal_set_hwreg(padapter, HW_VAR_FREECNT, &val8);
  630. break;
  631. default:
  632. break;
  633. }
  634. return _SUCCESS;
  635. }
  636. static int rm_state_wait_meas(struct rm_obj *prm, enum RM_EV_ID evid)
  637. {
  638. u8 val8;
  639. u64 val64;
  640. switch (evid) {
  641. case RM_EV_state_in:
  642. /* we create meas_req, waiting for peer report */
  643. rm_set_clock(prm, RM_REQ_TIMEOUT,
  644. RM_EV_request_timer_expire);
  645. break;
  646. case RM_EV_recv_rep:
  647. rm_state_goto(prm, RM_ST_RECV_REPORT);
  648. break;
  649. case RM_EV_request_timer_expire:
  650. case RM_EV_cancel:
  651. rm_state_goto(prm, RM_ST_END);
  652. break;
  653. case RM_EV_state_out:
  654. rm_cancel_clock(prm);
  655. break;
  656. default:
  657. break;
  658. }
  659. return _SUCCESS;
  660. }
  661. static int rm_state_send_report(struct rm_obj *prm, enum RM_EV_ID evid)
  662. {
  663. u8 val8;
  664. switch (evid) {
  665. case RM_EV_state_in:
  666. /* we have to issue report */
  667. switch (prm->q.m_type) {
  668. case bcn_req:
  669. issue_beacon_rep(prm);
  670. break;
  671. case ch_load_req:
  672. case noise_histo_req:
  673. issue_radio_meas_rep(prm);
  674. break;
  675. default:
  676. rm_state_goto(prm, RM_ST_END);
  677. return _SUCCESS;
  678. }
  679. /* check repeat */
  680. if (prm->p.rpt) {
  681. RTW_INFO("RM: rmid=%x repeat=%u/%u\n",
  682. prm->rmid, prm->p.rpt,
  683. prm->q.rpt);
  684. prm->p.rpt--;
  685. /*
  686. * we recv meas_req,
  687. * delay for a wihile and than meas again
  688. */
  689. if (prm->poll_mode)
  690. rm_set_clock(prm, RM_REPT_POLL_INTVL,
  691. RM_EV_repeat_delay_expire);
  692. else
  693. rm_set_clock(prm, RM_REPT_SCAN_INTVL,
  694. RM_EV_repeat_delay_expire);
  695. return _SUCCESS;
  696. }
  697. /* we are done */
  698. rm_state_goto(prm, RM_ST_END);
  699. break;
  700. case RM_EV_repeat_delay_expire:
  701. rm_state_goto(prm, RM_ST_DO_MEAS);
  702. break;
  703. case RM_EV_cancel:
  704. rm_state_goto(prm, RM_ST_END);
  705. break;
  706. case RM_EV_state_out:
  707. rm_cancel_clock(prm);
  708. break;
  709. default:
  710. break;
  711. }
  712. return _SUCCESS;
  713. }
  714. static int rm_state_recv_report(struct rm_obj *prm, enum RM_EV_ID evid)
  715. {
  716. u8 val8;
  717. switch (evid) {
  718. case RM_EV_state_in:
  719. /* we issue meas_req, got peer's meas report */
  720. switch (prm->p.action_code) {
  721. case RM_ACT_RADIO_MEAS_REP:
  722. /* check refuse, incapable and repeat */
  723. val8 = prm->p.m_mode;
  724. if (val8) {
  725. RTW_INFO("RM: rmid=%x peer reject (%s repeat=%d)\n",
  726. prm->rmid,
  727. val8|MEAS_REP_MOD_INCAP?"INCAP":
  728. val8|MEAS_REP_MOD_REFUSE?"REFUSE":
  729. val8|MEAS_REP_MOD_LATE?"LATE":"",
  730. prm->p.rpt);
  731. rm_state_goto(prm, RM_ST_END);
  732. return _SUCCESS;
  733. }
  734. break;
  735. case RM_ACT_NB_REP_RESP:
  736. /* report to upper layer if needing */
  737. rm_state_goto(prm, RM_ST_END);
  738. return _SUCCESS;
  739. default:
  740. rm_state_goto(prm, RM_ST_END);
  741. return _SUCCESS;
  742. }
  743. /* check repeat */
  744. if (prm->p.rpt) {
  745. RTW_INFO("RM: rmid=%x repeat=%u/%u\n",
  746. prm->rmid, prm->p.rpt,
  747. prm->q.rpt);
  748. prm->p.rpt--;
  749. /* waitting more report */
  750. rm_state_goto(prm, RM_ST_WAIT_MEAS);
  751. break;
  752. }
  753. /* we are done */
  754. rm_state_goto(prm, RM_ST_END);
  755. break;
  756. case RM_EV_cancel:
  757. rm_state_goto(prm, RM_ST_END);
  758. break;
  759. case RM_EV_state_out:
  760. rm_cancel_clock(prm);
  761. break;
  762. default:
  763. break;
  764. }
  765. return _SUCCESS;
  766. }
  767. static int rm_state_end(struct rm_obj *prm, enum RM_EV_ID evid)
  768. {
  769. switch (evid) {
  770. case RM_EV_state_in:
  771. _rm_post_event(prm->psta->padapter, prm->rmid, RM_EV_state_out);
  772. break;
  773. case RM_EV_cancel:
  774. case RM_EV_state_out:
  775. default:
  776. rm_free_rmobj(prm);
  777. break;
  778. }
  779. return _SUCCESS;
  780. }
  781. struct fsm_state rm_fsm[] = {
  782. {"RM_ST_IDLE", rm_state_idle},
  783. {"RM_ST_DO_MEAS", rm_state_do_meas},
  784. {"RM_ST_WAIT_MEAS", rm_state_wait_meas},
  785. {"RM_ST_SEND_REPORT", rm_state_send_report},
  786. {"RM_ST_RECV_REPORT", rm_state_recv_report},
  787. {"RM_ST_END", rm_state_end}
  788. };
  789. char *rm_state_name(enum RM_STATE state)
  790. {
  791. return rm_fsm[state].name;
  792. }
  793. char *rm_event_name(enum RM_EV_ID evid)
  794. {
  795. switch(evid) {
  796. case RM_EV_state_in:
  797. return "RM_EV_state_in";
  798. case RM_EV_busy_timer_expire:
  799. return "RM_EV_busy_timer_expire";
  800. case RM_EV_delay_timer_expire:
  801. return "RM_EV_delay_timer_expire";
  802. case RM_EV_meas_timer_expire:
  803. return "RM_EV_meas_timer_expire";
  804. case RM_EV_repeat_delay_expire:
  805. return "RM_EV_repeat_delay_expire";
  806. case RM_EV_retry_timer_expire:
  807. return "RM_EV_retry_timer_expire";
  808. case RM_EV_request_timer_expire:
  809. return "RM_EV_request_timer_expire";
  810. case RM_EV_wait_report:
  811. return "RM_EV_wait_report";
  812. case RM_EV_start_meas:
  813. return "RM_EV_start_meas";
  814. case RM_EV_survey_done:
  815. return "RM_EV_survey_done";
  816. case RM_EV_recv_rep:
  817. return "RM_EV_recv_report";
  818. case RM_EV_cancel:
  819. return "RM_EV_cancel";
  820. case RM_EV_state_out:
  821. return "RM_EV_state_out";
  822. case RM_EV_max:
  823. return "RM_EV_max";
  824. default:
  825. return "RM_EV_unknown";
  826. }
  827. return "UNKNOWN";
  828. }
  829. static void rm_state_initial(struct rm_obj *prm)
  830. {
  831. prm->state = RM_ST_IDLE;
  832. RTW_INFO("\n");
  833. RTW_INFO("RM: rmid=%x %-18s -> %s\n",prm->rmid,
  834. "new measurement", rm_fsm[prm->state].name);
  835. rm_post_event(prm->psta->padapter, prm->rmid, RM_EV_state_in);
  836. }
  837. static void rm_state_run(struct rm_obj *prm, enum RM_EV_ID evid)
  838. {
  839. RTW_INFO("RM: rmid=%x %-18s %s\n",prm->rmid,
  840. rm_fsm[prm->state].name,rm_event_name(evid));
  841. rm_fsm[prm->state].fsm_func(prm, evid);
  842. }
  843. static void rm_state_goto(struct rm_obj *prm, enum RM_STATE rm_state)
  844. {
  845. if (prm->state == rm_state)
  846. return;
  847. rm_state_run(prm, RM_EV_state_out);
  848. RTW_INFO("\n");
  849. RTW_INFO("RM: rmid=%x %-18s -> %s\n",prm->rmid,
  850. rm_fsm[prm->state].name, rm_fsm[rm_state].name);
  851. prm->state = rm_state;
  852. rm_state_run(prm, RM_EV_state_in);
  853. }
  854. #endif /* CONFIG_RTW_80211K */