xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/phl_wow.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright(c) 2019 Realtek Corporation.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify it
6*4882a593Smuzhiyun  * under the terms of version 2 of the GNU General Public License as
7*4882a593Smuzhiyun  * published by the Free Software Foundation.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful, but WITHOUT
10*4882a593Smuzhiyun  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12*4882a593Smuzhiyun  * more details.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *****************************************************************************/
15*4882a593Smuzhiyun #define _PHL_WOW_C_
16*4882a593Smuzhiyun #include "phl_headers.h"
17*4882a593Smuzhiyun 
phl_wow_mdl_init(struct phl_info_t * phl_info)18*4882a593Smuzhiyun enum rtw_phl_status phl_wow_mdl_init(struct phl_info_t* phl_info)
19*4882a593Smuzhiyun {
20*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
21*4882a593Smuzhiyun #ifdef CONFIG_WOWLAN
22*4882a593Smuzhiyun 	struct phl_wow_info *info = phl_to_wow_info(phl_info);
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun 	info->phl_info = phl_info;
25*4882a593Smuzhiyun 	_os_spinlock_init(phl_to_drvpriv(phl_info), &info->wow_lock);
26*4882a593Smuzhiyun #endif /* CONFIG_WOWLAN */
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	return pstatus;
29*4882a593Smuzhiyun }
30*4882a593Smuzhiyun 
phl_wow_mdl_deinit(struct phl_info_t * phl_info)31*4882a593Smuzhiyun void phl_wow_mdl_deinit(struct phl_info_t* phl_info)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun #ifdef CONFIG_WOWLAN
34*4882a593Smuzhiyun 	struct phl_wow_info *info = phl_to_wow_info(phl_info);
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	_os_spinlock_free(phl_to_drvpriv(phl_info), &info->wow_lock);
37*4882a593Smuzhiyun #endif /* CONFIG_WOWLAN */
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #ifdef CONFIG_WOWLAN
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* TO-DO: Confirm the enum strcut of the algo */
_phl_query_iv_len(u8 algo)43*4882a593Smuzhiyun u8 _phl_query_iv_len(u8 algo)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	u8 len = 0;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	switch(algo) {
48*4882a593Smuzhiyun 	case RTW_ENC_WEP40:
49*4882a593Smuzhiyun 		len = 4;
50*4882a593Smuzhiyun 		break;
51*4882a593Smuzhiyun 	case RTW_ENC_TKIP:
52*4882a593Smuzhiyun 	case RTW_ENC_CCMP:
53*4882a593Smuzhiyun 	case RTW_ENC_GCMP256:
54*4882a593Smuzhiyun 		len = 8;
55*4882a593Smuzhiyun 		break;
56*4882a593Smuzhiyun 	default:
57*4882a593Smuzhiyun 		len = 0;
58*4882a593Smuzhiyun 		break;
59*4882a593Smuzhiyun 	}
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	return len;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
_phl_query_key_desc_ver(struct phl_wow_info * wow_info,u8 algo)64*4882a593Smuzhiyun u8 _phl_query_key_desc_ver(struct phl_wow_info *wow_info, u8 algo)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	u8 akm_type = wow_info->gtk_ofld_info.akmtype_byte3;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	if (algo == RTW_ENC_TKIP)
69*4882a593Smuzhiyun 		return EAPOLKEY_KEYDESC_VER_1;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	if (akm_type == 1 || akm_type == 2) {
72*4882a593Smuzhiyun 		return EAPOLKEY_KEYDESC_VER_2;
73*4882a593Smuzhiyun 	} else if (akm_type > 2 && akm_type < 7) {
74*4882a593Smuzhiyun 		return EAPOLKEY_KEYDESC_VER_3;
75*4882a593Smuzhiyun 	} else {
76*4882a593Smuzhiyun 		return 0;
77*4882a593Smuzhiyun 	}
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_null_info(struct phl_wow_info * wow_info,struct rtw_phl_stainfo_t * phl_sta,struct rtw_pkt_ofld_null_info * null_info)80*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_null_info(
81*4882a593Smuzhiyun 	struct phl_wow_info *wow_info,
82*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *phl_sta,
83*4882a593Smuzhiyun 	struct rtw_pkt_ofld_null_info *null_info)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(null_info->a1[0]), &(phl_sta->mac_addr[0]), MAC_ADDRESS_LENGTH);
88*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(null_info->a2[0]), &(phl_sta->wrole->mac_addr[0]), MAC_ADDRESS_LENGTH);
89*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(null_info->a3[0]), &(phl_sta->mac_addr[0]), MAC_ADDRESS_LENGTH);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_probe_req_info(struct phl_wow_info * wow_info,struct rtw_phl_stainfo_t * phl_sta,struct rtw_pkt_ofld_probe_req_info * probe_req_info)93*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_probe_req_info(
94*4882a593Smuzhiyun 	struct phl_wow_info *wow_info,
95*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *phl_sta,
96*4882a593Smuzhiyun 	struct rtw_pkt_ofld_probe_req_info *probe_req_info)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	if (wow_info->nlo_info.construct_pbreq == NULL) {
101*4882a593Smuzhiyun 		_os_mem_cpy(drv_priv, &(probe_req_info->a2[0]),
102*4882a593Smuzhiyun 			&(phl_sta->wrole->mac_addr[0]), MAC_ADDRESS_LENGTH);
103*4882a593Smuzhiyun 	} else {
104*4882a593Smuzhiyun 		probe_req_info->construct_pbreq = wow_info->nlo_info.construct_pbreq;
105*4882a593Smuzhiyun 	}
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_arp_rsp_info(struct phl_wow_info * wow_info,struct rtw_phl_stainfo_t * phl_sta,struct rtw_pkt_ofld_arp_rsp_info * arp_rsp_info)108*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_arp_rsp_info(struct phl_wow_info *wow_info, struct rtw_phl_stainfo_t *phl_sta,
109*4882a593Smuzhiyun 						struct rtw_pkt_ofld_arp_rsp_info *arp_rsp_info)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
112*4882a593Smuzhiyun 	u8 pairwise_algo = get_wow_pairwise_algo_type(wow_info);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(arp_rsp_info->a1[0]), &(phl_sta->mac_addr[0]), MAC_ADDRESS_LENGTH);
115*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(arp_rsp_info->a2[0]), &(phl_sta->wrole->mac_addr[0]), MAC_ADDRESS_LENGTH);
116*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(arp_rsp_info->a3[0]), &(phl_sta->mac_addr[0]), MAC_ADDRESS_LENGTH);
117*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(arp_rsp_info->host_ipv4_addr[0]),
118*4882a593Smuzhiyun 		&(wow_info->arp_ofld_info.arp_ofld_content.host_ipv4_addr[0]),
119*4882a593Smuzhiyun 		IPV4_ADDRESS_LENGTH);
120*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(arp_rsp_info->remote_ipv4_addr[0]),
121*4882a593Smuzhiyun 		&(wow_info->arp_ofld_info.arp_ofld_content.remote_ipv4_addr[0]),
122*4882a593Smuzhiyun 		IPV4_ADDRESS_LENGTH);
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	arp_rsp_info->sec_hdr = _phl_query_iv_len(pairwise_algo);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_na_info(struct phl_wow_info * wow_info,struct rtw_phl_stainfo_t * phl_sta,struct rtw_pkt_ofld_na_info * na_info)127*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_na_info(struct phl_wow_info *wow_info, struct rtw_phl_stainfo_t *phl_sta,
128*4882a593Smuzhiyun 					struct rtw_pkt_ofld_na_info *na_info)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
131*4882a593Smuzhiyun 	u8 pairwise_algo = get_wow_pairwise_algo_type(wow_info);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(na_info->a1[0]), &(phl_sta->mac_addr[0]), MAC_ADDRESS_LENGTH);
134*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(na_info->a2[0]), &(phl_sta->wrole->mac_addr[0]), MAC_ADDRESS_LENGTH);
135*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(na_info->a3[0]), &(phl_sta->mac_addr[0]), MAC_ADDRESS_LENGTH);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	na_info->sec_hdr = _phl_query_iv_len(pairwise_algo);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_eapol_key_info(struct phl_wow_info * wow_info,struct rtw_phl_stainfo_t * phl_sta,struct rtw_pkt_ofld_eapol_key_info * eapol_key_info)141*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_eapol_key_info(
142*4882a593Smuzhiyun 	struct phl_wow_info *wow_info,
143*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *phl_sta,
144*4882a593Smuzhiyun 	struct rtw_pkt_ofld_eapol_key_info *eapol_key_info)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
147*4882a593Smuzhiyun 	struct rtw_gtk_ofld_info *gtk_ofld_info = &wow_info->gtk_ofld_info;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	u8 pairwise_algo = get_wow_pairwise_algo_type(wow_info);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(eapol_key_info->a1[0]), &(phl_sta->mac_addr[0]),
152*4882a593Smuzhiyun 		MAC_ADDRESS_LENGTH);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(eapol_key_info->a2[0]), &(phl_sta->wrole->mac_addr[0]),
155*4882a593Smuzhiyun 			MAC_ADDRESS_LENGTH);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(eapol_key_info->a3[0]), &(phl_sta->mac_addr[0]),
158*4882a593Smuzhiyun 			MAC_ADDRESS_LENGTH);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	eapol_key_info->sec_hdr = _phl_query_iv_len(pairwise_algo);
161*4882a593Smuzhiyun 	eapol_key_info->key_desc_ver = _phl_query_key_desc_ver(wow_info, pairwise_algo);
162*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, eapol_key_info->replay_cnt,
163*4882a593Smuzhiyun 				gtk_ofld_info->gtk_ofld_content.replay_cnt, 8);
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_sa_query_info(struct phl_wow_info * wow_info,struct rtw_phl_stainfo_t * phl_sta,struct rtw_pkt_ofld_sa_query_info * sa_query_info)166*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_sa_query_info(
167*4882a593Smuzhiyun 	struct phl_wow_info *wow_info,
168*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *phl_sta,
169*4882a593Smuzhiyun 	struct rtw_pkt_ofld_sa_query_info *sa_query_info)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
172*4882a593Smuzhiyun 	u8 pairwise_algo = get_wow_pairwise_algo_type(wow_info);
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(sa_query_info->a1[0]), &(phl_sta->mac_addr[0]),
175*4882a593Smuzhiyun 			MAC_ADDRESS_LENGTH);
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(sa_query_info->a2[0]), &(phl_sta->wrole->mac_addr[0]),
178*4882a593Smuzhiyun 			MAC_ADDRESS_LENGTH);
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(sa_query_info->a3[0]), &(phl_sta->mac_addr[0]),
181*4882a593Smuzhiyun 			MAC_ADDRESS_LENGTH);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	sa_query_info->sec_hdr = _phl_query_iv_len(pairwise_algo);
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_realwow_kapkt_info(struct phl_wow_info * wow_info,struct rtw_phl_stainfo_t * phl_sta,struct rtw_pkt_ofld_realwow_kapkt_info * kapkt_info)186*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_realwow_kapkt_info(
187*4882a593Smuzhiyun 	struct phl_wow_info *wow_info,
188*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *phl_sta,
189*4882a593Smuzhiyun 	struct rtw_pkt_ofld_realwow_kapkt_info *kapkt_info)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(kapkt_info->keep_alive_pkt_ptrn[0]),
194*4882a593Smuzhiyun 		&(wow_info->realwow_info.realwow_ofld_content.keep_alive_pkt_ptrn[0]),
195*4882a593Smuzhiyun 		wow_info->realwow_info.realwow_ofld_content.keep_alive_pkt_size);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	kapkt_info->keep_alive_pkt_size =
198*4882a593Smuzhiyun 				wow_info->realwow_info.realwow_ofld_content.keep_alive_pkt_size;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_realwow_ack_info(struct phl_wow_info * wow_info,struct rtw_pkt_ofld_realwow_ack_info * ack_info)201*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_realwow_ack_info(
202*4882a593Smuzhiyun 	struct phl_wow_info *wow_info,
203*4882a593Smuzhiyun 	struct rtw_pkt_ofld_realwow_ack_info *ack_info)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(ack_info->ack_ptrn[0]),
208*4882a593Smuzhiyun 		&(wow_info->realwow_info.realwow_ofld_content.ack_ptrn[0]),
209*4882a593Smuzhiyun 		wow_info->realwow_info.realwow_ofld_content.ack_ptrn_size);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	ack_info->ack_ptrn_size = wow_info->realwow_info.realwow_ofld_content.ack_ptrn_size;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun 
_phl_cfg_pkt_ofld_realwow_wp_info(struct phl_wow_info * wow_info,struct rtw_pkt_ofld_realwow_wp_info * wp_info)214*4882a593Smuzhiyun static void _phl_cfg_pkt_ofld_realwow_wp_info(
215*4882a593Smuzhiyun 	struct phl_wow_info *wow_info,
216*4882a593Smuzhiyun 	struct rtw_pkt_ofld_realwow_wp_info *wp_info)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(wow_info->phl_info);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, &(wp_info->wakeup_ptrn[0]),
221*4882a593Smuzhiyun 		&(wow_info->realwow_info.realwow_ofld_content.wakeup_ptrn[0]),
222*4882a593Smuzhiyun 		wow_info->realwow_info.realwow_ofld_content.wakeup_ptrn_size);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	wp_info->wakeup_ptrn_size = wow_info->realwow_info.realwow_ofld_content.wakeup_ptrn_size;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun 
rtw_phl_cfg_keep_alive_info(void * phl,struct rtw_keep_alive_info * info)227*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_cfg_keep_alive_info(void *phl, struct rtw_keep_alive_info *info)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
230*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
231*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
232*4882a593Smuzhiyun 	struct rtw_keep_alive_info *keep_alive_info = &wow_info->keep_alive_info;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	FUNCIN();
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	keep_alive_info->keep_alive_en = info->keep_alive_en;
237*4882a593Smuzhiyun 	keep_alive_info->keep_alive_period = info->keep_alive_period;
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] keep_alive_en %d\n", keep_alive_info->keep_alive_en);
240*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] keep_alive_period %d\n", keep_alive_info->keep_alive_period);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	return phl_status;
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun 
rtw_phl_cfg_disc_det_info(void * phl,struct rtw_disc_det_info * info)245*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_cfg_disc_det_info(void *phl, struct rtw_disc_det_info *info)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
248*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
249*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
250*4882a593Smuzhiyun 	struct rtw_disc_det_info *disc_det_info = &wow_info->disc_det_info;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	FUNCIN();
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	disc_det_info->disc_det_en = info->disc_det_en;
255*4882a593Smuzhiyun 	disc_det_info->disc_wake_en = info->disc_wake_en;
256*4882a593Smuzhiyun 	disc_det_info->try_pkt_count = info->try_pkt_count;
257*4882a593Smuzhiyun 	disc_det_info->check_period = info->check_period;
258*4882a593Smuzhiyun 	disc_det_info->cnt_bcn_lost_en = info->cnt_bcn_lost_en;
259*4882a593Smuzhiyun 	disc_det_info->cnt_bcn_lost_limit = info->cnt_bcn_lost_limit;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] disc_det_en %d\n", disc_det_info->disc_det_en);
262*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] disc_wake_en %d\n", disc_det_info->disc_wake_en);
263*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] try_pkt_count %d\n", disc_det_info->try_pkt_count);
264*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] check_period %d\n", disc_det_info->check_period);
265*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] cnt_bcn_lost_en %d\n", disc_det_info->cnt_bcn_lost_en);
266*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] cnt_bcn_lost_limit %d\n", disc_det_info->cnt_bcn_lost_limit);
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	return phl_status;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun static void
_phl_show_nlo_info(struct rtw_nlo_info * info)272*4882a593Smuzhiyun _phl_show_nlo_info(struct rtw_nlo_info *info)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun 	u32 i = 0;
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	if (info->num_of_networks == 0)
277*4882a593Smuzhiyun 		return;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	for (i = 0; i < info->num_of_networks; i++) {
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_,
282*4882a593Smuzhiyun 			"[wow][nlo] #%u ssid/len/cipher = %s/%u/%#x \n",
283*4882a593Smuzhiyun 			i, (char *)info->ssid[i], info->ssidlen[i], info->chipertype[i]);
284*4882a593Smuzhiyun 	}
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	for (i = 0; i < info->channel_num; i++) {
287*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_,
288*4882a593Smuzhiyun 			"[wow][nlo] channel #%u: %u \n", i, info->channel_list[i].chan);
289*4882a593Smuzhiyun 	}
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_,
292*4882a593Smuzhiyun 		"[wow][nlo] num of hidden ap %u \n", info->num_of_hidden_ap);
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_,
295*4882a593Smuzhiyun 		"[wow][nlo] delyms/cycle/period/slow_period = %u/%u/%u/%u \n",
296*4882a593Smuzhiyun 		info->delay, info->cycle, info->period, info->slow_period);
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
rtw_phl_cfg_nlo_info(void * phl,struct rtw_nlo_info * info)300*4882a593Smuzhiyun void rtw_phl_cfg_nlo_info(void *phl, struct rtw_nlo_info *info)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
303*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
304*4882a593Smuzhiyun 	struct rtw_nlo_info *nlo_info = &wow_info->nlo_info;
305*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(phl_info);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	FUNCIN();
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	nlo_info->nlo_en = info->nlo_en;
310*4882a593Smuzhiyun 	nlo_info->num_of_networks = info->num_of_networks;
311*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, nlo_info->ssid, info->ssid,
312*4882a593Smuzhiyun 		info->num_of_networks * MAX_SSID_LEN);
313*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, nlo_info->ssidlen,
314*4882a593Smuzhiyun 		info->ssidlen, info->num_of_networks);
315*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, nlo_info->chipertype,
316*4882a593Smuzhiyun 		info->chipertype, info->num_of_networks);
317*4882a593Smuzhiyun 	nlo_info->num_of_hidden_ap = info->num_of_hidden_ap;
318*4882a593Smuzhiyun 	nlo_info->channel_num = info->channel_num;
319*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv, nlo_info->channel_list, info->channel_list,
320*4882a593Smuzhiyun 		info->channel_num * sizeof(struct scan_ofld_ch_info));
321*4882a593Smuzhiyun 	nlo_info->period = info->period;
322*4882a593Smuzhiyun 	nlo_info->cycle = info->cycle;
323*4882a593Smuzhiyun 	nlo_info->slow_period = info->slow_period;
324*4882a593Smuzhiyun 	nlo_info->delay = info->delay;
325*4882a593Smuzhiyun 	nlo_info->construct_pbreq = info->construct_pbreq;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	_phl_show_nlo_info(nlo_info);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
rtw_phl_cfg_arp_ofld_info(void * phl,struct rtw_arp_ofld_info * info)330*4882a593Smuzhiyun void rtw_phl_cfg_arp_ofld_info(void *phl, struct rtw_arp_ofld_info *info)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
333*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
334*4882a593Smuzhiyun 	struct rtw_arp_ofld_info *arp_ofld_info = &wow_info->arp_ofld_info;
335*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(phl_info);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	FUNCIN();
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	arp_ofld_info->arp_en = info->arp_en;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] arp_en %u\n",
343*4882a593Smuzhiyun 			arp_ofld_info->arp_en);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	/* If not enabled, the following actions are not necessary */
346*4882a593Smuzhiyun 	if (false == arp_ofld_info->arp_en)
347*4882a593Smuzhiyun 		return;
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	arp_ofld_info->arp_action = info->arp_action;
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv,
352*4882a593Smuzhiyun 		&(arp_ofld_info->arp_ofld_content.remote_ipv4_addr[0]),
353*4882a593Smuzhiyun 		&(info->arp_ofld_content.remote_ipv4_addr[0]),
354*4882a593Smuzhiyun 		IPV4_ADDRESS_LENGTH);
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv,
357*4882a593Smuzhiyun 		&(arp_ofld_info->arp_ofld_content.host_ipv4_addr[0]),
358*4882a593Smuzhiyun 		&(info->arp_ofld_content.host_ipv4_addr[0]),
359*4882a593Smuzhiyun 		IPV4_ADDRESS_LENGTH);
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	_os_mem_cpy(drv_priv,
362*4882a593Smuzhiyun 		&(arp_ofld_info->arp_ofld_content.mac_addr[0]),
363*4882a593Smuzhiyun 		&(info->arp_ofld_content.mac_addr[0]),
364*4882a593Smuzhiyun 		MAC_ADDRESS_LENGTH);
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] arp_action %u\n",
367*4882a593Smuzhiyun 			arp_ofld_info->arp_action);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] arp_remote_ipv4  %u:%u:%u:%u\n",
370*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.remote_ipv4_addr[0],
371*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.remote_ipv4_addr[1],
372*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.remote_ipv4_addr[2],
373*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.remote_ipv4_addr[3]);
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] arp_host_ipv4  %u:%u:%u:%u\n",
376*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.host_ipv4_addr[0],
377*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.host_ipv4_addr[1],
378*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.host_ipv4_addr[2],
379*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.host_ipv4_addr[3]);
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] arp_mac_addr  %02x:%02x:%02x:%02x:%02x:%02x \n",
382*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.mac_addr[0],
383*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.mac_addr[1],
384*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.mac_addr[2],
385*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.mac_addr[3],
386*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.mac_addr[4],
387*4882a593Smuzhiyun 			arp_ofld_info->arp_ofld_content.mac_addr[5]);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun 
rtw_phl_cfg_ndp_ofld_info(void * phl,struct rtw_ndp_ofld_info * info)391*4882a593Smuzhiyun void rtw_phl_cfg_ndp_ofld_info(void *phl, struct rtw_ndp_ofld_info *info)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
394*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
395*4882a593Smuzhiyun 	struct rtw_ndp_ofld_info *ndp_ofld_info = &wow_info->ndp_ofld_info;
396*4882a593Smuzhiyun 	struct rtw_ndp_ofld_content *pcontent;
397*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(phl_info);
398*4882a593Smuzhiyun 	u8 idx = 0;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	FUNCIN();
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	ndp_ofld_info->ndp_en = info->ndp_en;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] ndp_en %u\n",
405*4882a593Smuzhiyun 			ndp_ofld_info->ndp_en);
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	/* If not enabled, the following actions are not necessary */
408*4882a593Smuzhiyun 	if (false == ndp_ofld_info->ndp_en)
409*4882a593Smuzhiyun 		return;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	for (idx = 0; idx < 2; idx++) {
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 		pcontent = &ndp_ofld_info->ndp_ofld_content[idx];
414*4882a593Smuzhiyun 		pcontent->ndp_en = info->ndp_ofld_content[idx].ndp_en;
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 		pcontent->chk_remote_ip =
417*4882a593Smuzhiyun 			info->ndp_ofld_content[idx].chk_remote_ip;
418*4882a593Smuzhiyun 		pcontent->num_target_ip =
419*4882a593Smuzhiyun 			info->ndp_ofld_content[idx].num_target_ip;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 		_os_mem_cpy(drv_priv, &(pcontent->mac_addr[0]),
422*4882a593Smuzhiyun 			&(info->ndp_ofld_content[idx].mac_addr[0]),
423*4882a593Smuzhiyun 			MAC_ADDRESS_LENGTH);
424*4882a593Smuzhiyun 		_os_mem_cpy(drv_priv, &(pcontent->remote_ipv6_addr[0]),
425*4882a593Smuzhiyun 			&(info->ndp_ofld_content[idx].remote_ipv6_addr[0]),
426*4882a593Smuzhiyun 			IPV6_ADDRESS_LENGTH);
427*4882a593Smuzhiyun 		_os_mem_cpy(drv_priv, &(pcontent->target_ipv6_addr[0][0]),
428*4882a593Smuzhiyun 			&(info->ndp_ofld_content[idx].target_ipv6_addr[0][0]),
429*4882a593Smuzhiyun 			IPV6_ADDRESS_LENGTH*2);
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] ndp_chk_remote_ip %u\n",
432*4882a593Smuzhiyun 			pcontent->chk_remote_ip);
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] ndp_num_target_ip %u\n",
435*4882a593Smuzhiyun 			pcontent->num_target_ip);
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] ndp_mac_addr  %02x:%02x:%02x:%02x:%02x:%02x \n",
438*4882a593Smuzhiyun 			pcontent->mac_addr[0],
439*4882a593Smuzhiyun 			pcontent->mac_addr[1],
440*4882a593Smuzhiyun 			pcontent->mac_addr[2],
441*4882a593Smuzhiyun 			pcontent->mac_addr[3],
442*4882a593Smuzhiyun 			pcontent->mac_addr[4],
443*4882a593Smuzhiyun 			pcontent->mac_addr[5]);
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_,
446*4882a593Smuzhiyun 			"[wow] ndp_remote_ipv6  %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \n",
447*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[0],
448*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[1],
449*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[2],
450*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[3],
451*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[4],
452*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[5],
453*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[6],
454*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[7],
455*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[8],
456*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[9],
457*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[10],
458*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[11],
459*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[12],
460*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[13],
461*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[14],
462*4882a593Smuzhiyun 			pcontent->remote_ipv6_addr[15]);
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_,
465*4882a593Smuzhiyun 			"[wow] ndp_target_ipv6_addr  %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \n",
466*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][0],
467*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][1],
468*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][2],
469*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][3],
470*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][4],
471*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][5],
472*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][6],
473*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][7],
474*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][8],
475*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][9],
476*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][10],
477*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][11],
478*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][12],
479*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][13],
480*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][14],
481*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[0][15]);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_,
484*4882a593Smuzhiyun 			"[wow] ndp_target_ipv6_addr  %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \n",
485*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][0],
486*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][1],
487*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][2],
488*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][3],
489*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][4],
490*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][5],
491*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][6],
492*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][7],
493*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][8],
494*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][9],
495*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][10],
496*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][11],
497*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][12],
498*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][13],
499*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][14],
500*4882a593Smuzhiyun 			pcontent->target_ipv6_addr[1][15]);
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	}
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun 
_phl_query_free_cam_entry_idx(struct rtw_pattern_match_info * pattern_match_info)506*4882a593Smuzhiyun u8 _phl_query_free_cam_entry_idx(struct rtw_pattern_match_info *pattern_match_info)
507*4882a593Smuzhiyun {
508*4882a593Smuzhiyun 	struct rtw_wowcam_upd_info *wowcam_info = pattern_match_info->wowcam_info;
509*4882a593Smuzhiyun 	u8 i = 0;
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 	for (i = 0; i < MAX_WOW_CAM_NUM; ++i)
512*4882a593Smuzhiyun 		if (wowcam_info[i].valid == 0)
513*4882a593Smuzhiyun 			break;
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	return i;
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun 
_phl_cal_crc16(u8 data,u16 crc)518*4882a593Smuzhiyun u16 _phl_cal_crc16(u8 data, u16 crc)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun 	u8 shift_in, data_bit;
521*4882a593Smuzhiyun 	u8 crc_bit4, crc_bit11, crc_bit15;
522*4882a593Smuzhiyun 	u16 crc_result;
523*4882a593Smuzhiyun 	int index;
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	for (index = 0; index < 8; index++) {
526*4882a593Smuzhiyun 		crc_bit15 = ((crc & BIT15) ? 1 : 0);
527*4882a593Smuzhiyun 		data_bit = (data & (BIT0 << index) ? 1 : 0);
528*4882a593Smuzhiyun 		shift_in = crc_bit15 ^ data_bit;
529*4882a593Smuzhiyun 		/*printf("crc_bit15=%d, DataBit=%d, shift_in=%d\n",
530*4882a593Smuzhiyun 		 * crc_bit15, data_bit, shift_in);*/
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 		crc_result = crc << 1;
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 		if (shift_in == 0)
535*4882a593Smuzhiyun 			crc_result &= (~BIT0);
536*4882a593Smuzhiyun 		else
537*4882a593Smuzhiyun 			crc_result |= BIT0;
538*4882a593Smuzhiyun 		/*printf("CRC =%x\n",CRC_Result);*/
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 		crc_bit11 = ((crc & BIT11) ? 1 : 0) ^ shift_in;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 		if (crc_bit11 == 0)
543*4882a593Smuzhiyun 			crc_result &= (~BIT12);
544*4882a593Smuzhiyun 		else
545*4882a593Smuzhiyun 			crc_result |= BIT12;
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 		/*printf("bit12 CRC =%x\n",CRC_Result);*/
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 		crc_bit4 = ((crc & BIT4) ? 1 : 0) ^ shift_in;
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 		if (crc_bit4 == 0)
552*4882a593Smuzhiyun 			crc_result &= (~BIT5);
553*4882a593Smuzhiyun 		else
554*4882a593Smuzhiyun 			crc_result |= BIT5;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 		/* printf("bit5 CRC =%x\n",CRC_Result); */
557*4882a593Smuzhiyun 		crc = crc_result;
558*4882a593Smuzhiyun 	}
559*4882a593Smuzhiyun 	return crc;
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun 
_phl_cal_wow_ptrn_crc(u8 * pattern,u32 length)562*4882a593Smuzhiyun u16 _phl_cal_wow_ptrn_crc(u8 *pattern, u32 length)
563*4882a593Smuzhiyun {
564*4882a593Smuzhiyun 	u16 crc = 0xffff;
565*4882a593Smuzhiyun 	u32 i;
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	for (i = 0; i < length; i++)
568*4882a593Smuzhiyun 		crc = _phl_cal_crc16(pattern[i], crc);
569*4882a593Smuzhiyun 	crc = ~crc;
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 	return crc;
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun /*
574*4882a593Smuzhiyun  * To get the wake up pattern from the mask.
575*4882a593Smuzhiyun  * We do not count first 12 bits which means
576*4882a593Smuzhiyun  * DA[6] and SA[6] in the pattern to match HW design.
577*4882a593Smuzhiyun  */
_phl_get_ptrn_after_mask(struct rtw_wowcam_upd_info * wowcam_info,u8 * ptrn_after_mask)578*4882a593Smuzhiyun u32 _phl_get_ptrn_after_mask(struct rtw_wowcam_upd_info *wowcam_info, u8 *ptrn_after_mask)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun 	u32 ptrn_len_after_mask = 0;
581*4882a593Smuzhiyun 	u32 i;
582*4882a593Smuzhiyun 	u8 da_sa_offset = 12;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	for (i = da_sa_offset; i < wowcam_info->ptrn_len; i++) {
585*4882a593Smuzhiyun 		if (wowcam_info->mask[i / 8] >> (i % 8) & 0x01) {
586*4882a593Smuzhiyun 			ptrn_after_mask[ptrn_len_after_mask] = wowcam_info->ptrn[i];
587*4882a593Smuzhiyun 			ptrn_len_after_mask++;
588*4882a593Smuzhiyun 		}
589*4882a593Smuzhiyun 	}
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	return ptrn_len_after_mask;
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun /*
595*4882a593Smuzhiyun  * translate mask from os to mask for hw
596*4882a593Smuzhiyun  *
597*4882a593Smuzhiyun  * pattern from OS uses 'ethenet frame', like this:
598*4882a593Smuzhiyun  *	|    6   |    6   |   2  |     20    |  Variable  |  4  |
599*4882a593Smuzhiyun  *	|--------+--------+------+-----------+------------+-----|
600*4882a593Smuzhiyun  *	|    802.3 Mac Header    | IP Header | TCP Packet | FCS |
601*4882a593Smuzhiyun  *	|   DA   |   SA   | Type |
602*4882a593Smuzhiyun  *
603*4882a593Smuzhiyun  * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
604*4882a593Smuzhiyun  *	|     24 or 30      |    6   |   2  |     20    |  Variable  |  4  |
605*4882a593Smuzhiyun  *	|-------------------+--------+------+-----------+------------+-----|
606*4882a593Smuzhiyun  *	| 802.11 MAC Header |       LLC     | IP Header | TCP Packet | FCS |
607*4882a593Smuzhiyun  *			    | Others | Type |
608*4882a593Smuzhiyun  *
609*4882a593Smuzhiyun  * Therefore, we need to translate mask_from_OS to mask_to_hw.
610*4882a593Smuzhiyun  * We should left-shift mask_from_os by 6 bits to omit 'DA',
611*4882a593Smuzhiyun  * to make it correspond to 'LLC' of mask_to_hw.
612*4882a593Smuzhiyun  * Our HW packet begins from LLC, mask_to_hw[5:0] is part of LLC,
613*4882a593Smuzhiyun  * but mask_from_os[5:0] is 'SA' after left-shift.
614*4882a593Smuzhiyun  * They just don't match, so we need to set first 5 bits to 0.
615*4882a593Smuzhiyun */
616*4882a593Smuzhiyun 
_phl_to_hw_wake_mask(struct rtw_wowcam_upd_info * wowcam_info)617*4882a593Smuzhiyun void _phl_to_hw_wake_mask(struct rtw_wowcam_upd_info *wowcam_info)
618*4882a593Smuzhiyun {
619*4882a593Smuzhiyun 	u8 mask_hw[MAX_WOW_PATTERN_SIZE_BYTE] = {0};
620*4882a593Smuzhiyun 	u32 mask_len = _os_div_round_up(wowcam_info->ptrn_len, 8);
621*4882a593Smuzhiyun 	u32 i;
622*4882a593Smuzhiyun 	u8 sa_offset = 6;
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun 	for (i = 0; i < mask_len - 1; i++) {
625*4882a593Smuzhiyun 		mask_hw[i] = wowcam_info->mask[i] >> sa_offset;
626*4882a593Smuzhiyun 		mask_hw[i] |= (wowcam_info->mask[i + 1] & 0x3F) << 2;
627*4882a593Smuzhiyun 	}
628*4882a593Smuzhiyun 	mask_hw[i] = (wowcam_info->mask[i] >> sa_offset) & 0x3F;
629*4882a593Smuzhiyun 	mask_hw[0] &= 0xC0;
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 	for (i = 0; i < MAX_WOW_PATTERN_SIZE_DWORD; i++) {
632*4882a593Smuzhiyun 		wowcam_info->wake_mask[i] = mask_hw[i * 4];
633*4882a593Smuzhiyun 		wowcam_info->wake_mask[i] |= (mask_hw[i * 4 + 1] << 8);
634*4882a593Smuzhiyun 		wowcam_info->wake_mask[i] |= (mask_hw[i * 4 + 2] << 16);
635*4882a593Smuzhiyun 		wowcam_info->wake_mask[i] |= (mask_hw[i * 4 + 3] << 24);
636*4882a593Smuzhiyun 	}
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun 
rtw_phl_remove_wow_ptrn_info(void * phl,u8 wowcam_id)639*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_remove_wow_ptrn_info(void *phl, u8 wowcam_id)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
642*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
643*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
644*4882a593Smuzhiyun 	struct rtw_pattern_match_info *pattern_match_info = &wow_info->pattern_match_info;
645*4882a593Smuzhiyun 	struct rtw_wowcam_upd_info *wowcam_info = &(pattern_match_info->wowcam_info[wowcam_id]);
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	if (wowcam_id < MAX_WOW_CAM_NUM) {
648*4882a593Smuzhiyun 		wowcam_info->valid = 0;
649*4882a593Smuzhiyun 		phl_status = RTW_PHL_STATUS_SUCCESS;
650*4882a593Smuzhiyun 	} else {
651*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_WARNING_, "[wow] %s(): Invalid wowcam id(%u), Fail.\n",
652*4882a593Smuzhiyun 						__func__, wowcam_id);
653*4882a593Smuzhiyun 		phl_status = RTW_PHL_STATUS_FAILURE;
654*4882a593Smuzhiyun 	}
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun 	return phl_status;
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun 
rtw_phl_add_wow_ptrn_info(void * phl,struct rtw_wowcam_upd_info * info,u8 * wowcam_id)659*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_add_wow_ptrn_info(void *phl, struct rtw_wowcam_upd_info *info, u8 *wowcam_id)
660*4882a593Smuzhiyun {
661*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
662*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
663*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
664*4882a593Smuzhiyun 	struct rtw_pattern_match_info *pattern_match_info = &wow_info->pattern_match_info;
665*4882a593Smuzhiyun 	struct rtw_wowcam_upd_info *wowcam_info = NULL;
666*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
667*4882a593Smuzhiyun 	u8 ptrn_after_mask[MAX_WOW_PATTERN_SIZE_BIT] = {0};
668*4882a593Smuzhiyun 	u32 ptrn_len_after_mask = 0;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	*wowcam_id = _phl_query_free_cam_entry_idx(pattern_match_info);
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	if (*wowcam_id < MAX_WOW_CAM_NUM) {
673*4882a593Smuzhiyun 		wowcam_info = &(pattern_match_info->wowcam_info[*wowcam_id]);
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 		_os_mem_set(d, wowcam_info, 0, sizeof(struct rtw_wowcam_upd_info));
676*4882a593Smuzhiyun 		_os_mem_cpy(d, wowcam_info, info, sizeof(struct rtw_wowcam_upd_info));
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun 		ptrn_len_after_mask = _phl_get_ptrn_after_mask(wowcam_info, ptrn_after_mask);
679*4882a593Smuzhiyun 		wowcam_info->match_crc = _phl_cal_wow_ptrn_crc(ptrn_after_mask, ptrn_len_after_mask);
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 		_phl_to_hw_wake_mask(wowcam_info);
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 		/* fill in phl */
684*4882a593Smuzhiyun 		wowcam_info->wow_cam_idx = *wowcam_id;
685*4882a593Smuzhiyun 		wowcam_info->rw = 1;
686*4882a593Smuzhiyun 		wowcam_info->is_negative_pattern_match = 0;
687*4882a593Smuzhiyun 		wowcam_info->skip_mac_hdr = 1;
688*4882a593Smuzhiyun 		wowcam_info->valid = 1;
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 		phl_status = RTW_PHL_STATUS_SUCCESS;
691*4882a593Smuzhiyun 	} else {
692*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_WARNING_, "[wow] no free cam entry can be used.\n");
693*4882a593Smuzhiyun 		phl_status = RTW_PHL_STATUS_RESOURCE;
694*4882a593Smuzhiyun 	}
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 	return phl_status;
697*4882a593Smuzhiyun }
698*4882a593Smuzhiyun 
rtw_phl_cfg_gtk_ofld_info(void * phl,struct rtw_gtk_ofld_info * info)699*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_cfg_gtk_ofld_info(void *phl, struct rtw_gtk_ofld_info *info)
700*4882a593Smuzhiyun {
701*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
702*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
703*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
704*4882a593Smuzhiyun 	struct rtw_gtk_ofld_info *gtk_ofld_info = &wow_info->gtk_ofld_info;
705*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	FUNCIN();
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	if (info == NULL || gtk_ofld_info == NULL) {
710*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_WARNING_, "[wow] %s(): some ptr is NULL\n", __func__);
711*4882a593Smuzhiyun 		phl_status = RTW_PHL_STATUS_FAILURE;
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun 	} else {
714*4882a593Smuzhiyun 		_os_mem_set(d, gtk_ofld_info, 0, sizeof(struct rtw_gtk_ofld_info));
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gtk_en(%u), continue to gtk_ofld.\n", info->gtk_en);
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 		if (info->gtk_en) {
719*4882a593Smuzhiyun 			_os_mem_cpy(d, gtk_ofld_info, info, sizeof(struct rtw_gtk_ofld_info));
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gtk_ofld_info:\n");
722*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - gtk_en          = %u\n", gtk_ofld_info->gtk_en);
723*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - tkip_en         = %u\n", gtk_ofld_info->tkip_en);
724*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - ieee80211w_en   = %u\n", gtk_ofld_info->ieee80211w_en);
725*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - pairwise_wakeup = %u\n", gtk_ofld_info->pairwise_wakeup);
726*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - bip_sec_algo    = %u\n", gtk_ofld_info->bip_sec_algo);
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gtk_ofld_content:\n");
729*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - akmtype_byte3   = %u\n", gtk_ofld_info->akmtype_byte3);
730*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - kck_len         = %u\n", gtk_ofld_info->gtk_ofld_content.kck_len);
731*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - kek_len         = %u\n", gtk_ofld_info->gtk_ofld_content.kek_len);
732*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - replay_cnt      = 0x%x%x\n",
733*4882a593Smuzhiyun 						*((u32 *)(gtk_ofld_info->gtk_ofld_content.replay_cnt)+1),
734*4882a593Smuzhiyun 						*((u32 *)(gtk_ofld_info->gtk_ofld_content.replay_cnt)));
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun 			if(info->ieee80211w_en) {
737*4882a593Smuzhiyun 				gtk_ofld_info->hw_11w_en = true;
738*4882a593Smuzhiyun 				PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - igtk_keyid      = 0x%x\n",
739*4882a593Smuzhiyun 								*((u32 *)(gtk_ofld_info->gtk_ofld_content.igtk_keyid)));
740*4882a593Smuzhiyun 				PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - ipn             = 0x%x%x\n",
741*4882a593Smuzhiyun 								*((u32 *)(gtk_ofld_info->gtk_ofld_content.ipn)+1),
742*4882a593Smuzhiyun 								*((u32 *)(gtk_ofld_info->gtk_ofld_content.ipn)));
743*4882a593Smuzhiyun 				PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - igtk_len        = %u\n", gtk_ofld_info->gtk_ofld_content.igtk_len);
744*4882a593Smuzhiyun 				PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - psk_len         = %u\n", gtk_ofld_info->gtk_ofld_content.psk_len);
745*4882a593Smuzhiyun 			}
746*4882a593Smuzhiyun 		} else {
747*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gtk_ofld_info:\n");
748*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - gtk_en          = %u\n", gtk_ofld_info->gtk_en);
749*4882a593Smuzhiyun 		}
750*4882a593Smuzhiyun 	}
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	FUNCOUT();
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	return phl_status;
755*4882a593Smuzhiyun }
756*4882a593Smuzhiyun 
rtw_phl_cfg_realwow_info(void * phl,struct rtw_realwow_info * info)757*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_cfg_realwow_info(void *phl, struct rtw_realwow_info *info)
758*4882a593Smuzhiyun {
759*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
760*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
761*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
762*4882a593Smuzhiyun 	struct rtw_realwow_info *realwow_info = &wow_info->realwow_info;
763*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	if (info == NULL || realwow_info == NULL) {
766*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_WARNING_, "[wow] %s(): some ptr is NULL\n", __func__);
767*4882a593Smuzhiyun 		phl_status = RTW_PHL_STATUS_FAILURE;
768*4882a593Smuzhiyun 
769*4882a593Smuzhiyun 	} else {
770*4882a593Smuzhiyun 		_os_mem_set(d, realwow_info, 0, sizeof(struct rtw_realwow_info));
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] realwow_en(%u), continue to realwow_ofld.\n",
773*4882a593Smuzhiyun 					info->realwow_en);
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 		if (info->realwow_en) {
776*4882a593Smuzhiyun 			_os_mem_cpy(d, realwow_info, info, sizeof(struct rtw_realwow_info));
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] realwow_ofld_info:\n");
779*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - realwow_en 		= %u\n",
780*4882a593Smuzhiyun 						realwow_info->realwow_en);
781*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - tkip_en			= %u\n",
782*4882a593Smuzhiyun 						realwow_info->auto_wakeup);
783*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - interval			= %u\n",
784*4882a593Smuzhiyun 						realwow_info->realwow_ofld_content.interval);
785*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - kapktsize			= %u\n",
786*4882a593Smuzhiyun 						realwow_info->realwow_ofld_content.keep_alive_pkt_size);
787*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - acklostlimit		= %u\n",
788*4882a593Smuzhiyun 						realwow_info->realwow_ofld_content.ack_lost_limit);
789*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - ackpatternsize		= %u\n",
790*4882a593Smuzhiyun 						realwow_info->realwow_ofld_content.ack_ptrn_size);
791*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - wakeuppatternsize	= %u\n",
792*4882a593Smuzhiyun 						realwow_info->realwow_ofld_content.wakeup_ptrn_size);
793*4882a593Smuzhiyun 		} else {
794*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] realwow_ofld_info:\n");
795*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] - realwow_en		= %u\n",
796*4882a593Smuzhiyun 						realwow_info->realwow_en);
797*4882a593Smuzhiyun 		}
798*4882a593Smuzhiyun 	}
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun 	return phl_status;
801*4882a593Smuzhiyun }
802*4882a593Smuzhiyun 
rtw_phl_cfg_wow_wake(void * phl,struct rtw_wow_wake_info * info)803*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_cfg_wow_wake(void *phl, struct rtw_wow_wake_info *info)
804*4882a593Smuzhiyun {
805*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
806*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
807*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
808*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 	struct rtw_wow_wake_info *wow_wake_info = &wow_info->wow_wake_info;
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	FUNCIN();
813*4882a593Smuzhiyun 
814*4882a593Smuzhiyun 	wow_wake_info->wow_en = info->wow_en;
815*4882a593Smuzhiyun 	wow_wake_info->drop_all_pkt = info->drop_all_pkt;
816*4882a593Smuzhiyun 	wow_wake_info->rx_parse_after_wake = info->rx_parse_after_wake;
817*4882a593Smuzhiyun 	wow_wake_info->pairwise_sec_algo = info->pairwise_sec_algo;
818*4882a593Smuzhiyun 	wow_wake_info->group_sec_algo = info->group_sec_algo;
819*4882a593Smuzhiyun 	wow_wake_info->pattern_match_en = info->pattern_match_en;
820*4882a593Smuzhiyun 	wow_wake_info->magic_pkt_en = info->magic_pkt_en;
821*4882a593Smuzhiyun 	wow_wake_info->hw_unicast_en = info->hw_unicast_en;
822*4882a593Smuzhiyun 	wow_wake_info->fw_unicast_en = info->fw_unicast_en;
823*4882a593Smuzhiyun 	wow_wake_info->deauth_wakeup = info->deauth_wakeup;
824*4882a593Smuzhiyun 	wow_wake_info->rekey_wakeup = info->rekey_wakeup;
825*4882a593Smuzhiyun 	wow_wake_info->eap_wakeup = info->eap_wakeup;
826*4882a593Smuzhiyun 	wow_wake_info->all_data_wakeup = info->all_data_wakeup;
827*4882a593Smuzhiyun 	_os_mem_cpy(d, &wow_wake_info->remote_wake_ctrl_info,
828*4882a593Smuzhiyun 		&info->remote_wake_ctrl_info, sizeof(struct rtw_remote_wake_ctrl_info));
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] wow_en %d\n", wow_wake_info->wow_en);
831*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] drop_all_pkt %d\n", wow_wake_info->drop_all_pkt);
832*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] rx_parse_after_wake %d\n", wow_wake_info->rx_parse_after_wake);
833*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] pairwise_sec_algo %d\n", wow_wake_info->pairwise_sec_algo);
834*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] group_sec_algo %d\n", wow_wake_info->group_sec_algo);
835*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] bip_sec_algo %d\n", wow_wake_info->bip_sec_algo);
836*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] pattern_match_en %d\n", wow_wake_info->pattern_match_en);
837*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] magic_pkt_en %d\n", wow_wake_info->magic_pkt_en);
838*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] hw_unicast_en %d\n", wow_wake_info->hw_unicast_en);
839*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] fw_unicast_en %d\n", wow_wake_info->fw_unicast_en);
840*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] deauth_wakeup %d\n", wow_wake_info->deauth_wakeup);
841*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] rekey_wakeup %d\n", wow_wake_info->rekey_wakeup);
842*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] eap_wakeup %d\n", wow_wake_info->eap_wakeup);
843*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] all_data_wakeup %d\n", wow_wake_info->all_data_wakeup);
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	return phl_status;
846*4882a593Smuzhiyun }
847*4882a593Smuzhiyun 
rtw_phl_cfg_gpio_wake_pulse(void * phl,struct rtw_wow_gpio_info * info)848*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_cfg_gpio_wake_pulse(void *phl, struct rtw_wow_gpio_info *info)
849*4882a593Smuzhiyun {
850*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
851*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
852*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
853*4882a593Smuzhiyun 	struct rtw_wow_gpio_info *wow_gpio = &wow_info->wow_gpio;
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 	FUNCIN();
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun 	wow_gpio->dev2hst_gpio_en = info->dev2hst_gpio_en;
858*4882a593Smuzhiyun 	wow_gpio->disable_inband = info->disable_inband;
859*4882a593Smuzhiyun 	wow_gpio->gpio_output_input = info->gpio_output_input;
860*4882a593Smuzhiyun 	wow_gpio->gpio_active = info->gpio_active;
861*4882a593Smuzhiyun 	wow_gpio->toggle_pulse = info->toggle_pulse;
862*4882a593Smuzhiyun 	wow_gpio->data_pin_wakeup = info->data_pin_wakeup;
863*4882a593Smuzhiyun 	wow_gpio->gpio_pulse_nonstop = info->gpio_pulse_nonstop;
864*4882a593Smuzhiyun 	wow_gpio->gpio_time_unit = info->gpio_time_unit;
865*4882a593Smuzhiyun 	wow_gpio->gpio_num = info->gpio_num;
866*4882a593Smuzhiyun 	wow_gpio->gpio_pulse_dura = info->gpio_pulse_dura;
867*4882a593Smuzhiyun 	wow_gpio->gpio_pulse_period = info->gpio_pulse_period;
868*4882a593Smuzhiyun 	wow_gpio->gpio_pulse_count = info->gpio_pulse_count;
869*4882a593Smuzhiyun 	wow_gpio->customer_id = info->customer_id;
870*4882a593Smuzhiyun 	wow_gpio->gpio_pulse_en_a = info->gpio_pulse_en_a;
871*4882a593Smuzhiyun 	wow_gpio->gpio_duration_unit_a = info->gpio_duration_unit_a;
872*4882a593Smuzhiyun 	wow_gpio->gpio_pulse_nonstop_a = info->gpio_pulse_nonstop_a;
873*4882a593Smuzhiyun 	wow_gpio->special_reason_a = info->special_reason_a;
874*4882a593Smuzhiyun 	wow_gpio->gpio_duration_a = info->gpio_duration_a;
875*4882a593Smuzhiyun 	wow_gpio->gpio_pulse_count_a = info->gpio_pulse_count_a;
876*4882a593Smuzhiyun 	wow_gpio->dev2hst_gpio_mode = info->dev2hst_gpio_mode;
877*4882a593Smuzhiyun 	wow_gpio->dev2hst_gpio = info->dev2hst_gpio;
878*4882a593Smuzhiyun 	wow_gpio->dev2hst_high = info->dev2hst_high;
879*4882a593Smuzhiyun 
880*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] dev2hst_gpio_en %d\n", wow_gpio->dev2hst_gpio_en);
881*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] disable_inband %d\n", wow_gpio->disable_inband);
882*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_output_input %d\n", wow_gpio->gpio_output_input);
883*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_active %d\n", wow_gpio->gpio_active);
884*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] toggle_pulse %d\n", wow_gpio->toggle_pulse);
885*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] data_pin_wakeup %d\n", wow_gpio->data_pin_wakeup);
886*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_pulse_nonstop %d\n", wow_gpio->gpio_pulse_nonstop);
887*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_time_unit %d\n", wow_gpio->gpio_time_unit);
888*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_num %d\n", wow_gpio->gpio_num);
889*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_pulse_dura %d\n", wow_gpio->gpio_pulse_dura);
890*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_pulse_period %d\n", wow_gpio->gpio_pulse_period);
891*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_pulse_count %d\n", wow_gpio->gpio_pulse_count);
892*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] customer_id %d\n", wow_gpio->customer_id);
893*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_pulse_en_a %d\n", wow_gpio->gpio_pulse_en_a);
894*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_duration_unit_a %d\n", wow_gpio->gpio_duration_unit_a);
895*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_pulse_nonstop_a %d\n", wow_gpio->gpio_pulse_nonstop_a);
896*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] special_reason_a %d\n", wow_gpio->special_reason_a);
897*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_duration_a %d\n", wow_gpio->gpio_duration_a);
898*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] gpio_pulse_count_a %d\n", wow_gpio->gpio_pulse_count_a);
899*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] dev2hst_gpio_mode %d\n", wow_gpio->dev2hst_gpio_mode);
900*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] dev2hst_gpio %d\n", wow_gpio->dev2hst_gpio);
901*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] dev2hst_high %d\n", wow_gpio->dev2hst_high);
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 	return phl_status;
904*4882a593Smuzhiyun }
905*4882a593Smuzhiyun 
phl_record_wow_stat(struct phl_wow_info * wow_info)906*4882a593Smuzhiyun void phl_record_wow_stat(struct phl_wow_info *wow_info)
907*4882a593Smuzhiyun {
908*4882a593Smuzhiyun 	struct phl_wow_stat *wow_stat = &wow_info->wow_stat;
909*4882a593Smuzhiyun 
910*4882a593Smuzhiyun 	/* init */
911*4882a593Smuzhiyun 	wow_stat->func_en = wow_info->func_en;
912*4882a593Smuzhiyun 	wow_stat->op_mode = wow_info->op_mode;
913*4882a593Smuzhiyun 	wow_stat->keep_alive_en = wow_info->keep_alive_info.keep_alive_en;
914*4882a593Smuzhiyun 	wow_stat->disc_det_en = wow_info->disc_det_info.disc_det_en;
915*4882a593Smuzhiyun 	wow_stat->arp_en = wow_info->arp_ofld_info.arp_en;
916*4882a593Smuzhiyun 	wow_stat->ndp_en = wow_info->ndp_ofld_info.ndp_en;
917*4882a593Smuzhiyun 	wow_stat->gtk_en = wow_info->gtk_ofld_info.gtk_en;
918*4882a593Smuzhiyun 	wow_stat->dot11w_en = wow_info->gtk_ofld_info.ieee80211w_en;
919*4882a593Smuzhiyun 	wow_stat->err.init = wow_info->err.init;
920*4882a593Smuzhiyun 	/* deinit */
921*4882a593Smuzhiyun 	wow_stat->mac_pwr = wow_info->mac_pwr;
922*4882a593Smuzhiyun 	wow_stat->wake_rsn = wow_info->wake_rsn;
923*4882a593Smuzhiyun 	wow_stat->err.deinit = wow_info->err.deinit;
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun 	if (wow_info->aoac_info.rpt_fail)
926*4882a593Smuzhiyun 		++wow_stat->aoac_rpt_fail_cnt;
927*4882a593Smuzhiyun }
928*4882a593Smuzhiyun 
929*4882a593Smuzhiyun #ifdef CONFIG_PCI_HCI
_init_precfg(struct phl_info_t * phl_info,u8 band)930*4882a593Smuzhiyun enum rtw_phl_status _init_precfg(struct phl_info_t *phl_info, u8 band)
931*4882a593Smuzhiyun {
932*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
933*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
934*4882a593Smuzhiyun 	u8 status = false;
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	do {
937*4882a593Smuzhiyun 		/* 1. stop Tx DMA */
938*4882a593Smuzhiyun 		rtw_hal_wow_cfg_txdma(phl_info->hal, false);
939*4882a593Smuzhiyun 
940*4882a593Smuzhiyun 		/* 2. stop HW Tx */
941*4882a593Smuzhiyun 		hstatus = rtw_hal_wow_drop_tx(phl_info->hal, band);
942*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
943*4882a593Smuzhiyun 			PHL_ERR("[wow] rtw_hal_wow_drop_tx fail!\n");
944*4882a593Smuzhiyun 			break;
945*4882a593Smuzhiyun 		}
946*4882a593Smuzhiyun 
947*4882a593Smuzhiyun 		/* 3. poll dma idle */
948*4882a593Smuzhiyun 		status = rtw_hal_poll_txdma_idle(phl_info->hal);
949*4882a593Smuzhiyun 		if (!status) {
950*4882a593Smuzhiyun 			PHL_ERR("[wow] rtw_hal_poll_txdma_idle fail!\n");
951*4882a593Smuzhiyun 			break;
952*4882a593Smuzhiyun 		}
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 	} while (0);
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun 	if (RTW_HAL_STATUS_SUCCESS != hstatus)
957*4882a593Smuzhiyun 		pstatus = RTW_PHL_STATUS_FAILURE;
958*4882a593Smuzhiyun 	else
959*4882a593Smuzhiyun 		pstatus = RTW_PHL_STATUS_SUCCESS;
960*4882a593Smuzhiyun 
961*4882a593Smuzhiyun 	FUNCOUT_WSTS(pstatus);
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun 	return pstatus;
964*4882a593Smuzhiyun }
_init_postcfg(struct phl_info_t * phl_info)965*4882a593Smuzhiyun enum rtw_phl_status _init_postcfg(struct phl_info_t *phl_info)
966*4882a593Smuzhiyun {
967*4882a593Smuzhiyun 	/* stop tx/rx hci */
968*4882a593Smuzhiyun 	rtw_hal_cfg_txhci(phl_info->hal, false);
969*4882a593Smuzhiyun 	rtw_hal_cfg_rxhci(phl_info->hal, false);
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun 	rtw_hal_poll_txdma_idle(phl_info->hal);
972*4882a593Smuzhiyun 
973*4882a593Smuzhiyun 	return RTW_PHL_STATUS_SUCCESS;
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun #elif defined(CONFIG_USB_HCI)
_init_precfg(struct phl_info_t * phl_info,u8 band)976*4882a593Smuzhiyun enum rtw_phl_status _init_precfg(struct phl_info_t *phl_info, u8 band)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun 	return RTW_PHL_STATUS_SUCCESS;
979*4882a593Smuzhiyun }
_init_postcfg(struct phl_info_t * phl_info)980*4882a593Smuzhiyun enum rtw_phl_status _init_postcfg(struct phl_info_t *phl_info)
981*4882a593Smuzhiyun {
982*4882a593Smuzhiyun 	return RTW_PHL_STATUS_SUCCESS;
983*4882a593Smuzhiyun }
984*4882a593Smuzhiyun 
985*4882a593Smuzhiyun #elif defined(CONFIG_SDIO_HCI)
_init_precfg(struct phl_info_t * phl_info,u8 band)986*4882a593Smuzhiyun enum rtw_phl_status _init_precfg(struct phl_info_t *phl_info, u8 band)
987*4882a593Smuzhiyun {
988*4882a593Smuzhiyun 	return RTW_PHL_STATUS_SUCCESS;
989*4882a593Smuzhiyun }
_init_postcfg(struct phl_info_t * phl_info)990*4882a593Smuzhiyun enum rtw_phl_status _init_postcfg(struct phl_info_t *phl_info)
991*4882a593Smuzhiyun {
992*4882a593Smuzhiyun 	return RTW_PHL_STATUS_SUCCESS;
993*4882a593Smuzhiyun }
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun #endif
996*4882a593Smuzhiyun 
_init_precfg_set_rxfltr(struct phl_info_t * phl_info)997*4882a593Smuzhiyun static enum rtw_phl_status _init_precfg_set_rxfltr(struct phl_info_t *phl_info)
998*4882a593Smuzhiyun {
999*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun 	do {
1002*4882a593Smuzhiyun 		hstatus = rtw_hal_set_rxfltr_by_type(phl_info->hal, 0, RTW_PHL_PKT_TYPE_DATA, 0);
1003*4882a593Smuzhiyun 	 	if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1004*4882a593Smuzhiyun 			PHL_ERR("[wow] set rx filter data drop fail, status(%u)\n", hstatus);
1005*4882a593Smuzhiyun 			break;
1006*4882a593Smuzhiyun 		}
1007*4882a593Smuzhiyun 
1008*4882a593Smuzhiyun 		hstatus = rtw_hal_set_rxfltr_by_type(phl_info->hal, 0, RTW_PHL_PKT_TYPE_MGNT, 0);
1009*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1010*4882a593Smuzhiyun 			PHL_ERR("[wow] set rx filter mgnt drop fail, status(%u)\n", hstatus);
1011*4882a593Smuzhiyun 			break;
1012*4882a593Smuzhiyun 		}
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 		hstatus = rtw_hal_set_rxfltr_by_type(phl_info->hal, 0, RTW_PHL_PKT_TYPE_CTRL, 0);
1015*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1016*4882a593Smuzhiyun 			PHL_ERR("[wow] set rx filter ctrl drop fail, status(%u)\n", hstatus);
1017*4882a593Smuzhiyun 			break;
1018*4882a593Smuzhiyun 		}
1019*4882a593Smuzhiyun 	} while (0);
1020*4882a593Smuzhiyun 
1021*4882a593Smuzhiyun 	return (hstatus == RTW_HAL_STATUS_SUCCESS) ?
1022*4882a593Smuzhiyun 			RTW_PHL_STATUS_SUCCESS : RTW_PHL_STATUS_FAILURE;
1023*4882a593Smuzhiyun }
1024*4882a593Smuzhiyun 
_init_postcfg_set_rxfltr(struct phl_info_t * phl_info)1025*4882a593Smuzhiyun static enum rtw_phl_status _init_postcfg_set_rxfltr(struct phl_info_t *phl_info)
1026*4882a593Smuzhiyun {
1027*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun 	do {
1030*4882a593Smuzhiyun 		hstatus = rtw_hal_set_rxfltr_by_type(phl_info->hal, 0, RTW_PHL_PKT_TYPE_DATA, 1);
1031*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1032*4882a593Smuzhiyun 			PHL_ERR("[wow] set rx filter data to host fail, status(%u)\n", hstatus);
1033*4882a593Smuzhiyun 			break;
1034*4882a593Smuzhiyun 		}
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 		hstatus = rtw_hal_set_rxfltr_by_type(phl_info->hal, 0, RTW_PHL_PKT_TYPE_MGNT, 1);
1037*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1038*4882a593Smuzhiyun 			PHL_ERR("[wow] set rx filter mgnt to host fail, status(%u)\n", hstatus);
1039*4882a593Smuzhiyun 			break;
1040*4882a593Smuzhiyun 		}
1041*4882a593Smuzhiyun 
1042*4882a593Smuzhiyun 		hstatus = rtw_hal_set_rxfltr_by_type(phl_info->hal, 0, RTW_PHL_PKT_TYPE_CTRL, 1);
1043*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1044*4882a593Smuzhiyun 			PHL_ERR("[wow] set rx filter ctrl to host fail, status(%u)\n", hstatus);
1045*4882a593Smuzhiyun 			break;
1046*4882a593Smuzhiyun 		}
1047*4882a593Smuzhiyun 	} while (0);
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun 	return (hstatus == RTW_HAL_STATUS_SUCCESS) ?
1050*4882a593Smuzhiyun 			RTW_PHL_STATUS_SUCCESS : RTW_PHL_STATUS_FAILURE;
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun 
1053*4882a593Smuzhiyun #define MAX_POLLING_TRX_STOP 2000 /* us */
phl_wow_init_precfg(struct phl_wow_info * wow_info)1054*4882a593Smuzhiyun enum rtw_phl_status phl_wow_init_precfg(struct phl_wow_info *wow_info)
1055*4882a593Smuzhiyun {
1056*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1057*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1058*4882a593Smuzhiyun 	struct phl_hci_trx_ops *trx_ops = phl_info->hci_trx_ops;
1059*4882a593Smuzhiyun 	u32 wait_cnt = 0;
1060*4882a593Smuzhiyun 
1061*4882a593Smuzhiyun 	FUNCIN();
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 	/* pause sw Tx */
1064*4882a593Smuzhiyun 	trx_ops->req_tx_stop(phl_info);
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun 	/* schedule current existing tx handler */
1067*4882a593Smuzhiyun 	pstatus = rtw_phl_tx_req_notify(phl_info);
1068*4882a593Smuzhiyun 	if (RTW_PHL_STATUS_SUCCESS != pstatus)
1069*4882a593Smuzhiyun 		PHL_ERR("[wow] rtw_phl_tx_req_notify fail, status(%u)\n", pstatus);
1070*4882a593Smuzhiyun 
1071*4882a593Smuzhiyun 	/* polling pause sw Tx done */
1072*4882a593Smuzhiyun 	while (wait_cnt < MAX_POLLING_TRX_STOP) {
1073*4882a593Smuzhiyun 		if (trx_ops->is_tx_pause(phl_info)) {
1074*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] sw tx pause succeed.\n");
1075*4882a593Smuzhiyun 			break;
1076*4882a593Smuzhiyun 		}
1077*4882a593Smuzhiyun 		_os_delay_us(phl_info->phl_com->drv_priv, 1);
1078*4882a593Smuzhiyun 		wait_cnt++;
1079*4882a593Smuzhiyun 	}
1080*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] stop sw tx wait_cnt %d.\n", wait_cnt);
1081*4882a593Smuzhiyun 
1082*4882a593Smuzhiyun 	/* init pre-configuration for different interfaces */
1083*4882a593Smuzhiyun 	pstatus = _init_precfg(phl_info, wow_info->sta->wrole->hw_band);
1084*4882a593Smuzhiyun 	if (RTW_PHL_STATUS_SUCCESS != pstatus)
1085*4882a593Smuzhiyun 		return pstatus;
1086*4882a593Smuzhiyun 
1087*4882a593Smuzhiyun 	/* set packet drop by setting rx filter */
1088*4882a593Smuzhiyun 	pstatus = _init_precfg_set_rxfltr(phl_info);
1089*4882a593Smuzhiyun 	if (RTW_PHL_STATUS_SUCCESS != pstatus)
1090*4882a593Smuzhiyun 		return pstatus;
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun 	/* disable ppdu sts */
1093*4882a593Smuzhiyun 	rtw_hal_ppdu_sts_cfg(phl_info->hal, wow_info->sta->wrole->hw_band, false);
1094*4882a593Smuzhiyun 
1095*4882a593Smuzhiyun 	pstatus = RTW_PHL_STATUS_SUCCESS;
1096*4882a593Smuzhiyun 
1097*4882a593Smuzhiyun 	return pstatus;
1098*4882a593Smuzhiyun }
1099*4882a593Smuzhiyun 
phl_wow_init_postcfg(struct phl_wow_info * wow_info)1100*4882a593Smuzhiyun enum rtw_phl_status phl_wow_init_postcfg(struct phl_wow_info *wow_info)
1101*4882a593Smuzhiyun {
1102*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1103*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
1104*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1105*4882a593Smuzhiyun 	struct phl_hci_trx_ops *trx_ops = phl_info->hci_trx_ops;
1106*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *sta = wow_info->sta;
1107*4882a593Smuzhiyun 	u32 wait_cnt = 0;
1108*4882a593Smuzhiyun #ifdef CONFIG_SYNC_INTERRUPT
1109*4882a593Smuzhiyun 	struct rtw_phl_evt_ops *evt_ops = &phl_info->phl_com->evt_ops;
1110*4882a593Smuzhiyun #endif /* CONFIG_SYNC_INTERRUPT */
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun 	/* disable interrupt */
1113*4882a593Smuzhiyun #ifdef CONFIG_SYNC_INTERRUPT
1114*4882a593Smuzhiyun 	evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), false);
1115*4882a593Smuzhiyun #else
1116*4882a593Smuzhiyun 	rtw_hal_disable_interrupt(phl_info->phl_com, phl_info->hal);
1117*4882a593Smuzhiyun #endif /* CONFIG_SYNC_INTERRUPT */
1118*4882a593Smuzhiyun 
1119*4882a593Smuzhiyun 	pstatus = _init_postcfg(phl_info);
1120*4882a593Smuzhiyun 	if (RTW_PHL_STATUS_SUCCESS != pstatus)
1121*4882a593Smuzhiyun 		PHL_ERR("[wow] _init_postcfg failed.\n");
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun 	/* stop sw rx */
1124*4882a593Smuzhiyun 	trx_ops->req_rx_stop(phl_info);
1125*4882a593Smuzhiyun 	pstatus = rtw_phl_start_rx_process(phl_info);
1126*4882a593Smuzhiyun 	if (RTW_PHL_STATUS_SUCCESS != pstatus)
1127*4882a593Smuzhiyun 		PHL_ERR("[wow] rtw_phl_start_rx_process failed.\n");
1128*4882a593Smuzhiyun 
1129*4882a593Smuzhiyun 	while (wait_cnt < MAX_POLLING_TRX_STOP) {
1130*4882a593Smuzhiyun 		if (trx_ops->is_rx_pause(phl_info)) {
1131*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] sw rx pause succeed.\n");
1132*4882a593Smuzhiyun 			break;
1133*4882a593Smuzhiyun 		}
1134*4882a593Smuzhiyun 		_os_delay_us(phl_info->phl_com->drv_priv, 1);
1135*4882a593Smuzhiyun 		wait_cnt++;
1136*4882a593Smuzhiyun 	}
1137*4882a593Smuzhiyun 
1138*4882a593Smuzhiyun 	if (wait_cnt == MAX_POLLING_TRX_STOP)
1139*4882a593Smuzhiyun 		PHL_WARN("[wow] sw rx pause fail.\n");
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun 	/* configure wow sleep */
1142*4882a593Smuzhiyun 	hstatus = rtw_hal_cfg_wow_sleep(phl_info->hal, true);
1143*4882a593Smuzhiyun 	if (RTW_HAL_STATUS_SUCCESS != hstatus)
1144*4882a593Smuzhiyun 		return RTW_PHL_STATUS_FAILURE;
1145*4882a593Smuzhiyun 
1146*4882a593Smuzhiyun 	/* forward rx packet to host by setting rx filter */
1147*4882a593Smuzhiyun 	pstatus = _init_postcfg_set_rxfltr(phl_info);
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun 	/* reset trx */
1150*4882a593Smuzhiyun #ifdef CONFIG_USB_HCI
1151*4882a593Smuzhiyun 	trx_ops->trx_stop(phl_info);
1152*4882a593Smuzhiyun #else
1153*4882a593Smuzhiyun 	trx_ops->trx_reset(phl_info, PHL_CTRL_TX | PHL_CTRL_RX);
1154*4882a593Smuzhiyun #endif
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	/* notify reorder sleep */
1158*4882a593Smuzhiyun 	phl_notify_reorder_sleep(phl_info, sta);
1159*4882a593Smuzhiyun 	return pstatus;
1160*4882a593Smuzhiyun }
1161*4882a593Smuzhiyun 
_phl_indic_wake_sec_upd(struct phl_wow_info * wow_info,u8 aoac_report_get_ok,u8 rx_ready)1162*4882a593Smuzhiyun static void _phl_indic_wake_sec_upd(struct phl_wow_info *wow_info, u8 aoac_report_get_ok, u8 rx_ready)
1163*4882a593Smuzhiyun {
1164*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1165*4882a593Smuzhiyun 	struct rtw_phl_evt_ops *ops = &phl_info->phl_com->evt_ops;
1166*4882a593Smuzhiyun 	void *drv_priv = phl_to_drvpriv(phl_info);
1167*4882a593Smuzhiyun 
1168*4882a593Smuzhiyun 	if (NULL != ops->wow_handle_sec_info_update)
1169*4882a593Smuzhiyun 		ops->wow_handle_sec_info_update(drv_priv, &wow_info->aoac_info, aoac_report_get_ok, rx_ready);
1170*4882a593Smuzhiyun 	else
1171*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_ERR_, "[wow] %s : evt_ops->wow_handle_sec_info_update is NULL.\n"
1172*4882a593Smuzhiyun 			, __func__);
1173*4882a593Smuzhiyun }
1174*4882a593Smuzhiyun 
_phl_handle_aoac_rpt_action(struct phl_wow_info * wow_info,bool rx_ready)1175*4882a593Smuzhiyun static void _phl_handle_aoac_rpt_action(struct phl_wow_info *wow_info, bool rx_ready)
1176*4882a593Smuzhiyun {
1177*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1178*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
1179*4882a593Smuzhiyun 	u8 aoac_report_get_ok = false;
1180*4882a593Smuzhiyun 	static u8 phase_0_ok = false;
1181*4882a593Smuzhiyun 
1182*4882a593Smuzhiyun 	if (wow_info->wow_wake_info.pairwise_sec_algo) {
1183*4882a593Smuzhiyun 		if (rx_ready == false) {
1184*4882a593Smuzhiyun 			/* phase 0 */
1185*4882a593Smuzhiyun 			hstatus = rtw_hal_get_wow_aoac_rpt(phl_info->hal, &wow_info->aoac_info, rx_ready);
1186*4882a593Smuzhiyun 			aoac_report_get_ok = (hstatus == RTW_HAL_STATUS_SUCCESS) ? true : false;
1187*4882a593Smuzhiyun 			_phl_indic_wake_sec_upd(wow_info, aoac_report_get_ok, rx_ready);
1188*4882a593Smuzhiyun 
1189*4882a593Smuzhiyun 			phase_0_ok = aoac_report_get_ok;
1190*4882a593Smuzhiyun 		}
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 		if (rx_ready == true) {
1193*4882a593Smuzhiyun 			/* phase 1 */
1194*4882a593Smuzhiyun 			if (phase_0_ok) {
1195*4882a593Smuzhiyun 				hstatus = rtw_hal_get_wow_aoac_rpt(phl_info->hal, &wow_info->aoac_info, rx_ready);
1196*4882a593Smuzhiyun 				aoac_report_get_ok = (hstatus == RTW_HAL_STATUS_SUCCESS) ? true : false;
1197*4882a593Smuzhiyun 				_phl_indic_wake_sec_upd(wow_info, aoac_report_get_ok, rx_ready);
1198*4882a593Smuzhiyun 			}
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun 			phase_0_ok = false;
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun 			wow_info->aoac_info.rpt_fail = (aoac_report_get_ok == false) ? true : false;
1203*4882a593Smuzhiyun 		}
1204*4882a593Smuzhiyun 	}
1205*4882a593Smuzhiyun }
1206*4882a593Smuzhiyun 
_phl_indic_wake_rsn(struct phl_wow_info * wow_info)1207*4882a593Smuzhiyun static enum rtw_phl_status _phl_indic_wake_rsn(struct phl_wow_info *wow_info)
1208*4882a593Smuzhiyun {
1209*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
1210*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1211*4882a593Smuzhiyun 	struct rtw_phl_evt_ops *evt_ops = &(phl_info->phl_com->evt_ops);
1212*4882a593Smuzhiyun 
1213*4882a593Smuzhiyun 	FUNCIN_WSTS(phl_status);
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 	if (NULL != evt_ops->indicate_wake_rsn) {
1216*4882a593Smuzhiyun 		evt_ops->indicate_wake_rsn(phl_to_drvpriv(phl_info), wow_info->wake_rsn);
1217*4882a593Smuzhiyun 	}
1218*4882a593Smuzhiyun 
1219*4882a593Smuzhiyun 	FUNCOUT_WSTS(phl_status);
1220*4882a593Smuzhiyun 
1221*4882a593Smuzhiyun 	return phl_status;
1222*4882a593Smuzhiyun }
1223*4882a593Smuzhiyun 
phl_wow_handle_wake_rsn(struct phl_wow_info * wow_info,u8 * reset)1224*4882a593Smuzhiyun void phl_wow_handle_wake_rsn(struct phl_wow_info *wow_info, u8 *reset)
1225*4882a593Smuzhiyun {
1226*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1227*4882a593Smuzhiyun 
1228*4882a593Smuzhiyun 	rtw_hal_get_wake_rsn(phl_info->hal, &wow_info->wake_rsn, reset);
1229*4882a593Smuzhiyun 	_phl_indic_wake_rsn(wow_info);
1230*4882a593Smuzhiyun }
1231*4882a593Smuzhiyun 
1232*4882a593Smuzhiyun #ifdef CONFIG_PCI_HCI
_deinit_precfg(struct phl_info_t * phl_info)1233*4882a593Smuzhiyun enum rtw_phl_status _deinit_precfg(struct phl_info_t *phl_info)
1234*4882a593Smuzhiyun {
1235*4882a593Smuzhiyun #ifdef DBG_RST_BDRAM_TIME
1236*4882a593Smuzhiyun 	u32 rst_bdram_start = _os_get_cur_time_ms();
1237*4882a593Smuzhiyun #endif /* DBG_RST_BDRAM_TIME */
1238*4882a593Smuzhiyun 
1239*4882a593Smuzhiyun 	rtw_hal_clear_bdidx(phl_info->hal);
1240*4882a593Smuzhiyun 
1241*4882a593Smuzhiyun #ifdef DBG_RST_BDRAM_TIME
1242*4882a593Smuzhiyun 	rst_bdram_start = _os_get_cur_time_ms();
1243*4882a593Smuzhiyun #endif
1244*4882a593Smuzhiyun 	rtw_hal_rst_bdram(phl_info->hal);
1245*4882a593Smuzhiyun 
1246*4882a593Smuzhiyun #ifdef DBG_RST_BDRAM_TIME
1247*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s : Reset bdram takes %u (ms).\n"
1248*4882a593Smuzhiyun 		, __func__, phl_get_passing_time_ms(rst_bdram_start));
1249*4882a593Smuzhiyun #endif
1250*4882a593Smuzhiyun 
1251*4882a593Smuzhiyun 	rtw_hal_cfg_txhci(phl_info->hal, true);
1252*4882a593Smuzhiyun 	rtw_hal_cfg_rxhci(phl_info->hal, true);
1253*4882a593Smuzhiyun 
1254*4882a593Smuzhiyun 	/* start tx dma */
1255*4882a593Smuzhiyun 	rtw_hal_wow_cfg_txdma(phl_info->hal, true);
1256*4882a593Smuzhiyun 
1257*4882a593Smuzhiyun 	return RTW_PHL_STATUS_SUCCESS;
1258*4882a593Smuzhiyun }
1259*4882a593Smuzhiyun #elif defined(CONFIG_USB_HCI)
_deinit_precfg(struct phl_info_t * phl_info)1260*4882a593Smuzhiyun enum rtw_phl_status _deinit_precfg(struct phl_info_t *phl_info)
1261*4882a593Smuzhiyun {
1262*4882a593Smuzhiyun 	return RTW_PHL_STATUS_SUCCESS;
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun #elif defined(CONFIG_SDIO_HCI)
_deinit_precfg(struct phl_info_t * phl_info)1265*4882a593Smuzhiyun enum rtw_phl_status _deinit_precfg(struct phl_info_t *phl_info)
1266*4882a593Smuzhiyun {
1267*4882a593Smuzhiyun 	return RTW_PHL_STATUS_SUCCESS;
1268*4882a593Smuzhiyun }
1269*4882a593Smuzhiyun #endif
1270*4882a593Smuzhiyun 
_deinit_precfg_set_intr(struct phl_info_t * phl_info)1271*4882a593Smuzhiyun void _deinit_precfg_set_intr(struct phl_info_t *phl_info)
1272*4882a593Smuzhiyun {
1273*4882a593Smuzhiyun #ifdef CONFIG_SYNC_INTERRUPT
1274*4882a593Smuzhiyun 	struct rtw_phl_evt_ops *evt_ops = &phl_info->phl_com->evt_ops;
1275*4882a593Smuzhiyun #endif /* CONFIG_SYNC_INTERRUPT */
1276*4882a593Smuzhiyun 
1277*4882a593Smuzhiyun 	rtw_hal_set_default_var(phl_info->hal, SET_DEF_RSN_WOW_RESUME_HNDL_RX);
1278*4882a593Smuzhiyun #ifdef CONFIG_SYNC_INTERRUPT
1279*4882a593Smuzhiyun 	evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), true);
1280*4882a593Smuzhiyun #else
1281*4882a593Smuzhiyun 	rtw_hal_enable_interrupt(phl_info->phl_com, phl_info->hal);
1282*4882a593Smuzhiyun #endif /* CONFIG_SYNC_INTERRUPT */
1283*4882a593Smuzhiyun }
1284*4882a593Smuzhiyun 
phl_wow_deinit_precfg(struct phl_wow_info * wow_info)1285*4882a593Smuzhiyun enum rtw_phl_status phl_wow_deinit_precfg(struct phl_wow_info *wow_info)
1286*4882a593Smuzhiyun {
1287*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
1288*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1289*4882a593Smuzhiyun 	struct phl_hci_trx_ops *trx_ops = phl_info->hci_trx_ops;
1290*4882a593Smuzhiyun 
1291*4882a593Smuzhiyun 	FUNCIN();
1292*4882a593Smuzhiyun 
1293*4882a593Smuzhiyun 	_deinit_precfg(phl_info);
1294*4882a593Smuzhiyun 
1295*4882a593Smuzhiyun 	rtw_hal_cfg_wow_sleep(phl_info->hal, false);
1296*4882a593Smuzhiyun 
1297*4882a593Smuzhiyun 	_phl_handle_aoac_rpt_action(wow_info, false);
1298*4882a593Smuzhiyun 
1299*4882a593Smuzhiyun 	/* resume sw rx */
1300*4882a593Smuzhiyun #ifdef CONFIG_USB_HCI
1301*4882a593Smuzhiyun 	trx_ops->trx_cfg(phl_info);
1302*4882a593Smuzhiyun #else
1303*4882a593Smuzhiyun 	trx_ops->trx_resume(phl_info, PHL_CTRL_RX);
1304*4882a593Smuzhiyun #endif
1305*4882a593Smuzhiyun 
1306*4882a593Smuzhiyun 	_deinit_precfg_set_intr(phl_info);
1307*4882a593Smuzhiyun 
1308*4882a593Smuzhiyun 	_phl_handle_aoac_rpt_action(wow_info, true);
1309*4882a593Smuzhiyun 
1310*4882a593Smuzhiyun 	return phl_status;
1311*4882a593Smuzhiyun }
1312*4882a593Smuzhiyun 
phl_reset_wow_info(struct phl_wow_info * wow_info)1313*4882a593Smuzhiyun void phl_reset_wow_info(struct phl_wow_info *wow_info)
1314*4882a593Smuzhiyun {
1315*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1316*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
1317*4882a593Smuzhiyun 
1318*4882a593Smuzhiyun 	wow_info->func_en = 0;
1319*4882a593Smuzhiyun 	wow_info->op_mode = RTW_WOW_OP_NONE;
1320*4882a593Smuzhiyun 	wow_info->mac_pwr = RTW_MAC_PWR_NONE;
1321*4882a593Smuzhiyun 	wow_info->ps_pwr_lvl = PS_PWR_LVL_PWRON;
1322*4882a593Smuzhiyun 
1323*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->err, 0, sizeof(struct phl_wow_error));
1324*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->keep_alive_info, 0, sizeof(struct rtw_keep_alive_info));
1325*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->disc_det_info, 0, sizeof(struct rtw_disc_det_info));
1326*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->nlo_info, 0, sizeof(struct rtw_nlo_info));
1327*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->arp_ofld_info, 0, sizeof(struct rtw_arp_ofld_info));
1328*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->ndp_ofld_info, 0, sizeof(struct rtw_ndp_ofld_info));
1329*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->gtk_ofld_info, 0, sizeof(struct rtw_gtk_ofld_info));
1330*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->realwow_info, 0, sizeof(struct rtw_realwow_info));
1331*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->wow_wake_info, 0, sizeof(struct rtw_wow_wake_info));
1332*4882a593Smuzhiyun 	_os_mem_set(d, &wow_info->aoac_info, 0, sizeof(struct rtw_aoac_report));
1333*4882a593Smuzhiyun 
1334*4882a593Smuzhiyun 	wow_info->wake_rsn = RTW_WOW_RSN_UNKNOWN;
1335*4882a593Smuzhiyun 
1336*4882a593Smuzhiyun 	/*
1337*4882a593Smuzhiyun 		&wow_info->pattern_match_info need not to be reset here.
1338*4882a593Smuzhiyun 		We expect those items will be remove triggered by core layer
1339*4882a593Smuzhiyun 	*/
1340*4882a593Smuzhiyun }
1341*4882a593Smuzhiyun 
_deinit_postcfg_set_intr(struct phl_info_t * phl_info)1342*4882a593Smuzhiyun void _deinit_postcfg_set_intr(struct phl_info_t *phl_info)
1343*4882a593Smuzhiyun {
1344*4882a593Smuzhiyun #ifdef CONFIG_SYNC_INTERRUPT
1345*4882a593Smuzhiyun 	struct rtw_phl_evt_ops *evt_ops = &phl_info->phl_com->evt_ops;
1346*4882a593Smuzhiyun #endif /* CONFIG_SYNC_INTERRUPT */
1347*4882a593Smuzhiyun 
1348*4882a593Smuzhiyun #ifdef CONFIG_SYNC_INTERRUPT
1349*4882a593Smuzhiyun 	evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), false);
1350*4882a593Smuzhiyun #else
1351*4882a593Smuzhiyun 	rtw_hal_disable_interrupt(phl_info->phl_com, phl_info->hal);
1352*4882a593Smuzhiyun #endif /* CONFIG_SYNC_INTERRUPT */
1353*4882a593Smuzhiyun 	rtw_hal_set_default_var(phl_info->hal, SET_DEF_RSN_WOW_RESUME_DONE);
1354*4882a593Smuzhiyun #ifdef CONFIG_SYNC_INTERRUPT
1355*4882a593Smuzhiyun 	evt_ops->set_interrupt_caps(phl_to_drvpriv(phl_info), true);
1356*4882a593Smuzhiyun #else
1357*4882a593Smuzhiyun 	rtw_hal_enable_interrupt(phl_info->phl_com, phl_info->hal);
1358*4882a593Smuzhiyun #endif /* CONFIG_SYNC_INTERRUPT */
1359*4882a593Smuzhiyun }
1360*4882a593Smuzhiyun 
phl_wow_deinit_postcfg(struct phl_wow_info * wow_info)1361*4882a593Smuzhiyun enum rtw_phl_status phl_wow_deinit_postcfg(struct phl_wow_info *wow_info)
1362*4882a593Smuzhiyun {
1363*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
1364*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1365*4882a593Smuzhiyun 	struct phl_hci_trx_ops *trx_ops = phl_info->hci_trx_ops;
1366*4882a593Smuzhiyun 
1367*4882a593Smuzhiyun 	FUNCIN();
1368*4882a593Smuzhiyun 
1369*4882a593Smuzhiyun 	/* resume sw tx */
1370*4882a593Smuzhiyun 	trx_ops->trx_resume(phl_info, PHL_CTRL_TX);
1371*4882a593Smuzhiyun 	/* enable ppdu sts */
1372*4882a593Smuzhiyun 	rtw_hal_ppdu_sts_cfg(phl_info->hal, wow_info->sta->wrole->hw_band, true);
1373*4882a593Smuzhiyun 
1374*4882a593Smuzhiyun 	_deinit_postcfg_set_intr(phl_info);
1375*4882a593Smuzhiyun 
1376*4882a593Smuzhiyun 	return phl_status;
1377*4882a593Smuzhiyun }
1378*4882a593Smuzhiyun 
_phl_wow_cfg_pkt_ofld(struct phl_wow_info * wow_info,u8 pkt_type,u8 * pkt_id,void * buf)1379*4882a593Smuzhiyun enum rtw_phl_status _phl_wow_cfg_pkt_ofld(struct phl_wow_info *wow_info, u8 pkt_type, u8 *pkt_id, void *buf)
1380*4882a593Smuzhiyun {
1381*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1382*4882a593Smuzhiyun 	u16 macid = wow_info->sta->macid;
1383*4882a593Smuzhiyun 	u32 *token;
1384*4882a593Smuzhiyun 
1385*4882a593Smuzhiyun 	switch(pkt_type) {
1386*4882a593Smuzhiyun 	case PKT_TYPE_NULL_DATA:
1387*4882a593Smuzhiyun 		token = &wow_info->null_pkt_token;
1388*4882a593Smuzhiyun 		break;
1389*4882a593Smuzhiyun 	case PKT_TYPE_ARP_RSP:
1390*4882a593Smuzhiyun 		token = &wow_info->arp_pkt_token;
1391*4882a593Smuzhiyun 		break;
1392*4882a593Smuzhiyun 	case PKT_TYPE_NDP:
1393*4882a593Smuzhiyun 		token = &wow_info->ndp_pkt_token;
1394*4882a593Smuzhiyun 		break;
1395*4882a593Smuzhiyun 	case PKT_TYPE_EAPOL_KEY:
1396*4882a593Smuzhiyun 		token = &wow_info->eapol_key_pkt_token;
1397*4882a593Smuzhiyun 		break;
1398*4882a593Smuzhiyun 	case PKT_TYPE_SA_QUERY:
1399*4882a593Smuzhiyun 		token = &wow_info->sa_query_pkt_token;
1400*4882a593Smuzhiyun 		break;
1401*4882a593Smuzhiyun 	case PKT_TYPE_REALWOW_KAPKT:
1402*4882a593Smuzhiyun 		token = &wow_info->kapkt_pkt_token;
1403*4882a593Smuzhiyun 		break;
1404*4882a593Smuzhiyun 	case PKT_TYPE_REALWOW_ACK:
1405*4882a593Smuzhiyun 		token = &wow_info->ack_pkt_token;
1406*4882a593Smuzhiyun 		break;
1407*4882a593Smuzhiyun 	case PKT_TYPE_REALWOW_WP:
1408*4882a593Smuzhiyun 		token = &wow_info->wp_token;
1409*4882a593Smuzhiyun 		break;
1410*4882a593Smuzhiyun 	case PKT_TYPE_PROBE_REQ:
1411*4882a593Smuzhiyun 		token = &wow_info->probe_req_pkt_token;
1412*4882a593Smuzhiyun 		break;
1413*4882a593Smuzhiyun 	default:
1414*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_WOW, _PHL_ERR_, "[wow] %s : unknown pkt_type %d.\n"
1415*4882a593Smuzhiyun 			, __func__, pkt_type);
1416*4882a593Smuzhiyun 		return pstatus;
1417*4882a593Smuzhiyun 	}
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun 	pstatus = RTW_PHL_PKT_OFLD_REQ(wow_info->phl_info, macid, pkt_type, token, buf);
1420*4882a593Smuzhiyun 
1421*4882a593Smuzhiyun 	if (pstatus == RTW_PHL_STATUS_SUCCESS)
1422*4882a593Smuzhiyun 		*pkt_id = phl_pkt_ofld_get_id(wow_info->phl_info, macid, pkt_type);
1423*4882a593Smuzhiyun 
1424*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s : pkt_type %s, pkt_id %d, token %u, status(%u)\n",
1425*4882a593Smuzhiyun 		__func__, phl_get_pkt_ofld_str(pkt_type), *pkt_id, *token, pstatus);
1426*4882a593Smuzhiyun 
1427*4882a593Smuzhiyun 	return pstatus;
1428*4882a593Smuzhiyun }
1429*4882a593Smuzhiyun 
_phl_wow_cfg_nlo(struct phl_wow_info * wow_info)1430*4882a593Smuzhiyun static enum rtw_phl_status _phl_wow_cfg_nlo(struct phl_wow_info *wow_info)
1431*4882a593Smuzhiyun {
1432*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1433*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
1434*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1435*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *sta = wow_info->sta;
1436*4882a593Smuzhiyun 
1437*4882a593Smuzhiyun 	do {
1438*4882a593Smuzhiyun 
1439*4882a593Smuzhiyun 		/* always stop first */
1440*4882a593Smuzhiyun 		hstatus = rtw_hal_wow_cfg_nlo(phl_info->hal, SCAN_OFLD_OP_STOP,
1441*4882a593Smuzhiyun 					sta->macid, sta->wrole->hw_band, sta->wrole->hw_port,
1442*4882a593Smuzhiyun 					&wow_info->nlo_info);
1443*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1444*4882a593Smuzhiyun 			pstatus = RTW_PHL_STATUS_FAILURE;
1445*4882a593Smuzhiyun 			break;
1446*4882a593Smuzhiyun 		}
1447*4882a593Smuzhiyun 
1448*4882a593Smuzhiyun 		/* construct channel list and offload to fw */
1449*4882a593Smuzhiyun 		hstatus = rtw_hal_wow_cfg_nlo_chnl_list(phl_info->hal,
1450*4882a593Smuzhiyun 					&wow_info->nlo_info);
1451*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1452*4882a593Smuzhiyun 			pstatus = RTW_PHL_STATUS_FAILURE;
1453*4882a593Smuzhiyun 			break;
1454*4882a593Smuzhiyun 		}
1455*4882a593Smuzhiyun 
1456*4882a593Smuzhiyun 		hstatus = rtw_hal_wow_cfg_nlo(phl_info->hal, SCAN_OFLD_OP_START,
1457*4882a593Smuzhiyun 					sta->macid, sta->wrole->hw_band, sta->wrole->hw_port,
1458*4882a593Smuzhiyun 					&wow_info->nlo_info);
1459*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1460*4882a593Smuzhiyun 			pstatus = RTW_PHL_STATUS_FAILURE;
1461*4882a593Smuzhiyun 			break;
1462*4882a593Smuzhiyun 		}
1463*4882a593Smuzhiyun 
1464*4882a593Smuzhiyun 	} while (0);
1465*4882a593Smuzhiyun 
1466*4882a593Smuzhiyun 	return pstatus;
1467*4882a593Smuzhiyun }
1468*4882a593Smuzhiyun 
phl_wow_func_en(struct phl_wow_info * wow_info)1469*4882a593Smuzhiyun enum rtw_phl_status phl_wow_func_en(struct phl_wow_info *wow_info)
1470*4882a593Smuzhiyun {
1471*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1472*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
1473*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1474*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *sta = wow_info->sta;
1475*4882a593Smuzhiyun 	struct rtw_pkt_ofld_null_info null_info = {0};
1476*4882a593Smuzhiyun 	struct rtw_pkt_ofld_arp_rsp_info arp_rsp_info = {0};
1477*4882a593Smuzhiyun 	struct rtw_pkt_ofld_na_info na_info = {0};
1478*4882a593Smuzhiyun 	struct rtw_pkt_ofld_eapol_key_info eapol_key_info = {0};
1479*4882a593Smuzhiyun 	struct rtw_pkt_ofld_sa_query_info sa_query_info = {0};
1480*4882a593Smuzhiyun 	struct rtw_pkt_ofld_realwow_kapkt_info kapkt_info = {0};
1481*4882a593Smuzhiyun 	struct rtw_pkt_ofld_realwow_ack_info ack_info = {0};
1482*4882a593Smuzhiyun 	struct rtw_pkt_ofld_realwow_wp_info wakeup_info = {0};
1483*4882a593Smuzhiyun 	struct rtw_pkt_ofld_probe_req_info probe_req_info = {0};
1484*4882a593Smuzhiyun 	struct rtw_hal_wow_cfg cfg;
1485*4882a593Smuzhiyun 
1486*4882a593Smuzhiyun 	FUNCIN();
1487*4882a593Smuzhiyun 
1488*4882a593Smuzhiyun 	if (!wow_info->wow_wake_info.wow_en) {
1489*4882a593Smuzhiyun 		PHL_WARN("%s : wow func is not enabled!\n", __func__);
1490*4882a593Smuzhiyun 		return pstatus;
1491*4882a593Smuzhiyun 	}
1492*4882a593Smuzhiyun 
1493*4882a593Smuzhiyun 	do {
1494*4882a593Smuzhiyun 
1495*4882a593Smuzhiyun 		hstatus = rtw_hal_reset_pkt_ofld_state(phl_info->hal);
1496*4882a593Smuzhiyun 
1497*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1498*4882a593Smuzhiyun 			pstatus = RTW_PHL_STATUS_FAILURE;
1499*4882a593Smuzhiyun 			break;
1500*4882a593Smuzhiyun 		}
1501*4882a593Smuzhiyun 
1502*4882a593Smuzhiyun 		if (wow_info->keep_alive_info.keep_alive_en) {
1503*4882a593Smuzhiyun 
1504*4882a593Smuzhiyun 			_phl_cfg_pkt_ofld_null_info(wow_info, sta, &null_info);
1505*4882a593Smuzhiyun 
1506*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1507*4882a593Smuzhiyun 					PKT_TYPE_NULL_DATA,
1508*4882a593Smuzhiyun 					&wow_info->keep_alive_info.null_pkt_id,
1509*4882a593Smuzhiyun 					(void *)&null_info);
1510*4882a593Smuzhiyun 
1511*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1512*4882a593Smuzhiyun 				break;
1513*4882a593Smuzhiyun 		}
1514*4882a593Smuzhiyun 
1515*4882a593Smuzhiyun 		if (wow_info->arp_ofld_info.arp_en) {
1516*4882a593Smuzhiyun 
1517*4882a593Smuzhiyun 			_phl_cfg_pkt_ofld_arp_rsp_info(wow_info, sta, &arp_rsp_info);
1518*4882a593Smuzhiyun 
1519*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1520*4882a593Smuzhiyun 					PKT_TYPE_ARP_RSP,
1521*4882a593Smuzhiyun 					&wow_info->arp_ofld_info.arp_rsp_id,
1522*4882a593Smuzhiyun 					(void *)&arp_rsp_info);
1523*4882a593Smuzhiyun 
1524*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1525*4882a593Smuzhiyun 				break;
1526*4882a593Smuzhiyun 		}
1527*4882a593Smuzhiyun 
1528*4882a593Smuzhiyun 		if (wow_info->ndp_ofld_info.ndp_en) {
1529*4882a593Smuzhiyun 
1530*4882a593Smuzhiyun 			_phl_cfg_pkt_ofld_na_info(wow_info, sta, &na_info);
1531*4882a593Smuzhiyun 
1532*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1533*4882a593Smuzhiyun 					PKT_TYPE_NDP, &wow_info->ndp_ofld_info.ndp_id,
1534*4882a593Smuzhiyun 					(void *)&na_info);
1535*4882a593Smuzhiyun 
1536*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1537*4882a593Smuzhiyun 				break;
1538*4882a593Smuzhiyun 		}
1539*4882a593Smuzhiyun 
1540*4882a593Smuzhiyun 		if (wow_info->gtk_ofld_info.gtk_en) {
1541*4882a593Smuzhiyun 			_phl_cfg_pkt_ofld_eapol_key_info(wow_info, sta, &eapol_key_info);
1542*4882a593Smuzhiyun 
1543*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1544*4882a593Smuzhiyun 					PKT_TYPE_EAPOL_KEY, &wow_info->gtk_ofld_info.gtk_rsp_id,
1545*4882a593Smuzhiyun 					(void *)&eapol_key_info);
1546*4882a593Smuzhiyun 
1547*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1548*4882a593Smuzhiyun 				break;
1549*4882a593Smuzhiyun 
1550*4882a593Smuzhiyun 			if (wow_info->gtk_ofld_info.ieee80211w_en) {
1551*4882a593Smuzhiyun 				_phl_cfg_pkt_ofld_sa_query_info(wow_info, sta, &sa_query_info);
1552*4882a593Smuzhiyun 
1553*4882a593Smuzhiyun 				pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1554*4882a593Smuzhiyun 					PKT_TYPE_SA_QUERY, &wow_info->gtk_ofld_info.sa_query_id,
1555*4882a593Smuzhiyun 					(void *)&sa_query_info);
1556*4882a593Smuzhiyun 
1557*4882a593Smuzhiyun 				if (pstatus != RTW_PHL_STATUS_SUCCESS)
1558*4882a593Smuzhiyun 					break;
1559*4882a593Smuzhiyun 			}
1560*4882a593Smuzhiyun 		}
1561*4882a593Smuzhiyun 
1562*4882a593Smuzhiyun 		if (wow_info->realwow_info.realwow_en) {
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 			/* realwow keep alive */
1565*4882a593Smuzhiyun 			_phl_cfg_pkt_ofld_realwow_kapkt_info(wow_info, sta, &kapkt_info);
1566*4882a593Smuzhiyun 
1567*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1568*4882a593Smuzhiyun 					PKT_TYPE_REALWOW_KAPKT,
1569*4882a593Smuzhiyun 					&wow_info->realwow_info.keepalive_id,
1570*4882a593Smuzhiyun 					(void *)&kapkt_info);
1571*4882a593Smuzhiyun 
1572*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1573*4882a593Smuzhiyun 				break;
1574*4882a593Smuzhiyun 
1575*4882a593Smuzhiyun 			/* realwow ack */
1576*4882a593Smuzhiyun 			_phl_cfg_pkt_ofld_realwow_ack_info(wow_info, &ack_info);
1577*4882a593Smuzhiyun 
1578*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1579*4882a593Smuzhiyun 					PKT_TYPE_REALWOW_ACK,
1580*4882a593Smuzhiyun 					&wow_info->realwow_info.ack_pattern_id,
1581*4882a593Smuzhiyun 					(void *)&ack_info);
1582*4882a593Smuzhiyun 
1583*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1584*4882a593Smuzhiyun 				break;
1585*4882a593Smuzhiyun 
1586*4882a593Smuzhiyun 			/* realwow wake up */
1587*4882a593Smuzhiyun 			_phl_cfg_pkt_ofld_realwow_wp_info(wow_info, &wakeup_info);
1588*4882a593Smuzhiyun 
1589*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1590*4882a593Smuzhiyun 					PKT_TYPE_REALWOW_WP,
1591*4882a593Smuzhiyun 					&wow_info->realwow_info.wakeup_pattern_id,
1592*4882a593Smuzhiyun 					(void *)&wakeup_info);
1593*4882a593Smuzhiyun 
1594*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1595*4882a593Smuzhiyun 				break;
1596*4882a593Smuzhiyun 		}
1597*4882a593Smuzhiyun 
1598*4882a593Smuzhiyun 		if (wow_info->nlo_info.nlo_en) {
1599*4882a593Smuzhiyun 
1600*4882a593Smuzhiyun 			_phl_cfg_pkt_ofld_probe_req_info(wow_info, sta, &probe_req_info);
1601*4882a593Smuzhiyun 
1602*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_pkt_ofld(wow_info,
1603*4882a593Smuzhiyun 					PKT_TYPE_PROBE_REQ,
1604*4882a593Smuzhiyun 					&wow_info->nlo_info.probe_req_id,
1605*4882a593Smuzhiyun 					(void *)&probe_req_info);
1606*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1607*4882a593Smuzhiyun 				break;
1608*4882a593Smuzhiyun 
1609*4882a593Smuzhiyun 			pstatus = _phl_wow_cfg_nlo(wow_info);
1610*4882a593Smuzhiyun 			if (pstatus != RTW_PHL_STATUS_SUCCESS)
1611*4882a593Smuzhiyun 				break;
1612*4882a593Smuzhiyun 		}
1613*4882a593Smuzhiyun 
1614*4882a593Smuzhiyun 		cfg.keep_alive_cfg = &wow_info->keep_alive_info;
1615*4882a593Smuzhiyun 		cfg.disc_det_cfg = &wow_info->disc_det_info;
1616*4882a593Smuzhiyun 		cfg.nlo_cfg = &wow_info->nlo_info;
1617*4882a593Smuzhiyun 		cfg.arp_ofld_cfg = &wow_info->arp_ofld_info;
1618*4882a593Smuzhiyun 		cfg.ndp_ofld_cfg = &wow_info->ndp_ofld_info;
1619*4882a593Smuzhiyun 		cfg.gtk_ofld_cfg = &wow_info->gtk_ofld_info;
1620*4882a593Smuzhiyun 		cfg.realwow_cfg = &wow_info->realwow_info;
1621*4882a593Smuzhiyun 		cfg.wow_wake_cfg = &wow_info->wow_wake_info;
1622*4882a593Smuzhiyun 		cfg.pattern_match_info = &wow_info->pattern_match_info;
1623*4882a593Smuzhiyun 		cfg.wow_gpio = &wow_info->wow_gpio;
1624*4882a593Smuzhiyun 
1625*4882a593Smuzhiyun 		hstatus = rtw_hal_wow_func_en(phl_info->phl_com, phl_info->hal, sta->macid, &cfg);
1626*4882a593Smuzhiyun 		if (hstatus != RTW_HAL_STATUS_SUCCESS) {
1627*4882a593Smuzhiyun 			PHL_ERR("rtw_hal_wow_func_en fail, status (%u)\n", hstatus);
1628*4882a593Smuzhiyun 			pstatus = RTW_PHL_STATUS_FAILURE;
1629*4882a593Smuzhiyun 			break;
1630*4882a593Smuzhiyun 		}
1631*4882a593Smuzhiyun 
1632*4882a593Smuzhiyun 		hstatus = rtw_hal_wow_func_start(phl_info->phl_com, phl_info->hal, sta->macid, &cfg);
1633*4882a593Smuzhiyun 		if (hstatus != RTW_HAL_STATUS_SUCCESS) {
1634*4882a593Smuzhiyun 			PHL_ERR("rtw_hal_wow_func_start fail, status (%u)\n", hstatus);
1635*4882a593Smuzhiyun 			pstatus = RTW_PHL_STATUS_FAILURE;
1636*4882a593Smuzhiyun 			break;
1637*4882a593Smuzhiyun 		}
1638*4882a593Smuzhiyun 
1639*4882a593Smuzhiyun 		wow_info->func_en = true;
1640*4882a593Smuzhiyun 		pstatus = RTW_PHL_STATUS_SUCCESS;
1641*4882a593Smuzhiyun 
1642*4882a593Smuzhiyun 	} while (0);
1643*4882a593Smuzhiyun 
1644*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s status (%u).\n", __func__, pstatus);
1645*4882a593Smuzhiyun 
1646*4882a593Smuzhiyun 	return pstatus;
1647*4882a593Smuzhiyun }
1648*4882a593Smuzhiyun 
phl_wow_func_dis(struct phl_wow_info * wow_info)1649*4882a593Smuzhiyun void phl_wow_func_dis(struct phl_wow_info *wow_info)
1650*4882a593Smuzhiyun {
1651*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1652*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
1653*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1654*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *sta = wow_info->sta;
1655*4882a593Smuzhiyun 	struct rtw_hal_wow_cfg cfg;
1656*4882a593Smuzhiyun 
1657*4882a593Smuzhiyun 	if (!wow_info->wow_wake_info.wow_en) {
1658*4882a593Smuzhiyun 		PHL_WARN("%s : wow func is not enabled!\n", __func__);
1659*4882a593Smuzhiyun 		return;
1660*4882a593Smuzhiyun 	}
1661*4882a593Smuzhiyun 
1662*4882a593Smuzhiyun 	cfg.keep_alive_cfg = &wow_info->keep_alive_info;
1663*4882a593Smuzhiyun 	cfg.disc_det_cfg = &wow_info->disc_det_info;
1664*4882a593Smuzhiyun 	cfg.nlo_cfg = &wow_info->nlo_info;
1665*4882a593Smuzhiyun 	cfg.arp_ofld_cfg = &wow_info->arp_ofld_info;
1666*4882a593Smuzhiyun 	cfg.ndp_ofld_cfg = &wow_info->ndp_ofld_info;
1667*4882a593Smuzhiyun 	cfg.gtk_ofld_cfg = &wow_info->gtk_ofld_info;
1668*4882a593Smuzhiyun 	cfg.realwow_cfg = &wow_info->realwow_info;
1669*4882a593Smuzhiyun 	cfg.wow_wake_cfg = &wow_info->wow_wake_info;
1670*4882a593Smuzhiyun 	cfg.pattern_match_info = &wow_info->pattern_match_info;
1671*4882a593Smuzhiyun 	cfg.wow_gpio = &wow_info->wow_gpio;
1672*4882a593Smuzhiyun 
1673*4882a593Smuzhiyun 	hstatus = rtw_hal_wow_func_dis(phl_info->phl_com, phl_info->hal, sta->macid,
1674*4882a593Smuzhiyun 		&cfg);
1675*4882a593Smuzhiyun 	if (hstatus != RTW_HAL_STATUS_SUCCESS)
1676*4882a593Smuzhiyun 		PHL_ERR("rtw_hal_wow_func_dis fail, status (%u)\n", hstatus);
1677*4882a593Smuzhiyun 
1678*4882a593Smuzhiyun 	if (wow_info->keep_alive_info.keep_alive_en) {
1679*4882a593Smuzhiyun 		phl_pkt_ofld_cancel(phl_info, sta->macid,
1680*4882a593Smuzhiyun 							PKT_TYPE_NULL_DATA, &wow_info->null_pkt_token);
1681*4882a593Smuzhiyun 	}
1682*4882a593Smuzhiyun 
1683*4882a593Smuzhiyun 	if (wow_info->arp_ofld_info.arp_en) {
1684*4882a593Smuzhiyun 		phl_pkt_ofld_cancel(phl_info, sta->macid,
1685*4882a593Smuzhiyun 							PKT_TYPE_ARP_RSP, &wow_info->arp_pkt_token);
1686*4882a593Smuzhiyun 	}
1687*4882a593Smuzhiyun 
1688*4882a593Smuzhiyun 	if (wow_info->ndp_ofld_info.ndp_en) {
1689*4882a593Smuzhiyun 		phl_pkt_ofld_cancel(phl_info, sta->macid,
1690*4882a593Smuzhiyun 							PKT_TYPE_NDP, &wow_info->ndp_pkt_token);
1691*4882a593Smuzhiyun 	}
1692*4882a593Smuzhiyun 
1693*4882a593Smuzhiyun 	if (wow_info->gtk_ofld_info.gtk_en) {
1694*4882a593Smuzhiyun 		phl_pkt_ofld_cancel(phl_info, sta->macid,
1695*4882a593Smuzhiyun 							PKT_TYPE_EAPOL_KEY, &wow_info->eapol_key_pkt_token);
1696*4882a593Smuzhiyun 		if (wow_info->gtk_ofld_info.ieee80211w_en) {
1697*4882a593Smuzhiyun 			phl_pkt_ofld_cancel(phl_info, sta->macid,
1698*4882a593Smuzhiyun 								PKT_TYPE_SA_QUERY, &wow_info->sa_query_pkt_token);
1699*4882a593Smuzhiyun 		}
1700*4882a593Smuzhiyun 	}
1701*4882a593Smuzhiyun 
1702*4882a593Smuzhiyun 	if (wow_info->realwow_info.realwow_en) {
1703*4882a593Smuzhiyun 		phl_pkt_ofld_cancel(phl_info, sta->macid,
1704*4882a593Smuzhiyun 					PKT_TYPE_REALWOW_KAPKT, &wow_info->kapkt_pkt_token);
1705*4882a593Smuzhiyun 		phl_pkt_ofld_cancel(phl_info, sta->macid,
1706*4882a593Smuzhiyun 					PKT_TYPE_REALWOW_ACK, &wow_info->ack_pkt_token);
1707*4882a593Smuzhiyun 		phl_pkt_ofld_cancel(phl_info, sta->macid,
1708*4882a593Smuzhiyun 					PKT_TYPE_REALWOW_WP, &wow_info->wp_token);
1709*4882a593Smuzhiyun 	}
1710*4882a593Smuzhiyun 
1711*4882a593Smuzhiyun 	if (wow_info->nlo_info.nlo_en) {
1712*4882a593Smuzhiyun 
1713*4882a593Smuzhiyun 		pstatus = phl_pkt_ofld_cancel(phl_info, sta->macid,
1714*4882a593Smuzhiyun 					PKT_TYPE_PROBE_REQ, &wow_info->probe_req_pkt_token);
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun 		hstatus = rtw_hal_wow_cfg_nlo(phl_info->hal, SCAN_OFLD_OP_STOP,
1717*4882a593Smuzhiyun 						sta->macid, sta->wrole->hw_band, sta->wrole->hw_port,
1718*4882a593Smuzhiyun 						&wow_info->nlo_info);
1719*4882a593Smuzhiyun 	}
1720*4882a593Smuzhiyun 
1721*4882a593Smuzhiyun 
1722*4882a593Smuzhiyun 	hstatus = rtw_hal_wow_func_stop(phl_info->phl_com, phl_info->hal, sta->macid);
1723*4882a593Smuzhiyun 	if (hstatus != RTW_HAL_STATUS_SUCCESS)
1724*4882a593Smuzhiyun 		PHL_ERR("rtw_hal_wow_func_stop fail, status (%u)\n", hstatus);
1725*4882a593Smuzhiyun 
1726*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s done.\n", __func__);
1727*4882a593Smuzhiyun }
1728*4882a593Smuzhiyun 
phl_wow_decide_op_mode(struct phl_wow_info * wow_info,struct rtw_phl_stainfo_t * sta)1729*4882a593Smuzhiyun void phl_wow_decide_op_mode(struct phl_wow_info *wow_info, struct rtw_phl_stainfo_t *sta)
1730*4882a593Smuzhiyun {
1731*4882a593Smuzhiyun 	u8 nlo_en = wow_info->nlo_info.nlo_en;
1732*4882a593Smuzhiyun 	enum mlme_state mstat = sta->wrole->mstate;
1733*4882a593Smuzhiyun 	struct rtw_ps_cap_t *ps_cap = _get_ps_cap(wow_info->phl_info);
1734*4882a593Smuzhiyun 
1735*4882a593Smuzhiyun 	wow_info->sta = sta;
1736*4882a593Smuzhiyun 	wow_info->ps_pwr_lvl = PS_PWR_LVL_PWRON;
1737*4882a593Smuzhiyun 
1738*4882a593Smuzhiyun 	if (mstat == MLME_NO_LINK && !nlo_en) {
1739*4882a593Smuzhiyun 		wow_info->op_mode = RTW_WOW_OP_PWR_DOWN;
1740*4882a593Smuzhiyun 	} else if (mstat == MLME_NO_LINK && nlo_en) {
1741*4882a593Smuzhiyun 		wow_info->op_mode = RTW_WOW_OP_DISCONNECT_STBY;
1742*4882a593Smuzhiyun 		#ifdef CONFIG_POWER_SAVE
1743*4882a593Smuzhiyun 		if (ps_cap->ips_wow_en)
1744*4882a593Smuzhiyun 			wow_info->ps_pwr_lvl = phl_ps_judge_pwr_lvl(ps_cap->ips_wow_cap, PS_MODE_IPS, true);
1745*4882a593Smuzhiyun 		#endif
1746*4882a593Smuzhiyun 	} else if (mstat == MLME_LINKED) {
1747*4882a593Smuzhiyun 		wow_info->op_mode = RTW_WOW_OP_CONNECT_STBY;
1748*4882a593Smuzhiyun 		#ifdef CONFIG_POWER_SAVE
1749*4882a593Smuzhiyun 		if (ps_cap->lps_wow_en)
1750*4882a593Smuzhiyun 			wow_info->ps_pwr_lvl = phl_ps_judge_pwr_lvl(ps_cap->lps_wow_cap, PS_MODE_LPS, true);
1751*4882a593Smuzhiyun 		#endif
1752*4882a593Smuzhiyun 	} else {
1753*4882a593Smuzhiyun 		wow_info->op_mode = RTW_WOW_OP_PWR_DOWN;
1754*4882a593Smuzhiyun 	}
1755*4882a593Smuzhiyun 
1756*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s op mode set to %d, pwr lvl %s.\n.",
1757*4882a593Smuzhiyun 			  __func__, wow_info->op_mode, phl_ps_pwr_lvl_to_str(wow_info->ps_pwr_lvl));
1758*4882a593Smuzhiyun }
1759*4882a593Smuzhiyun 
1760*4882a593Smuzhiyun #ifdef CONFIG_POWER_SAVE
1761*4882a593Smuzhiyun /**
1762*4882a593Smuzhiyun  * phl_wow_ps_proto_cfg - set the ps protocol under wowlan
1763*4882a593Smuzhiyun  * @wow_info: see struct phl_wow_info
1764*4882a593Smuzhiyun  * @enter_ps: enter lps or not
1765*4882a593Smuzhiyun  *
1766*4882a593Smuzhiyun  * return enum rtw_phl_status
1767*4882a593Smuzhiyun  */
phl_wow_ps_proto_cfg(struct phl_wow_info * wow_info,bool enter_ps)1768*4882a593Smuzhiyun enum rtw_phl_status phl_wow_ps_proto_cfg(struct phl_wow_info *wow_info, bool enter_ps)
1769*4882a593Smuzhiyun {
1770*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1771*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1772*4882a593Smuzhiyun 	struct ps_cfg cfg = {0};
1773*4882a593Smuzhiyun 	struct rtw_ps_cap_t *ps_cap = _get_ps_cap(phl_info);
1774*4882a593Smuzhiyun 
1775*4882a593Smuzhiyun 	if (wow_info->op_mode == RTW_WOW_OP_DISCONNECT_STBY) {
1776*4882a593Smuzhiyun 		/* IPS */
1777*4882a593Smuzhiyun 		if (ps_cap->ips_wow_en) {
1778*4882a593Smuzhiyun 			cfg.macid = wow_info->sta->macid;
1779*4882a593Smuzhiyun 			pstatus = phl_ps_ips_cfg(phl_info, &cfg, enter_ps);
1780*4882a593Smuzhiyun 		}
1781*4882a593Smuzhiyun 	} else if (wow_info->op_mode == RTW_WOW_OP_CONNECT_STBY) {
1782*4882a593Smuzhiyun 		/* LPS */
1783*4882a593Smuzhiyun 		if (ps_cap->lps_wow_en) {
1784*4882a593Smuzhiyun 			cfg.macid = wow_info->sta->macid;
1785*4882a593Smuzhiyun 			cfg.awake_interval = ps_cap->lps_wow_awake_interval;
1786*4882a593Smuzhiyun 			cfg.listen_bcn_mode = ps_cap->lps_wow_listen_bcn_mode;
1787*4882a593Smuzhiyun 			cfg.smart_ps_mode = ps_cap->lps_wow_smart_ps_mode;
1788*4882a593Smuzhiyun 			pstatus = phl_ps_lps_cfg(phl_info, &cfg, enter_ps);
1789*4882a593Smuzhiyun 		}
1790*4882a593Smuzhiyun 	} else {
1791*4882a593Smuzhiyun 		PHL_ERR("%s : undefined wowlan op mode.\n", __func__);
1792*4882a593Smuzhiyun 	}
1793*4882a593Smuzhiyun 
1794*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s : op mode %d, enter ps %d, pwr lvl %s.\n.",
1795*4882a593Smuzhiyun 			  __func__, wow_info->op_mode, enter_ps, phl_ps_pwr_lvl_to_str(wow_info->ps_pwr_lvl));
1796*4882a593Smuzhiyun 
1797*4882a593Smuzhiyun 	return pstatus;
1798*4882a593Smuzhiyun }
1799*4882a593Smuzhiyun 
1800*4882a593Smuzhiyun /**
1801*4882a593Smuzhiyun  * phl_wow_ps_pwr_ntfy - notify the power level when enter low power
1802*4882a593Smuzhiyun  * @wow_info: see struct phl_wow_info
1803*4882a593Smuzhiyun  * @enter_ps: enter low power or not
1804*4882a593Smuzhiyun  *
1805*4882a593Smuzhiyun  */
phl_wow_ps_pwr_ntfy(struct phl_wow_info * wow_info,bool enter_ps)1806*4882a593Smuzhiyun void phl_wow_ps_pwr_ntfy(struct phl_wow_info *wow_info, bool enter_ps)
1807*4882a593Smuzhiyun {
1808*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1809*4882a593Smuzhiyun 
1810*4882a593Smuzhiyun 	if (wow_info->ps_pwr_lvl == PS_PWR_LVL_PWRON)
1811*4882a593Smuzhiyun 		return;
1812*4882a593Smuzhiyun 
1813*4882a593Smuzhiyun 	if (wow_info->op_mode == RTW_WOW_OP_DISCONNECT_STBY) {
1814*4882a593Smuzhiyun 		/* IPS */
1815*4882a593Smuzhiyun 	} else if (wow_info->op_mode == RTW_WOW_OP_CONNECT_STBY) {
1816*4882a593Smuzhiyun 		#ifdef CONFIG_BTCOEX
1817*4882a593Smuzhiyun 		rtw_hal_btc_radio_state_ntfy(phl_info->hal, (enter_ps == true ?
1818*4882a593Smuzhiyun 							BTC_RFCTRL_FW_CTRL : BTC_RFCTRL_WL_ON));
1819*4882a593Smuzhiyun 		#endif
1820*4882a593Smuzhiyun 	} else {
1821*4882a593Smuzhiyun 		PHL_ERR("%s : undefined wowlan op mode.\n", __func__);
1822*4882a593Smuzhiyun 	}
1823*4882a593Smuzhiyun 
1824*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s : op mode %d, enter ps %d, pwr lvl %s.\n.",
1825*4882a593Smuzhiyun 			  __func__, wow_info->op_mode, enter_ps, phl_ps_pwr_lvl_to_str(wow_info->ps_pwr_lvl));
1826*4882a593Smuzhiyun }
1827*4882a593Smuzhiyun 
1828*4882a593Smuzhiyun 
1829*4882a593Smuzhiyun /**
1830*4882a593Smuzhiyun  * phl_wow_ps_pwr_cfg - set the low power level under wowlan
1831*4882a593Smuzhiyun  * @wow_info: see struct phl_wow_info
1832*4882a593Smuzhiyun  * @enter_ps: enter low power or not
1833*4882a593Smuzhiyun  *
1834*4882a593Smuzhiyun  * returns enum rtw_phl_status
1835*4882a593Smuzhiyun  */
phl_wow_ps_pwr_cfg(struct phl_wow_info * wow_info,bool enter_ps)1836*4882a593Smuzhiyun enum rtw_phl_status phl_wow_ps_pwr_cfg(struct phl_wow_info *wow_info, bool enter_ps)
1837*4882a593Smuzhiyun {
1838*4882a593Smuzhiyun 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1839*4882a593Smuzhiyun 	struct phl_info_t *phl_info = wow_info->phl_info;
1840*4882a593Smuzhiyun 
1841*4882a593Smuzhiyun 	if (wow_info->ps_pwr_lvl == PS_PWR_LVL_PWRON)
1842*4882a593Smuzhiyun 		return hstatus;
1843*4882a593Smuzhiyun 
1844*4882a593Smuzhiyun 	if (wow_info->op_mode == RTW_WOW_OP_DISCONNECT_STBY) {
1845*4882a593Smuzhiyun 		hstatus = rtw_hal_ps_pwr_lvl_cfg(phl_info->phl_com, phl_info->hal,
1846*4882a593Smuzhiyun 					(enter_ps == true ? wow_info->ps_pwr_lvl : PS_PWR_LVL_PWRON));
1847*4882a593Smuzhiyun 	} else if (wow_info->op_mode == RTW_WOW_OP_CONNECT_STBY) {
1848*4882a593Smuzhiyun 		hstatus = rtw_hal_ps_pwr_lvl_cfg(phl_info->phl_com, phl_info->hal,
1849*4882a593Smuzhiyun 					(enter_ps == true ? wow_info->ps_pwr_lvl : PS_PWR_LVL_PWRON));
1850*4882a593Smuzhiyun 	} else {
1851*4882a593Smuzhiyun 		PHL_ERR("%s : undefined wowlan op mode.\n", __func__);
1852*4882a593Smuzhiyun 	}
1853*4882a593Smuzhiyun 
1854*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_WOW, _PHL_INFO_, "[wow] %s : op mode %d, enter ps %d, pwr lvl %s.\n.",
1855*4882a593Smuzhiyun 			  __func__, wow_info->op_mode, enter_ps, phl_ps_pwr_lvl_to_str(wow_info->ps_pwr_lvl));
1856*4882a593Smuzhiyun 
1857*4882a593Smuzhiyun 	return (hstatus == RTW_HAL_STATUS_SUCCESS ?
1858*4882a593Smuzhiyun 			RTW_PHL_STATUS_SUCCESS : RTW_PHL_STATUS_FAILURE);
1859*4882a593Smuzhiyun }
1860*4882a593Smuzhiyun #endif /* CONFIG_POWER_SAVE */
1861*4882a593Smuzhiyun 
1862*4882a593Smuzhiyun #define case_rsn(rsn) \
1863*4882a593Smuzhiyun 	case RTW_WOW_RSN_##rsn: return #rsn
1864*4882a593Smuzhiyun 
rtw_phl_get_wow_rsn_str(void * phl,enum rtw_wow_wake_reason wake_rsn)1865*4882a593Smuzhiyun const char *rtw_phl_get_wow_rsn_str(void *phl, enum rtw_wow_wake_reason wake_rsn)
1866*4882a593Smuzhiyun {
1867*4882a593Smuzhiyun 	switch (wake_rsn) {
1868*4882a593Smuzhiyun 	case_rsn(UNKNOWN); /* RTW_WOW_RSN_UNKNOWN */
1869*4882a593Smuzhiyun 	case_rsn(RX_PAIRWISEKEY);
1870*4882a593Smuzhiyun 	case_rsn(RX_GTK);
1871*4882a593Smuzhiyun 	case_rsn(RX_FOURWAY_HANDSHAKE);
1872*4882a593Smuzhiyun 	case_rsn(RX_DISASSOC);
1873*4882a593Smuzhiyun 	case_rsn(RX_DEAUTH);
1874*4882a593Smuzhiyun 	case_rsn(RX_ARP_REQUEST);
1875*4882a593Smuzhiyun 	case_rsn(RX_NS);
1876*4882a593Smuzhiyun 	case_rsn(RX_EAPREQ_IDENTIFY);
1877*4882a593Smuzhiyun 	case_rsn(FW_DECISION_DISCONNECT);
1878*4882a593Smuzhiyun 	case_rsn(RX_MAGIC_PKT);
1879*4882a593Smuzhiyun 	case_rsn(RX_UNICAST_PKT);
1880*4882a593Smuzhiyun 	case_rsn(RX_PATTERN_PKT);
1881*4882a593Smuzhiyun 	case_rsn(RTD3_SSID_MATCH);
1882*4882a593Smuzhiyun 	case_rsn(RX_DATA_PKT);
1883*4882a593Smuzhiyun 	case_rsn(RX_SSDP_MATCH);
1884*4882a593Smuzhiyun 	case_rsn(RX_WSD_MATCH);
1885*4882a593Smuzhiyun 	case_rsn(RX_SLP_MATCH);
1886*4882a593Smuzhiyun 	case_rsn(RX_LLTD_MATCH);
1887*4882a593Smuzhiyun 	case_rsn(RX_MDNS_MATCH);
1888*4882a593Smuzhiyun 	case_rsn(RX_REALWOW_V2_WAKEUP_PKT);
1889*4882a593Smuzhiyun 	case_rsn(RX_REALWOW_V2_ACK_LOST);
1890*4882a593Smuzhiyun 	case_rsn(RX_REALWOW_V2_TX_KAPKT);
1891*4882a593Smuzhiyun 	case_rsn(ENABLE_FAIL_DMA_IDLE);
1892*4882a593Smuzhiyun 	case_rsn(ENABLE_FAIL_DMA_PAUSE);
1893*4882a593Smuzhiyun 	case_rsn(RTIME_FAIL_DMA_IDLE);
1894*4882a593Smuzhiyun 	case_rsn(RTIME_FAIL_DMA_PAUSE);
1895*4882a593Smuzhiyun 	case_rsn(RX_SNMP_MISMATCHED_PKT);
1896*4882a593Smuzhiyun 	case_rsn(RX_DESIGNATED_MAC_PKT);
1897*4882a593Smuzhiyun 	case_rsn(NLO_SSID_MACH);
1898*4882a593Smuzhiyun 	case_rsn(AP_OFFLOAD_WAKEUP);
1899*4882a593Smuzhiyun 	case_rsn(DMAC_ERROR_OCCURRED);
1900*4882a593Smuzhiyun 	case_rsn(EXCEPTION_OCCURRED);
1901*4882a593Smuzhiyun 	case_rsn(L0_TO_L1_ERROR_OCCURRED);
1902*4882a593Smuzhiyun 	case_rsn(ASSERT_OCCURRED);
1903*4882a593Smuzhiyun 	case_rsn(L2_ERROR_OCCURRED);
1904*4882a593Smuzhiyun 	case_rsn(WDT_TIMEOUT_WAKE);
1905*4882a593Smuzhiyun 	case_rsn(RX_ACTION);
1906*4882a593Smuzhiyun 	case_rsn(CLK_32K_UNLOCK);
1907*4882a593Smuzhiyun 	case_rsn(CLK_32K_LOCK);
1908*4882a593Smuzhiyun 	default:
1909*4882a593Smuzhiyun 		return "UNDEFINED"; /* RTW_WOW_RSN_MAX */
1910*4882a593Smuzhiyun 	}
1911*4882a593Smuzhiyun }
1912*4882a593Smuzhiyun 
rtw_phl_cfg_wow_set_sw_gpio_mode(void * phl,struct rtw_wow_gpio_info * info)1913*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_cfg_wow_set_sw_gpio_mode(void *phl, struct rtw_wow_gpio_info *info)
1914*4882a593Smuzhiyun {
1915*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
1916*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1917*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
1918*4882a593Smuzhiyun 	struct rtw_wow_gpio_info *wow_gpio = &wow_info->wow_gpio;
1919*4882a593Smuzhiyun 
1920*4882a593Smuzhiyun 	FUNCIN();
1921*4882a593Smuzhiyun 
1922*4882a593Smuzhiyun 	wow_gpio->dev2hst_gpio = info->dev2hst_gpio;
1923*4882a593Smuzhiyun 	wow_gpio->dev2hst_gpio_mode = info->dev2hst_gpio_mode;
1924*4882a593Smuzhiyun 	phl_status = rtw_hal_set_sw_gpio_mode(phl_info->phl_com, phl_info->hal
1925*4882a593Smuzhiyun 		, wow_gpio->dev2hst_gpio_mode, wow_gpio->dev2hst_gpio);
1926*4882a593Smuzhiyun 
1927*4882a593Smuzhiyun 	PHL_INFO("%s, gpio=%d, gpio_mode=%d\n", __FUNCTION__
1928*4882a593Smuzhiyun 		, wow_gpio->dev2hst_gpio, wow_gpio->dev2hst_gpio_mode);
1929*4882a593Smuzhiyun 
1930*4882a593Smuzhiyun 	return phl_status;
1931*4882a593Smuzhiyun }
1932*4882a593Smuzhiyun 
rtw_phl_cfg_wow_sw_gpio_ctrl(void * phl,struct rtw_wow_gpio_info * info)1933*4882a593Smuzhiyun enum rtw_phl_status rtw_phl_cfg_wow_sw_gpio_ctrl(void *phl, struct rtw_wow_gpio_info *info)
1934*4882a593Smuzhiyun {
1935*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
1936*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1937*4882a593Smuzhiyun 	struct phl_wow_info *wow_info = phl_to_wow_info(phl_info);
1938*4882a593Smuzhiyun 	struct rtw_wow_gpio_info *wow_gpio = &wow_info->wow_gpio;
1939*4882a593Smuzhiyun 
1940*4882a593Smuzhiyun 	FUNCIN();
1941*4882a593Smuzhiyun 
1942*4882a593Smuzhiyun 	wow_gpio->dev2hst_high = info->dev2hst_high;
1943*4882a593Smuzhiyun 	phl_status = rtw_hal_sw_gpio_ctrl(phl_info->phl_com, phl_info->hal
1944*4882a593Smuzhiyun 		, wow_gpio->dev2hst_high, wow_gpio->dev2hst_gpio);
1945*4882a593Smuzhiyun 
1946*4882a593Smuzhiyun 	PHL_INFO("%s, gpio=%d, output=%d\n", __FUNCTION__
1947*4882a593Smuzhiyun 		, wow_gpio->dev2hst_gpio, wow_gpio->dev2hst_high);
1948*4882a593Smuzhiyun 
1949*4882a593Smuzhiyun 	return phl_status;
1950*4882a593Smuzhiyun }
1951*4882a593Smuzhiyun 
1952*4882a593Smuzhiyun #endif /* CONFIG_WOWLAN */
1953