xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/phl_ser_fsm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2019 - 2020 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 "phl_headers.h"
16 
17 #ifdef CONFIG_FSM
18 /*
19  * SER stands for System Error Recovery
20  */
21 
22 #define SER_FW_TIMEOUT 1000 /* ms */
23 #define SER_POLLING_INTERVAL 10 /* ms */
24 #define SER_USB_POLLING_INTERVAL_IDL 1000 /* ms */
25 #define SER_USB_POLLING_INTERVAL_ACT 10 /* ms */
26 
27 #define SER_POLL_IO_TIMES 200
28 #define SER_USB_POLL_IO_TIMES 300
29 #define SER_POLL_BULK_TIMES 100
30 
31 #define SER_L0 0x00000001
32 #define SER_L1 0x00000002
33 #define SER_L2 0x00000004
34 
35 struct ser_obj {
36 	struct fsm_main *fsm;
37 	struct phl_info_t *phl_info;
38 	struct fsm_obj *fsm_obj;
39 
40 	int poll_io_times;
41 	int poll_bulk_times;
42 	bool trigger_l2_reset;
43 	bool trigger_l1_reset;
44 	bool dynamicThredRunning;
45 	_os_lock state_lock;
46 };
47 
48 enum SER_STATE_ST {
49 	SER_ST_IDLE,
50 	SER_ST_L1_PAUSE_TRX,
51 	SER_ST_L1_DO_HCI,
52 	SER_ST_L1_RESUME_TRX,
53 	SER_ST_L2
54 };
55 
56 enum SER_EV_ID {
57 	SER_EV_L1_START,
58 	//SER_EV_L2_START,
59 	//SER_EV_M1_PAUSE_TRX,
60 	SER_EV_M3_DO_RECOVERY,
61 	SER_EV_M5_READY,
62 	SER_EV_M9_L2_RESET,
63 	SER_EV_FW_TIMER_EXPIRE,
64 	SER_EV_POLL_IO_EXPIRE,
65 	SER_EV_POLL_BULK_EXPIRE,
66 	SER_EV_POLL_USB_INT_EXPIRE,
67 	SER_EV_CHK_SER_EVENT,
68 	SER_EV_MAX
69 };
70 
71 static int ser_idle_st_hdl(void *obj, u16 event, void *param);
72 static int ser_usb_idle_st_hdl(void *obj, u16 event, void *param);
73 static int ser_pci_l1_pause_trx_st_hdl(void *obj, u16 event, void *param);
74 static int ser_usb_l1_pause_trx_st_hdl(void *obj, u16 event, void *param);
75 static int ser_sdio_l1_pause_trx_st_hdl(void *obj, u16 event, void *param);
76 static int ser_pci_l1_do_hci_st_hdl(void *obj, u16 event, void *param);
77 static int ser_usb_l1_do_hci_st_hdl(void *obj, u16 event, void *param);
78 static int ser_sdio_l1_do_hci_st_hdl(void *obj, u16 event, void *param);
79 static int ser_l1_resume_trx_st_hdl(void *obj, u16 event, void *param);
80 static int ser_l2_st_hdl(void *obj, u16 event, void *param);
81 
82 /* PCIE STATE table */
83 static struct fsm_state_ent ser_pci_state_tbl[] = {
84 	ST_ENT(SER_ST_IDLE, ser_idle_st_hdl),
85 	ST_ENT(SER_ST_L1_PAUSE_TRX, ser_pci_l1_pause_trx_st_hdl),
86 	ST_ENT(SER_ST_L1_DO_HCI, ser_pci_l1_do_hci_st_hdl),
87 	ST_ENT(SER_ST_L1_RESUME_TRX, ser_l1_resume_trx_st_hdl),
88 	ST_ENT(SER_ST_L2, ser_l2_st_hdl)
89 };
90 
91 /* USB STATE table */
92 static struct fsm_state_ent ser_usb_state_tbl[] = {
93 	ST_ENT(SER_ST_IDLE, ser_usb_idle_st_hdl),
94 	ST_ENT(SER_ST_L1_PAUSE_TRX, ser_usb_l1_pause_trx_st_hdl),
95 	ST_ENT(SER_ST_L1_DO_HCI, ser_usb_l1_do_hci_st_hdl),
96 	ST_ENT(SER_ST_L1_RESUME_TRX, ser_l1_resume_trx_st_hdl),
97 	ST_ENT(SER_ST_L2, ser_l2_st_hdl)
98 };
99 
100 /* SDIO STATE table */
101 static struct fsm_state_ent ser_sdio_state_tbl[] = {
102 	ST_ENT(SER_ST_IDLE, ser_idle_st_hdl),
103 	ST_ENT(SER_ST_L1_PAUSE_TRX, ser_sdio_l1_pause_trx_st_hdl),
104 	ST_ENT(SER_ST_L1_DO_HCI, ser_sdio_l1_do_hci_st_hdl),
105 	ST_ENT(SER_ST_L1_RESUME_TRX, ser_l1_resume_trx_st_hdl),
106 	ST_ENT(SER_ST_L2, ser_l2_st_hdl)
107 };
108 
109 
110 /* EVENT table */
111 static struct fsm_event_ent ser_event_tbl[] = {
112 	EV_ENT(SER_EV_L1_START),
113 	//EV_ENT(SER_EV_L2_START),
114 	//EV_ENT(SER_EV_M1_PAUSE_TRX),
115 	EV_ENT(SER_EV_M3_DO_RECOVERY),
116 	EV_ENT(SER_EV_M5_READY),
117 	EV_ENT(SER_EV_M9_L2_RESET),
118 	EV_ENT(SER_EV_FW_TIMER_EXPIRE),
119 	EV_ENT(SER_EV_POLL_IO_EXPIRE),
120 	EV_ENT(SER_EV_POLL_BULK_EXPIRE),
121 	EV_DBG(SER_EV_POLL_USB_INT_EXPIRE),
122 	EV_ENT(SER_EV_CHK_SER_EVENT),
123 	EV_ENT(SER_EV_MAX) /* EV_MAX for fsm safety checking */
124 };
125 
_ser_event_notify(void * phl,u8 * p_ntfy)126 static enum rtw_phl_status _ser_event_notify(void *phl, u8* p_ntfy)
127 {
128 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
129 	struct ser_obj *pser = phl_info->ser_obj;
130 	struct phl_msg msg = {0};
131 	enum RTW_PHL_SER_NOTIFY_EVENT notify = RTW_PHL_SER_L2_RESET;
132 	u32 err = 0;
133 
134 	notify = rtw_hal_ser_get_error_status(pser->phl_info->hal, &err);
135 
136 	if (p_ntfy != NULL)
137 		*p_ntfy = notify;
138 
139 	phl_info->phl_com->phl_stats.ser_event[notify]++;
140 
141 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "_ser_event_notify, error 0x%x, notify 0x%x\n", err, notify);
142 
143 	if (notify == RTW_PHL_SER_L0_RESET) {
144 		PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_, "_ser_event_notify, hit L0 Reset\n");
145 		return RTW_PHL_STATUS_SUCCESS;
146 	}
147 
148 	if (notify == RTW_PHL_SER_LOG_ONLY) {
149 		PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_, "_ser_event_notify, RTW_PHL_SER_LOG_ONLY\n");
150 		return RTW_PHL_STATUS_SUCCESS;
151 	}
152 
153 	if (notify == RTW_PHL_SER_DUMP_FW_LOG) {
154 		PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_, "_ser_event_notify, RTW_PHL_SER_DUMP_FW_LOG\n");
155 
156 		SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_PHY_MGNT);
157 		SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_DUMP_PLE_BUFFER);
158 		phl_msg_hub_send(phl_info, NULL, &msg);
159 
160 		return RTW_PHL_STATUS_SUCCESS;
161 	}
162 
163 	return phl_ser_send_msg(phl, notify);
164 }
165 
166 
167 /*
168  * SER sub function
169  */
ser_pcie_pause_dma_io(struct ser_obj * pser)170 void ser_pcie_pause_dma_io(struct ser_obj *pser)
171 {
172 	FSM_DBG(pser->fsm, "%s: %s\n",
173 		phl_fsm_obj_name(pser->fsm_obj), __func__);
174 }
175 
ser_polling_io_state(struct ser_obj * pser)176 int ser_polling_io_state(struct ser_obj *pser)
177 {
178 	FSM_DBG(pser->fsm, "%s: %s\n",
179 		phl_fsm_obj_name(pser->fsm_obj), __func__);
180 	return 0; /* success */
181 }
182 
ser_return_all_tcb_and_mem(struct ser_obj * pser)183 void ser_return_all_tcb_and_mem(struct ser_obj *pser)
184 {
185 	FSM_DBG(pser->fsm, "%s: %s\n",
186 		phl_fsm_obj_name(pser->fsm_obj), __func__);
187 }
188 
ser_send_l0_handle_method_event(struct ser_obj * pser,enum RTW_PHL_SER_RCVY_STEP event)189 void ser_send_l0_handle_method_event(struct ser_obj *pser, enum RTW_PHL_SER_RCVY_STEP event)
190 {
191 	FSM_DBG(pser->fsm, "%s: %s with event = 0x%04X\n",
192 		phl_fsm_obj_name(pser->fsm_obj), __func__, event);
193 
194 	/*
195 	* Default use notify only RTW_PHL_SER_L0_CFG_NOTIFY
196 	* if need do l0 debug, set RTW_PHL_SER_L0_CFG_HANDSHAKE when init.
197 	* 1. after receive L0 notify within h2c, dump some Crs for debug.
198 	* 2. set RTW_PHL_SER_L0_RCVY_EN
199 	*/
200 	phl_ser_event_to_fw(pser->phl_info, event);
201 }
202 
ser_send_l0_do_rcvy_event(struct ser_obj * pser)203 void ser_send_l0_do_rcvy_event(struct ser_obj *pser)
204 {
205 	FSM_DBG(pser->fsm, "%s: %s\n",
206 		phl_fsm_obj_name(pser->fsm_obj), __func__);
207 
208 	/*Default use notify only RTW_PHL_SER_L0_CFG_NOTIFY*/
209 	phl_ser_event_to_fw(pser->phl_info, RTW_PHL_SER_L0_RCVY_EN);
210 }
211 
212 
ser_send_m2_event(struct ser_obj * pser)213 void ser_send_m2_event(struct ser_obj *pser)
214 {
215 	FSM_DBG(pser->fsm, "%s: %s\n",
216 		phl_fsm_obj_name(pser->fsm_obj), __func__);
217 
218 	phl_ser_event_to_fw(pser->phl_info, RTW_PHL_SER_L1_DISABLE_EN);
219 }
220 
ser_send_m4_event(struct ser_obj * pser)221 void ser_send_m4_event(struct ser_obj *pser)
222 {
223 	FSM_DBG(pser->fsm, "%s: %s\n",
224 		phl_fsm_obj_name(pser->fsm_obj), __func__);
225 	phl_ser_event_to_fw(pser->phl_info, RTW_PHL_SER_L1_RCVY_EN);
226 }
227 
ser_usb_trx_disable_cr(struct ser_obj * pser)228 void ser_usb_trx_disable_cr(struct ser_obj *pser)
229 {
230 	FSM_DBG(pser->fsm, "%s: %s\n",
231 		phl_fsm_obj_name(pser->fsm_obj), __func__);
232 }
233 
ser_usb_wait_all_bulk_complete(struct ser_obj * pser)234 int ser_usb_wait_all_bulk_complete(struct ser_obj *pser)
235 {
236 	FSM_DBG(pser->fsm, "%s: %s\n",
237 		phl_fsm_obj_name(pser->fsm_obj), __func__);
238 	return 0; /* success */
239 }
240 
ser_pci_clear_rw_pointer(struct ser_obj * pser)241 void ser_pci_clear_rw_pointer(struct ser_obj *pser)
242 {
243 	FSM_DBG(pser->fsm, "%s: %s\n",
244 		phl_fsm_obj_name(pser->fsm_obj), __func__);
245 }
246 
ser_pci_assert_dessert_dma_reset(struct ser_obj * pser)247 void ser_pci_assert_dessert_dma_reset(struct ser_obj *pser)
248 {
249 	FSM_DBG(pser->fsm, "%s: %s\n",
250 		phl_fsm_obj_name(pser->fsm_obj), __func__);
251 }
252 
ser_pci_reset_bdram(struct ser_obj * pser)253 void ser_pci_reset_bdram(struct ser_obj *pser)
254 {
255 	FSM_DBG(pser->fsm, "%s: %s\n",
256 		phl_fsm_obj_name(pser->fsm_obj), __func__);
257 }
258 
ser_pci_enable_dma_io(struct ser_obj * pser)259 void ser_pci_enable_dma_io(struct ser_obj *pser)
260 {
261 	FSM_DBG(pser->fsm, "%s: %s\n",
262 		phl_fsm_obj_name(pser->fsm_obj), __func__);
263 }
264 
ser_usb_enable_bulk_IO(struct ser_obj * pser)265 void ser_usb_enable_bulk_IO(struct ser_obj *pser)
266 {
267 	FSM_DBG(pser->fsm, "%s: %s\n",
268 		phl_fsm_obj_name(pser->fsm_obj), __func__);
269 }
ser_resume_trx_process(struct ser_obj * pser,u8 type)270 void ser_resume_trx_process(struct ser_obj *pser, u8 type)
271 {
272 	struct phl_hci_trx_ops *ops = pser->phl_info->hci_trx_ops;
273 
274 	FSM_DBG(pser->fsm, "%s: %s\n",
275 		phl_fsm_obj_name(pser->fsm_obj), __func__);
276 
277 	ops->trx_resume(pser->phl_info, type);
278 }
279 
280 #ifdef RTW_WKARD_SER_USB_POLLING_EVENT
281 extern bool rtw_phl_recognize_interrupt(void *phl);
282 extern enum rtw_phl_status rtw_phl_interrupt_handler(void *phl);
ser_usb_chk_int_event(struct ser_obj * pser)283 static void ser_usb_chk_int_event(struct ser_obj *pser)
284 {
285 	if (true == rtw_phl_recognize_interrupt(pser->phl_info))
286 		rtw_phl_interrupt_handler(pser->phl_info);
287 }
288 #endif
289 
290 /*
291  * SER state handler
292  */
rtw_phl_ser_inprogress(void * phl)293 u8 rtw_phl_ser_inprogress(void *phl)
294 {
295 	return phl_ser_inprogress(phl);
296 }
297 
rtw_phl_ser_clear_status(void * phl,u32 serstatus)298 void rtw_phl_ser_clear_status(void *phl, u32 serstatus)
299 {
300 	 phl_ser_clear_status(phl, serstatus);
301 }
302 
303 /*
304  * ser idle handler
305  */
ser_idle_st_hdl(void * obj,u16 event,void * param)306 static int ser_idle_st_hdl(void *obj, u16 event, void *param)
307 {
308 	struct ser_obj *pser = (struct ser_obj *)obj;
309 	u8 notify;
310 
311 	switch (event) {
312 	case FSM_EV_STATE_IN:
313 		break;
314 
315 	case SER_EV_CHK_SER_EVENT:
316 		if (true == rtw_hal_recognize_halt_c2h_interrupt(pser->phl_info->hal)) {
317 			_ser_event_notify(pser->phl_info, &notify);
318 			if ((notify == RTW_PHL_SER_L0_RESET) || (notify == RTW_PHL_SER_L2_RESET))
319 				rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
320 		}
321 		else {
322 			rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
323 		}
324 
325 		break;
326 
327 	case SER_EV_L1_START:
328 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L1_PAUSE_TRX);
329 		break;
330 #if 0
331 	case SER_EV_L2_START:
332 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
333 		break;
334 #endif
335 
336 	case SER_EV_M9_L2_RESET:
337 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
338 		break;
339 
340 	case FSM_EV_STATE_OUT:
341 		break;
342 
343 	default:
344 		break;
345 	}
346 	return 0;
347 }
348 
ser_usb_idle_st_hdl(void * obj,u16 event,void * param)349 static int ser_usb_idle_st_hdl(void *obj, u16 event, void *param)
350 {
351 	struct ser_obj *pser = (struct ser_obj *)obj;
352 
353 	switch (event) {
354 	case FSM_EV_SWITCH_IN:
355 #if 1
356 		/* Disable L0 Reset Notify from FW to driver */
357 		ser_send_l0_handle_method_event(pser, RTW_PHL_SER_L0_CFG_DIS_NOTIFY);
358 #endif
359 		/* fallthrough */
360 	case FSM_EV_STATE_IN:
361 
362 #if defined(RTW_WKARD_SER_USB_POLLING_EVENT) && !defined(CONFIG_PHL_CMD_SER)
363 		phl_fsm_set_alarm_ext(pser->fsm_obj,
364 			SER_USB_POLLING_INTERVAL_IDL, SER_EV_POLL_USB_INT_EXPIRE, 1, NULL);
365 #endif
366 
367 		break;
368 
369 #ifdef RTW_WKARD_SER_USB_POLLING_EVENT
370 	case SER_EV_POLL_USB_INT_EXPIRE:
371 		ser_usb_chk_int_event(pser);
372 
373 		phl_fsm_set_alarm_ext(pser->fsm_obj,
374 			SER_USB_POLLING_INTERVAL_IDL, SER_EV_POLL_USB_INT_EXPIRE, 1, NULL);
375 		break;
376 #endif
377 
378 	case SER_EV_L1_START:
379 #ifndef RTW_WKARD_SER_USB_DISABLE_L1_RCVY_FLOW
380 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L1_PAUSE_TRX);
381 #endif
382 		break;
383 
384 #if 0
385 	case SER_EV_L2_START:
386 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
387 		break;
388 #endif
389 
390 	case SER_EV_M9_L2_RESET:
391 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
392 		break;
393 
394 	case FSM_EV_STATE_OUT:
395 		phl_fsm_cancel_alarm_ext(pser->fsm_obj, 1);
396 		break;
397 
398 	default:
399 		break;
400 	}
401 	return 0;
402 }
403 
ser_pci_l1_pause_trx_st_hdl(void * obj,u16 event,void * param)404 static int ser_pci_l1_pause_trx_st_hdl(void *obj, u16 event, void *param)
405 {
406 	struct ser_obj *pser = (struct ser_obj *)obj;
407 	struct phl_hci_trx_ops *ops = pser->phl_info->hci_trx_ops;
408 	struct phl_msg msg = {0};
409 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
410 
411 	SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_SER);
412 	SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_SER_L1);
413 
414 	switch (event) {
415 	case FSM_EV_STATE_IN:
416 
417 		phl_ser_set_status(pser, SER_L1);
418 
419 		//send msg to core
420 		phl_msg_hub_send(pser->phl_info, NULL, &msg);
421 
422 		ops->req_tx_stop(pser->phl_info);
423 		rtw_phl_tx_req_notify(pser->phl_info);
424 
425 		if(rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_RCVY_STEP_1)
426 			!= RTW_HAL_STATUS_SUCCESS){
427 			ser_resume_trx_process(pser, PHL_CTRL_TX);
428 			rtw_phl_tx_req_notify(pser->phl_info);
429 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
430 			break;
431 		}
432 
433 		ops->req_rx_stop(pser->phl_info);
434 		rtw_phl_start_rx_process(pser->phl_info);
435 
436 		if (false == ops->is_tx_pause(pser->phl_info) ||
437 			false == ops->is_rx_pause(pser->phl_info)) {
438 			/* pci: polling fail; wait for a while */
439 			phl_fsm_set_alarm(pser->fsm_obj,
440 				SER_POLLING_INTERVAL, SER_EV_POLL_IO_EXPIRE);
441 
442 			/* prevent infinite polling */
443 			pser->poll_io_times = SER_POLL_IO_TIMES;
444 			break;
445 		}
446 
447 		ops->trx_reset(pser->phl_info, PHL_CTRL_TX|PHL_CTRL_RX);
448 
449 		/* pci: send M2 event */
450 		ser_send_m2_event(pser);
451 
452 		/* pci: wait M3 */
453 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
454 			SER_EV_FW_TIMER_EXPIRE);
455 		break;
456 
457 	case SER_EV_M3_DO_RECOVERY:
458 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L1_DO_HCI);
459 		break;
460 
461 	case SER_EV_FW_TIMER_EXPIRE:
462 		/*phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);*/
463 		status = rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_SER_RCVY_STEP_2);
464 
465 		ser_resume_trx_process(pser, PHL_CTRL_RX);
466 		rtw_phl_start_rx_process(pser->phl_info);
467 		ser_resume_trx_process(pser, PHL_CTRL_TX);
468 		rtw_phl_tx_req_notify(pser->phl_info);
469 
470 		if (status != RTW_HAL_STATUS_SUCCESS) {
471 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
472 		} else {
473 			phl_ser_clear_status(pser, SER_L1);
474 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
475 		}
476 
477 		break;
478 
479 	case SER_EV_M9_L2_RESET:
480 
481 		ser_resume_trx_process(pser, PHL_CTRL_RX);
482 		rtw_phl_start_rx_process(pser->phl_info);
483 		ser_resume_trx_process(pser, PHL_CTRL_TX);
484 		rtw_phl_tx_req_notify(pser->phl_info);
485 
486 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
487 
488 		break;
489 
490 	case SER_EV_POLL_IO_EXPIRE:
491 
492 		if (pser->poll_io_times-- <= 0) {
493 #ifdef RTW_WKARD_SER_L1_EXPIRE
494 
495 			ops->trx_reset(pser->phl_info, PHL_CTRL_TX|PHL_CTRL_RX);
496 
497 			/* pci: send M2 event */
498 			ser_send_m2_event(pser);
499 
500 			/* pci: wait M3 */
501 			phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
502 				SER_EV_FW_TIMER_EXPIRE);
503 
504 #else
505 			ser_resume_trx_process(pser, PHL_CTRL_RX);
506 			rtw_phl_start_rx_process(pser->phl_info);
507 			ser_resume_trx_process(pser, PHL_CTRL_TX);
508 			rtw_phl_tx_req_notify(pser->phl_info);
509 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
510 #endif
511 			break;
512 		}
513 
514 		/*send msg to core*/
515 		/*phl_msg_hub_send(pser->phl_info, &msg);*/
516 
517 		if (false == ops->is_tx_pause(pser->phl_info) ||
518 			false == ops->is_rx_pause(pser->phl_info) ) {
519 			/* pci: polling fail; wait for a while */
520 			phl_fsm_set_alarm(pser->fsm_obj,
521 				SER_POLLING_INTERVAL, SER_EV_POLL_IO_EXPIRE);
522 			break;
523 		}
524 /*
525 		if(rtw_hal_lv1_rcvy(hal_info, RTW_PHL_SER_LV1_RCVY_STEP_1) != RTW_HAL_STATUS_SUCCESS){
526 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
527 			break;
528 		}
529 */
530 		ops->trx_reset(pser->phl_info, PHL_CTRL_TX|PHL_CTRL_RX);
531 
532 		/* pci: send M2 event */
533 		ser_send_m2_event(pser);
534 
535 		/* pci: wait M3 */
536 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
537 			SER_EV_FW_TIMER_EXPIRE);
538 		break;
539 
540 	case FSM_EV_CANCEL:
541 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
542 		break;
543 
544 	case FSM_EV_STATE_OUT:
545 		phl_fsm_cancel_alarm(pser->fsm_obj);
546 		break;
547 
548 	default:
549 		break;
550 	}
551 	return 0;
552 }
553 
ser_usb_l1_pause_trx_done(struct ser_obj * pser)554 static void ser_usb_l1_pause_trx_done(struct ser_obj *pser)
555 {
556 	rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_RCVY_STEP_1);
557 
558 	ser_send_m2_event(pser);
559 }
560 
ser_usb_l1_pause_trx_st_hdl(void * obj,u16 event,void * param)561 static int ser_usb_l1_pause_trx_st_hdl(void *obj, u16 event, void *param)
562 {
563 	struct ser_obj *pser = (struct ser_obj *)obj;
564 	struct phl_hci_trx_ops *ops = pser->phl_info->hci_trx_ops;
565 	struct phl_msg msg = {0};
566 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
567 
568 	switch (event) {
569 	case FSM_EV_STATE_IN:
570 		phl_ser_set_status(pser, SER_L1);
571 
572 		SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_SER);
573 		SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_SER_L1);
574 		phl_msg_hub_send(pser->phl_info, NULL, &msg);
575 
576 		ops->req_tx_stop(pser->phl_info);
577 		rtw_phl_tx_req_notify(pser->phl_info);
578 
579 #if 0
580 		/* not request pause PHL Rx in USB data path */
581 		ops->req_rx_stop(pser->phl_info);
582 		rtw_phl_start_rx_process(pser->phl_info);
583 #endif
584 
585 		if (false == ops->is_tx_pause(pser->phl_info)
586 #if 0
587 			|| false == ops->is_rx_pause(pser->phl_info)
588 #endif
589 			) {
590 			phl_fsm_set_alarm(pser->fsm_obj,
591 				SER_USB_POLLING_INTERVAL_ACT, SER_EV_POLL_IO_EXPIRE);
592 
593 			pser->poll_io_times = SER_USB_POLL_IO_TIMES;
594 			break;
595 		}
596 
597 		ser_usb_l1_pause_trx_done(pser);
598 
599 #ifdef RTW_WKARD_SER_USB_POLLING_EVENT
600 		phl_fsm_set_alarm_ext(pser->fsm_obj,
601 			SER_USB_POLLING_INTERVAL_ACT, SER_EV_POLL_USB_INT_EXPIRE, 1, NULL);
602 #endif
603 
604 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
605 			SER_EV_FW_TIMER_EXPIRE);
606 
607 		break;
608 
609 #ifdef RTW_WKARD_SER_USB_POLLING_EVENT
610 	case SER_EV_POLL_USB_INT_EXPIRE:
611 		ser_usb_chk_int_event(pser);
612 
613 		phl_fsm_set_alarm_ext(pser->fsm_obj,
614 			SER_USB_POLLING_INTERVAL_ACT, SER_EV_POLL_USB_INT_EXPIRE, 1, NULL);
615 		break;
616 #endif
617 
618 	case SER_EV_M3_DO_RECOVERY:
619 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L1_DO_HCI);
620 		break;
621 
622 	case SER_EV_FW_TIMER_EXPIRE:
623 		status = rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_SER_RCVY_STEP_2);
624 		ser_resume_trx_process(pser, PHL_CTRL_TX);
625 		rtw_phl_tx_req_notify(pser->phl_info);
626 
627 		if (status != RTW_HAL_STATUS_SUCCESS)
628 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
629 		else
630 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
631 
632 		break;
633 
634 	case SER_EV_M9_L2_RESET:
635 		ser_resume_trx_process(pser, PHL_CTRL_TX);
636 		rtw_phl_tx_req_notify(pser->phl_info);
637 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
638 		break;
639 
640 	case SER_EV_POLL_IO_EXPIRE:
641 
642 		if (pser->poll_io_times-- <= 0) {
643 #ifdef RTW_WKARD_SER_L1_EXPIRE
644 			ser_usb_l1_pause_trx_done(pser);
645 
646 			phl_fsm_set_alarm_ext(pser->fsm_obj,
647 				SER_USB_POLLING_INTERVAL_ACT, SER_EV_POLL_USB_INT_EXPIRE, 1, NULL);
648 
649 			phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
650 				SER_EV_FW_TIMER_EXPIRE);
651 #else
652 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
653 #endif
654 			break;
655 		}
656 
657 		if (false == ops->is_tx_pause(pser->phl_info)
658 #if 0
659 			|| false == ops->is_rx_pause(pser->phl_info)
660 #endif
661 			) {
662 			phl_fsm_set_alarm(pser->fsm_obj,
663 				SER_USB_POLLING_INTERVAL_ACT, SER_EV_POLL_IO_EXPIRE);
664 			break;
665 		}
666 
667 		ser_usb_l1_pause_trx_done(pser);
668 
669 		phl_fsm_set_alarm_ext(pser->fsm_obj,
670 			SER_USB_POLLING_INTERVAL_ACT, SER_EV_POLL_USB_INT_EXPIRE, 1, NULL);
671 
672 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
673 			SER_EV_FW_TIMER_EXPIRE);
674 
675 		break;
676 
677 	case FSM_EV_CANCEL:
678 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
679 		break;
680 
681 	case FSM_EV_STATE_OUT:
682 		phl_fsm_cancel_alarm(pser->fsm_obj);
683 		phl_fsm_cancel_alarm_ext(pser->fsm_obj, 1);
684 		break;
685 
686 	default:
687 		break;
688 	}
689 	return 0;
690 }
691 
ser_sdio_l1_pause_trx_st_hdl(void * obj,u16 event,void * param)692 static int ser_sdio_l1_pause_trx_st_hdl(void *obj, u16 event, void *param)
693 {
694 	struct ser_obj *pser = (struct ser_obj *)obj;
695 	struct phl_hci_trx_ops *ops = pser->phl_info->hci_trx_ops;
696 	struct phl_msg msg = {0};
697 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
698 
699 	switch (event) {
700 	case FSM_EV_STATE_IN:
701 		phl_ser_set_status(pser, BIT1);
702 
703 		SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_SER);
704 		SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_SER_L1);
705 		phl_msg_hub_send(pser->phl_info, NULL, &msg);
706 
707 		ops->req_tx_stop(pser->phl_info);
708 		rtw_phl_tx_req_notify(pser->phl_info);
709 
710 		ops->req_rx_stop(pser->phl_info);
711 		rtw_phl_start_rx_process(pser->phl_info);
712 
713 		if (false == ops->is_tx_pause(pser->phl_info)
714 			|| false == ops->is_rx_pause(pser->phl_info)) {
715 			phl_fsm_set_alarm(pser->fsm_obj,
716 				SER_POLLING_INTERVAL, SER_EV_POLL_IO_EXPIRE);
717 
718 			pser->poll_io_times = SER_POLL_IO_TIMES;
719 			break;
720 		}
721 
722 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_DIS_HCI_INT);
723 
724 		if (rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_RCVY_STEP_1)
725 			!= RTW_HAL_STATUS_SUCCESS) {
726 			rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
727 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
728 			break;
729 		}
730 
731 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_SER_HANDSHAKE_MODE);
732 
733 		ser_send_m2_event(pser);
734 
735 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
736 			SER_EV_FW_TIMER_EXPIRE);
737 
738 		break;
739 
740 	case SER_EV_CHK_SER_EVENT:
741 		if (true == rtw_hal_recognize_halt_c2h_interrupt(pser->phl_info->hal))
742 			_ser_event_notify(pser->phl_info, NULL);
743 
744 		break;
745 
746 	case SER_EV_M3_DO_RECOVERY:
747 		rtw_hal_clear_interrupt(pser->phl_info->hal);
748 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L1_DO_HCI);
749 		break;
750 
751 	case SER_EV_FW_TIMER_EXPIRE:
752 		status = rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_SER_RCVY_STEP_2);
753 
754 		ser_resume_trx_process(pser, PHL_CTRL_RX);
755 		rtw_phl_start_rx_process(pser->phl_info);
756 		ser_resume_trx_process(pser, PHL_CTRL_TX);
757 		rtw_phl_tx_req_notify(pser->phl_info);
758 
759 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
760 
761 		if (status != RTW_HAL_STATUS_SUCCESS) {
762 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
763 		} else {
764 			phl_ser_clear_status(pser, BIT1);
765 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
766 		}
767 
768 		break;
769 
770 	case SER_EV_M9_L2_RESET:
771 		ser_resume_trx_process(pser, PHL_CTRL_RX);
772 		rtw_phl_start_rx_process(pser->phl_info);
773 		ser_resume_trx_process(pser, PHL_CTRL_TX);
774 		rtw_phl_tx_req_notify(pser->phl_info);
775 
776 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
777 
778 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
779 		break;
780 
781 	case SER_EV_POLL_IO_EXPIRE:
782 
783 		if (pser->poll_io_times-- <= 0) {
784 #ifdef RTW_WKARD_SER_L1_EXPIRE
785 
786 			if (rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_RCVY_STEP_1)
787 				!= RTW_HAL_STATUS_SUCCESS) {
788 				rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
789 				phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
790 				break;
791 			}
792 
793 			rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_SER_HANDSHAKE_MODE);
794 
795 			ser_send_m2_event(pser);
796 
797 			phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
798 				SER_EV_FW_TIMER_EXPIRE);
799 
800 #else
801 			ser_resume_trx_process(pser, PHL_CTRL_RX);
802 			rtw_phl_start_rx_process(pser->phl_info);
803 			ser_resume_trx_process(pser, PHL_CTRL_TX);
804 			rtw_phl_tx_req_notify(pser->phl_info);
805 
806 			rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
807 
808 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
809 #endif
810 			break;
811 		}
812 
813 		if (false == ops->is_tx_pause(pser->phl_info) ||
814 			false == ops->is_rx_pause(pser->phl_info)) {
815 			phl_fsm_set_alarm(pser->fsm_obj,
816 				SER_POLLING_INTERVAL, SER_EV_POLL_IO_EXPIRE);
817 			break;
818 		}
819 
820 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_DIS_HCI_INT);
821 
822 		if (rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_RCVY_STEP_1)
823 			!= RTW_HAL_STATUS_SUCCESS) {
824 			rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
825 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
826 			break;
827 		}
828 
829 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_SER_HANDSHAKE_MODE);
830 
831 		ser_send_m2_event(pser);
832 
833 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
834 			SER_EV_FW_TIMER_EXPIRE);
835 		break;
836 
837 	case FSM_EV_CANCEL:
838 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
839 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
840 		break;
841 
842 	case FSM_EV_STATE_OUT:
843 		phl_fsm_cancel_alarm(pser->fsm_obj);
844 		break;
845 
846 	default:
847 		break;
848 	}
849 	return 0;
850 }
851 
ser_pci_l1_do_hci_st_hdl(void * obj,u16 event,void * param)852 static int ser_pci_l1_do_hci_st_hdl(void *obj, u16 event, void *param)
853 {
854 	struct ser_obj *pser = (struct ser_obj *)obj;
855 
856 	switch (event) {
857 	case FSM_EV_STATE_IN:
858 
859 		if(rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_SER_RCVY_STEP_2)
860 			!= RTW_HAL_STATUS_SUCCESS){
861 			ser_resume_trx_process(pser, PHL_CTRL_RX);
862 			rtw_phl_start_rx_process(pser->phl_info);
863 			ser_resume_trx_process(pser, PHL_CTRL_TX);
864 			rtw_phl_tx_req_notify(pser->phl_info);
865 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
866 			break;
867 		}
868 		ser_resume_trx_process(pser, PHL_CTRL_RX);
869 		rtw_phl_start_rx_process(pser->phl_info);
870 
871 		/* pci: send M4 event */
872 		ser_send_m4_event(pser);
873 
874 		/* pci: set timeout to wait M5 */
875 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
876 			SER_EV_FW_TIMER_EXPIRE);
877 		break;
878 
879 	case SER_EV_M5_READY:
880 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L1_RESUME_TRX);
881 		break;
882 
883 
884 	case SER_EV_FW_TIMER_EXPIRE:
885 		/* PHL_INFO("ser_pci_l1_do_hci_st_hdl():	SER_EV_FW_TIMER_EXPIRE \n"); */
886 		/* _ser_event_notify(pser->phl_info, NULL); */
887 		/* phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2); */
888 		ser_resume_trx_process(pser, PHL_CTRL_TX);
889 		rtw_phl_tx_req_notify(pser->phl_info);
890 		phl_ser_clear_status(pser, SER_L1);
891 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
892 		break;
893 
894 	case SER_EV_M9_L2_RESET:
895 
896 		ser_resume_trx_process(pser, PHL_CTRL_TX);
897 		rtw_phl_tx_req_notify(pser->phl_info);
898 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
899 
900 		break;
901 
902 	case FSM_EV_CANCEL:
903 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
904 		break;
905 
906 	case FSM_EV_STATE_OUT:
907 		phl_fsm_cancel_alarm(pser->fsm_obj);
908 		break;
909 
910 	default:
911 		break;
912 	}
913 	return 0;
914 }
915 
ser_usb_l1_do_hci_st_hdl(void * obj,u16 event,void * param)916 static int ser_usb_l1_do_hci_st_hdl(void *obj, u16 event, void *param)
917 {
918 	struct ser_obj *pser = (struct ser_obj *)obj;
919 
920 	switch (event) {
921 	case FSM_EV_STATE_IN:
922 		if (rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_SER_RCVY_STEP_2)
923 			!= RTW_HAL_STATUS_SUCCESS) {
924 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
925 			break;
926 		}
927 		ser_resume_trx_process(pser, PHL_CTRL_RX);
928 		rtw_phl_start_rx_process(pser->phl_info);
929 
930 		ser_send_m4_event(pser);
931 
932 #ifdef RTW_WKARD_SER_USB_POLLING_EVENT
933 		phl_fsm_set_alarm_ext(pser->fsm_obj,
934 			SER_USB_POLLING_INTERVAL_ACT, SER_EV_POLL_USB_INT_EXPIRE, 1, NULL);
935 #endif
936 
937 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
938 			SER_EV_FW_TIMER_EXPIRE);
939 		break;
940 
941 #ifdef RTW_WKARD_SER_USB_POLLING_EVENT
942 	case SER_EV_POLL_USB_INT_EXPIRE:
943 		ser_usb_chk_int_event(pser);
944 
945 		phl_fsm_set_alarm_ext(pser->fsm_obj,
946 			SER_USB_POLLING_INTERVAL_ACT, SER_EV_POLL_USB_INT_EXPIRE, 1, NULL);
947 		break;
948 #endif
949 
950 	case SER_EV_M5_READY:
951 	case SER_EV_FW_TIMER_EXPIRE:
952 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L1_RESUME_TRX);
953 		break;
954 
955 	case SER_EV_M9_L2_RESET:
956 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
957 		break;
958 
959 	case FSM_EV_CANCEL:
960 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
961 		break;
962 
963 	case FSM_EV_STATE_OUT:
964 		phl_fsm_cancel_alarm(pser->fsm_obj);
965 		phl_fsm_cancel_alarm_ext(pser->fsm_obj, 1);
966 		break;
967 
968 	default:
969 		break;
970 	}
971 	return 0;
972 }
973 
ser_sdio_l1_do_hci_st_hdl(void * obj,u16 event,void * param)974 static int ser_sdio_l1_do_hci_st_hdl(void *obj, u16 event, void *param)
975 {
976 	struct ser_obj *pser = (struct ser_obj *)obj;
977 
978 	switch (event) {
979 	case FSM_EV_STATE_IN:
980 
981 		if (rtw_hal_lv1_rcvy(pser->phl_info->hal, RTW_PHL_SER_LV1_SER_RCVY_STEP_2)
982 			!= RTW_HAL_STATUS_SUCCESS) {
983 			rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
984 			phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
985 			break;
986 		}
987 		ser_resume_trx_process(pser, PHL_CTRL_RX);
988 		rtw_phl_start_rx_process(pser->phl_info);
989 
990 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_SER_HANDSHAKE_MODE);
991 
992 		ser_send_m4_event(pser);
993 
994 		phl_fsm_set_alarm(pser->fsm_obj, SER_FW_TIMEOUT,
995 			SER_EV_FW_TIMER_EXPIRE);
996 		break;
997 
998 	case SER_EV_CHK_SER_EVENT:
999 		if (true == rtw_hal_recognize_halt_c2h_interrupt(pser->phl_info->hal))
1000 			_ser_event_notify(pser->phl_info, NULL);
1001 
1002 		break;
1003 
1004 	case SER_EV_M5_READY:
1005 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
1006 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L1_RESUME_TRX);
1007 		break;
1008 
1009 	case SER_EV_FW_TIMER_EXPIRE:
1010 		ser_resume_trx_process(pser, PHL_CTRL_TX);
1011 		rtw_phl_tx_req_notify(pser->phl_info);
1012 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
1013 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
1014 		break;
1015 
1016 	case SER_EV_M9_L2_RESET:
1017 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
1018 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_L2);
1019 		break;
1020 
1021 	case FSM_EV_CANCEL:
1022 		rtw_hal_config_interrupt(pser->phl_info->hal, RTW_PHL_EN_HCI_INT);
1023 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
1024 		break;
1025 
1026 	case FSM_EV_STATE_OUT:
1027 		phl_fsm_cancel_alarm(pser->fsm_obj);
1028 		break;
1029 
1030 	default:
1031 		break;
1032 	}
1033 	return 0;
1034 }
1035 
ser_l1_resume_trx_st_hdl(void * obj,u16 event,void * param)1036 static int ser_l1_resume_trx_st_hdl(void *obj, u16 event, void *param)
1037 {
1038 	struct ser_obj *pser = (struct ser_obj *)obj;
1039 
1040 
1041 	switch (event) {
1042 	case FSM_EV_STATE_IN:
1043 
1044 		/* TODO resume TRX process */
1045 		ser_resume_trx_process(pser, PHL_CTRL_TX);
1046 		rtw_phl_tx_req_notify(pser->phl_info);
1047 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
1048 		break;
1049 
1050 	case FSM_EV_CANCEL:
1051 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
1052 		break;
1053 
1054 	case FSM_EV_STATE_OUT:
1055 		phl_fsm_cancel_alarm(pser->fsm_obj);
1056 		phl_ser_clear_status(pser, SER_L1);
1057 		break;
1058 
1059 	default:
1060 		break;
1061 	}
1062 	return 0;
1063 }
1064 
ser_l2_st_hdl(void * obj,u16 event,void * param)1065 static int ser_l2_st_hdl(void *obj, u16 event, void *param)
1066 {
1067 	struct ser_obj *pser = (struct ser_obj *)obj;
1068 	struct phl_msg msg = {0};
1069 
1070 	switch (event) {
1071 	case FSM_EV_STATE_IN:
1072 
1073 		/*To avoid fw watchdog intr trigger periodically*/
1074 		rtw_hal_ser_reset_wdt_intr(pser->phl_info->hal);
1075 
1076 		/* TODO do something */
1077 		phl_ser_clear_status(pser, SER_L1);
1078 		phl_ser_set_status(pser, SER_L2);
1079 
1080 		SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_SER);
1081 		SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_SER_L2);
1082 		phl_msg_hub_send(pser->phl_info, NULL, &msg);
1083 
1084 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
1085 		break;
1086 
1087 	case FSM_EV_TIMER_EXPIRE:
1088 		break;
1089 
1090 	case FSM_EV_CANCEL:
1091 		phl_fsm_state_goto(pser->fsm_obj, SER_ST_IDLE);
1092 		break;
1093 
1094 	case FSM_EV_STATE_OUT:
1095 		phl_fsm_cancel_alarm(pser->fsm_obj);
1096 		break;
1097 
1098 	default:
1099 		break;
1100 	}
1101 	return 0;
1102 }
1103 
ser_dump_obj(void * obj,char * s,int * sz)1104 static void ser_dump_obj(void *obj, char *s, int *sz)
1105 {
1106 	/* nothing to do for now */
1107 }
1108 
ser_dump_fsm(void * fsm,char * s,int * sz)1109 static void ser_dump_fsm(void *fsm, char *s, int *sz)
1110 {
1111 	/* nothing to do for now */
1112 }
1113 
1114 /* For EXTERNAL application to create a ser FSM */
1115 /* @root: FSM root structure
1116  * @phl_info: private data structure to invoke hal/phl function
1117  *
1118  * return
1119  * fsm_main: FSM main structure (Do NOT expose)
1120  */
phl_ser_new_fsm(struct fsm_root * root,struct phl_info_t * phl_info)1121 struct fsm_main *phl_ser_new_fsm(struct fsm_root *root,
1122 	struct phl_info_t *phl_info)
1123 {
1124 	void *d = phl_to_drvpriv(phl_info);
1125 	struct fsm_main *fsm = NULL;
1126 	struct rtw_phl_fsm_tb tb;
1127 
1128 	_os_mem_set(d, &tb, 0, sizeof(tb));
1129 
1130 	if (phl_info->phl_com->hci_type == RTW_HCI_PCIE)
1131 		tb.state_tbl = ser_pci_state_tbl;
1132 	else if (phl_info->phl_com->hci_type == RTW_HCI_USB)
1133 		tb.state_tbl = ser_usb_state_tbl;
1134 	else if (phl_info->phl_com->hci_type == RTW_HCI_SDIO)
1135 		tb.state_tbl = ser_sdio_state_tbl;
1136 	else
1137 		return NULL;
1138 
1139 	tb.max_state = sizeof(ser_pci_state_tbl)/sizeof(ser_pci_state_tbl[0]);
1140 	tb.max_event = sizeof(ser_event_tbl)/sizeof(ser_event_tbl[0]);
1141 	tb.evt_tbl = ser_event_tbl;
1142 	tb.dump_obj = ser_dump_obj;
1143 	tb.dump_obj = ser_dump_fsm;
1144 	tb.dbg_level = FSM_DBG_INFO;
1145 	tb.evt_level = FSM_DBG_INFO;
1146 
1147 	fsm = phl_fsm_init_fsm(root, "ser", phl_info, &tb);
1148 
1149 	return fsm;
1150 }
1151 
1152 /* For EXTERNAL application to destory ser fsm */
1153 /* @fsm: see fsm_main
1154  */
phl_ser_destory_fsm(struct fsm_main * fsm)1155 void phl_ser_destory_fsm(struct fsm_main *fsm)
1156 {
1157 	if (fsm == NULL)
1158 		return;
1159 
1160 	/* deinit fsm local variable if has */
1161 
1162 	/* call FSM Framewro to deinit fsm */
1163 	phl_fsm_deinit_fsm(fsm);
1164 }
1165 
1166 /* For EXTERNAL application to create SER object */
1167 /* @fsm: FSM main structure which created by phl_ser_new_fsm()
1168  * @phl_info: private data structure to invoke hal/phl function
1169  *
1170  * return
1171  * ser_obj: structure of SER object (Do NOT expose)
1172  */
phl_ser_new_obj(struct fsm_main * fsm,struct phl_info_t * phl_info)1173 struct ser_obj *phl_ser_new_obj(struct fsm_main *fsm,
1174 	struct phl_info_t *phl_info)
1175 {
1176 	void *d = phl_to_drvpriv(phl_info);
1177 	struct fsm_obj *obj;
1178 	struct ser_obj *pser;
1179 
1180 
1181 	pser = phl_fsm_new_obj(fsm, (void **)&obj, sizeof(*pser));
1182 
1183 	if (pser == NULL) {
1184 		/* TODO free fsm; currently will be freed in deinit process */
1185 		FSM_ERR(fsm, "ser: malloc obj fail\n");
1186 		return NULL;
1187 	}
1188 	pser->fsm = fsm;
1189 	pser->fsm_obj = obj;
1190 	pser->phl_info = phl_info;
1191 
1192 	/* init local use variable */
1193 	_os_spinlock_init(d, &pser->state_lock);
1194 
1195 	return pser;
1196 }
1197 
1198 /* For EXTERNAL application to destory ser object */
1199 /* @pser: local created command object
1200  *
1201  */
phl_ser_destory_obj(struct ser_obj * pser)1202 void phl_ser_destory_obj(struct ser_obj *pser)
1203 {
1204 	void *d;
1205 
1206 	if (pser == NULL)
1207 		return;
1208 
1209 	d = phl_to_drvpriv(pser->phl_info);
1210 
1211 	/* deinit obj local variable if has */
1212 	_os_spinlock_free(d, &pser->state_lock);
1213 
1214 	/* inform FSM framewory to recycle fsm_obj */
1215 	phl_fsm_destory_obj(pser->fsm_obj);
1216 }
1217 
1218 /* For EXTERNAL application to stop ser service (expose) */
1219 /* @pser: ser job will be cancelled
1220  */
phl_ser_cancel(void * phl)1221 enum rtw_phl_status phl_ser_cancel(void *phl)
1222 {
1223 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1224 	struct ser_obj *pser = phl_info->ser_obj;
1225 
1226 	return phl_fsm_gen_msg(phl, pser->fsm_obj, NULL, 0, FSM_EV_CANCEL);
1227 }
1228 
1229 /* For EXTERNAL interrupt handler to send event into ser fsm (expose) */
phl_ser_event_to_fw(void * phl,u32 err)1230 enum rtw_phl_status phl_ser_event_to_fw(void *phl, u32 err)
1231 {
1232 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1233 	enum rtw_hal_status status;
1234 
1235 	status = rtw_hal_ser_set_error_status(phl_info->hal ,err);
1236 	PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_, "phl_ser_event_to_fw err %d, status 0x%x\n", err, status);
1237 	return status;
1238 }
1239 
1240 /* For EXTERNAL interrupt handler and dump fw ple (expose) */
rtw_phl_ser_dump_ple_buffer(void * phl)1241 enum rtw_phl_status rtw_phl_ser_dump_ple_buffer(void *phl)
1242 {
1243 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1244 
1245 	PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_, "rtw_phl_ser_dump_ple_buffer\n");
1246 
1247 	rtw_hal_dump_fw_rsvd_ple(phl_info->hal);
1248 
1249 	return RTW_PHL_STATUS_SUCCESS;
1250 }
1251 
1252 /* For EXTERNAL interrupt handler and dump fw ple (expose) */
phl_fw_watchdog_timeout_notify(void * phl)1253 enum rtw_phl_status phl_fw_watchdog_timeout_notify(void *phl)
1254 {
1255 	enum RTW_PHL_SER_NOTIFY_EVENT notify = RTW_PHL_SER_L2_RESET;
1256 	PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_, "phl_fw_watchdog_timeout_notify triggle L2 Reset !!!\n");
1257 
1258 	return phl_ser_send_msg(phl, notify);
1259 }
1260 
rtw_phl_ser_l2_notify(struct rtw_phl_com_t * phl_com)1261 enum rtw_phl_status rtw_phl_ser_l2_notify(struct rtw_phl_com_t *phl_com)
1262 {
1263 	enum RTW_PHL_SER_NOTIFY_EVENT notify = RTW_PHL_SER_L2_RESET;
1264 	PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_, "rtw_phl_ser_l2_notify triggle L2 Reset !!!\n");
1265 
1266 	return phl_ser_send_msg(phl_com->phl_priv, notify);
1267 }
1268 
1269 /* @phl: phl_info_t
1270  * @notify: event to ser fsm
1271  */
1272 
1273 #ifndef CONFIG_PHL_CMD_SER
phl_ser_send_msg(void * phl,enum RTW_PHL_SER_NOTIFY_EVENT notify)1274 enum rtw_phl_status phl_ser_send_msg(void *phl,
1275 	enum RTW_PHL_SER_NOTIFY_EVENT notify)
1276 {
1277 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1278 	struct ser_obj *pser = phl_info->ser_obj;
1279 	u16 event;
1280 
1281 	switch (notify) {
1282 	case RTW_PHL_SER_PAUSE_TRX: /* M1 */
1283 		event = SER_EV_L1_START;
1284 		break;
1285 	case RTW_PHL_SER_DO_RECOVERY: /* M3 */
1286 		event = SER_EV_M3_DO_RECOVERY;
1287 		break;
1288 	case RTW_PHL_SER_READY: /* M5 */
1289 		event = SER_EV_M5_READY;
1290 		break;
1291 	case RTW_PHL_SER_L2_RESET: /* M9 */
1292 		event = SER_EV_M9_L2_RESET;
1293 		break;
1294 	case RTW_PHL_SER_EVENT_CHK:
1295 		event = SER_EV_CHK_SER_EVENT;
1296 		break;
1297 	case RTW_PHL_SER_L0_RESET:
1298 		PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "phl_ser_send_msg(): Unsupported case:%d, please check it\n",
1299 				notify);
1300 		return RTW_PHL_STATUS_FAILURE;
1301 	default:
1302 		PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "phl_ser_send_msg(): Unrecognize case:%d, please check it\n",
1303 				notify);
1304 		return RTW_PHL_STATUS_FAILURE;
1305 	}
1306 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "phl_ser_send_msg  event  %d\n", event);
1307 
1308 	return phl_fsm_gen_msg(phl, pser->fsm_obj, NULL, 0, event);
1309 }
1310 
1311 
1312 /* For EXTERNAL application to do L2 reset (expose) */
1313 /* @pser: ser job will be cancelled
1314  */
phl_ser_inprogress(void * phl)1315 u8 phl_ser_inprogress(void *phl)
1316 {
1317 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1318 	struct ser_obj *pser = phl_info->ser_obj;
1319 	u8 reset_type = 0;
1320 	void *d = phl_to_drvpriv(phl_info);
1321 
1322 	_os_spinlock(d, &pser->state_lock, _bh, NULL);
1323 
1324 	if(pser->trigger_l1_reset == true) {
1325 		reset_type |= SER_L1;
1326 		//pser->trigger_l2_reset = false;
1327 	}
1328 	if(pser->trigger_l2_reset == true) {
1329 		reset_type |= SER_L2;
1330 	}
1331 
1332 	_os_spinunlock(d, &pser->state_lock, _bh, NULL);
1333 	return reset_type;
1334 }
1335 #endif
1336 
1337 /* For EXTERNAL application to do L2 reset (expose) */
1338 /* @pser: ser job will be cancelled
1339  */
phl_ser_clear_status(struct ser_obj * pser,u32 serstatus)1340 void phl_ser_clear_status(struct ser_obj *pser, u32 serstatus)
1341 {
1342 	void *d = phl_to_drvpriv(pser->phl_info);
1343 
1344 	_os_spinlock(d, &pser->state_lock, _bh, NULL);
1345 
1346 	if(serstatus & SER_L1) {
1347 		pser->trigger_l1_reset = false;
1348 	}
1349 	if(serstatus & SER_L2) {
1350 		pser->trigger_l2_reset = false;
1351 	}
1352 
1353 	_os_spinunlock(d, &pser->state_lock, _bh, NULL);
1354 }
1355 
phl_ser_set_status(struct ser_obj * pser,u32 serstatus)1356 void phl_ser_set_status(struct ser_obj *pser, u32 serstatus)
1357 {
1358 	void *d = phl_to_drvpriv(pser->phl_info);
1359 
1360 	_os_spinlock(d, &pser->state_lock, _bh, NULL);
1361 
1362 	if(serstatus & SER_L1) {
1363 		pser->trigger_l1_reset = true;
1364 	}
1365 	if(serstatus & SER_L2) {
1366 		pser->trigger_l2_reset = true;
1367 	}
1368 
1369 	_os_spinunlock(d, &pser->state_lock, _bh, NULL);
1370 }
1371 
1372 
1373 /* For EXTERNAL application notify from upper layer*/
phl_ser_notify_from_upper_watchdog_status(void * phl,bool inprogress)1374 void phl_ser_notify_from_upper_watchdog_status(void *phl, bool inprogress)
1375 {
1376 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1377 	struct ser_obj *pser = phl_info->ser_obj;
1378 
1379 	pser->dynamicThredRunning = inprogress;
1380 }
1381 
rtw_phl_notify_watchdog_status(void * phl,bool inprogress)1382 void rtw_phl_notify_watchdog_status(void *phl, bool inprogress)
1383 {
1384 	phl_ser_notify_from_upper_watchdog_status(phl, inprogress);
1385 }
1386 #endif /*CONFIG_FSM*/
1387 
1388