xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/phl_p2pps.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2020 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _PHL_P2PPS_C_
16 #include "phl_headers.h"
17 #ifdef RTW_WKARD_P2PPS_REFINE
18 #ifdef CONFIG_PHL_P2PPS
phl_p2pps_init(struct phl_info_t * phl)19 enum rtw_phl_status phl_p2pps_init(struct phl_info_t *phl)
20 {
21 	enum rtw_phl_status status = RTW_PHL_STATUS_SUCCESS;
22 	struct rtw_phl_com_t *phl_com = phl->phl_com;
23 	struct rtw_phl_p2pps_info *info;
24 
25 	info = (struct rtw_phl_p2pps_info *)_os_mem_alloc(phl_to_drvpriv(phl),
26 		sizeof(*info));
27 	if (info == NULL)
28 		return RTW_PHL_STATUS_RESOURCE;
29 	_os_mem_set(phl_to_drvpriv(phl),
30 			info, 0, sizeof(*info));
31 	phl_com->p2pps_info = (void*)info;
32 	info->phl_info = phl;
33 	_os_spinlock_init(phl_to_drvpriv(phl), &info->p2pps_lock);
34 	return status;
35 }
36 
phl_p2pps_deinit(struct phl_info_t * phl_info)37 void phl_p2pps_deinit(struct phl_info_t *phl_info)
38 {
39 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
40 	struct rtw_phl_p2pps_info *info ;
41 	info = (struct rtw_phl_p2pps_info *)phl_com->p2pps_info;
42 	if (info) {
43 		_os_spinlock_free(phl_to_drvpriv(phl_info), &info->p2pps_lock);
44 		_os_mem_free(phl_to_drvpriv(phl_info), info, sizeof(*info));
45 	}
46 	phl_com->p2pps_info = NULL;
47 }
48 
49 void
_phl_p2pps_dump_single_noa_desc(struct rtw_phl_noa_desc * desc)50 _phl_p2pps_dump_single_noa_desc(struct rtw_phl_noa_desc *desc)
51 {
52 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():enable = %d\n",
53 		desc->enable);
54 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():start_t_h = 0x%x\n",
55 		desc->start_t_h);
56 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():start_t_l = 0x%x\n",
57 		desc->start_t_l);
58 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():interval = %d\n",
59 		desc->interval);
60 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():duration = %d\n",
61 		desc->duration);
62 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():count = %d\n",
63 		desc->count);
64 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():noa_id = %d\n",
65 		desc->noa_id);
66 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():tag = %d\n",
67 		desc->tag);
68 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_single_noa_desc():w_role = 0x%p\n",
69 		desc->w_role);
70 }
71 
72 void
_phl_p2pps_dump_noa_table(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_info * info)73 _phl_p2pps_dump_noa_table(struct rtw_phl_p2pps_info *psinfo,
74 	struct rtw_phl_noa_info *info)
75 {
76 	void *drvpriv = phlcom_to_drvpriv(psinfo->phl_info->phl_com);
77 	struct rtw_phl_noa_desc *desc = NULL;
78 	u8 i = 0;
79 
80 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():====>\n");
81 	_os_spinlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
82 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA] info.en_desc_num = %d, pause = %d\n",
83 		info->en_desc_num, info->paused);
84 	for (i = 0; i < MAX_NOA_DESC; i++) {
85 		desc = &info->noa_desc[i];
86 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]================DESC[%d]==================\n",
87 			i);
88 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():enable = %d\n",
89 			desc->enable);
90 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():start_t_h = 0x%x\n",
91 			desc->start_t_h);
92 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():start_t_l = 0x%x\n",
93 			desc->start_t_l);
94 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():interval = %d\n",
95 			desc->interval);
96 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():duration = %d\n",
97 			desc->duration);
98 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():count = %d\n",
99 			desc->count);
100 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():noa_id = %d\n",
101 			desc->noa_id);
102 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():tag = %d\n",
103 			desc->tag);
104 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_dump_noa_table():w_role = 0x%p\n",
105 			desc->w_role);
106 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]================DESC[%d]==================\n",
107 			i);
108 	}
109 	_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
110 }
111 
112 struct rtw_phl_noa_info *
_phl_p2pps_get_noa_info_by_role(struct rtw_phl_p2pps_info * psinfo,struct rtw_wifi_role_t * wrole)113 _phl_p2pps_get_noa_info_by_role(struct rtw_phl_p2pps_info *psinfo,
114 	struct rtw_wifi_role_t *wrole)
115 {
116 	u8 idx = get_role_idx(wrole);
117 	return &psinfo->noa_info[idx];
118 }
119 
120 struct rtw_phl_noa_desc *
_phl_p2pps_get_first_noa_desc_with_cnt255(struct phl_info_t * phl,struct rtw_phl_noa_info * info)121 _phl_p2pps_get_first_noa_desc_with_cnt255(struct phl_info_t *phl,
122 	struct rtw_phl_noa_info *info)
123 {
124 	u8 i = 0;
125 
126 	struct rtw_phl_noa_desc *tmp_desc;
127 	for (i = 0; i < MAX_NOA_DESC; i++) {
128 		tmp_desc = &info->noa_desc[i];
129 		if(tmp_desc->count == 255 && tmp_desc->enable) {
130 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_get_first_noa_desc_with_cnt255():get desc, tag = %d!!\n",
131 				tmp_desc->tag);
132 			return tmp_desc;
133 		}
134 	}
135 	return NULL;
136 }
137 
138 #ifdef RTW_WKARD_P2PPS_SINGLE_NOA
139 
140 u8
_phl_p2pps_query_mcc_inprog_wkard(struct phl_info_t * phl_info,struct rtw_wifi_role_t * w_role)141 _phl_p2pps_query_mcc_inprog_wkard(struct phl_info_t *phl_info,
142 	struct rtw_wifi_role_t *w_role)
143 {
144 	u8 ret = false;
145 #ifdef CONFIG_MCC_SUPPORT
146 	//ret = phl_mr_query_mcc_inprogress(phl_info, w_role,
147 	//					RTW_PHL_MCC_CHK_INPROGRESS);
148 #endif
149 	return ret;
150 }
151 
152 struct rtw_wifi_role_t *
_phl_get_role_by_band_port(struct phl_info_t * phl_info,u8 hw_band,u8 hw_port)153 _phl_get_role_by_band_port(struct phl_info_t* phl_info,
154 	u8 hw_band,
155 	u8 hw_port)
156 {
157 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
158 	struct mr_ctl_t *mr_ctl = phlcom_to_mr_ctrl(phl_com);
159 	struct hw_band_ctl_t *band_ctrl = &(mr_ctl->band_ctrl[hw_band]);
160 	struct rtw_wifi_role_t *wrole = NULL;
161 	u8 ridx = 0;
162 
163 	for (ridx = 0; ridx < MAX_WIFI_ROLE_NUMBER; ridx++) {
164 		if (!(band_ctrl->role_map & BIT(ridx)))
165 			continue;
166 		wrole = rtw_phl_get_wrole_by_ridx(phl_info->phl_com, ridx);
167 		if (wrole == NULL)
168 			continue;
169 		if (wrole->hw_band == hw_band && wrole->hw_port == hw_port) {
170 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_get_role_by_band_port():role_id(%d) hw_band = %d, hw_port = %d\n",
171 			ridx, wrole->hw_band, wrole->hw_port);
172 			return wrole;
173 		}
174 	}
175 	return NULL;
176 }
177 
178 void
_phl_p2pps_calc_next_noa_s_time(struct phl_info_t * phl_info,struct rtw_wifi_role_t * w_role,struct rtw_phl_tsf32_tog_rpt * rpt,struct rtw_phl_noa_desc * orig_desc,struct rtw_phl_noa_desc * new_desc)179 _phl_p2pps_calc_next_noa_s_time(struct phl_info_t *phl_info,
180 	struct rtw_wifi_role_t *w_role,
181 	struct rtw_phl_tsf32_tog_rpt *rpt,
182 	struct rtw_phl_noa_desc *orig_desc,
183 	struct rtw_phl_noa_desc *new_desc)
184 {
185 	void *d = phl_to_drvpriv(phl_info);
186 	u64 new_st = 0, old_st = 0;
187 	u64 tog_t = 0, delta_t = 0, intv_cnt = 0;
188 
189 	_os_mem_cpy(d, new_desc, orig_desc, sizeof(*orig_desc));
190 	old_st = (((u64)orig_desc->start_t_h << 32) | orig_desc->start_t_l);
191 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_calc_next_noa_s_time():old_st: 0x%08x %08x\n",
192 		(u32)(old_st >> 32), (u32)old_st);
193 	tog_t = (((u64)rpt->tsf_h << 32) | rpt->tsf_l);
194 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_calc_next_noa_s_time():tog_t = 0x%08x %08x\n",
195 		(u32)(tog_t >> 32), (u32)tog_t);
196 	delta_t = tog_t - old_st;
197 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_calc_next_noa_s_time():delta_t = 0x%08x %08x\n",
198 		(u32)(delta_t >> 32), (u32)delta_t);
199 	intv_cnt = _os_division64(delta_t,  new_desc->interval) + 1;
200 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_calc_next_noa_s_time():intv_cnt = 0x%08x %08x\n",
201 		(u32)(intv_cnt >> 32), (u32)intv_cnt);
202 	new_st = old_st + (intv_cnt * new_desc->interval);
203 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_calc_next_noa_s_time():new_st = 0x%08x %08x\n",
204 		(u32)(new_st >> 32), (u32)new_st);
205 	new_desc->start_t_h = new_st >> 32;
206 	new_desc->start_t_l = new_st & 0xFFFFFFFF;
207 }
208 
_phl_p2pps_ap_on_tsf32_tog(struct phl_info_t * phl_info,struct rtw_wifi_role_t * wrole,struct rtw_phl_tsf32_tog_rpt * rpt)209 void _phl_p2pps_ap_on_tsf32_tog(struct phl_info_t* phl_info,
210 	struct rtw_wifi_role_t *wrole,
211 	struct rtw_phl_tsf32_tog_rpt *rpt)
212 {
213 	struct rtw_phl_p2pps_info *psinfo = phl_to_p2pps_info(phl_info);
214 	struct rtw_phl_noa_info *info = NULL;
215 	struct rtw_phl_noa_desc *orig_desc = NULL;
216 	struct rtw_phl_noa_desc new_desc = {0};
217 	void *d = phl_to_drvpriv(phl_info);
218 
219 	info = _phl_p2pps_get_noa_info_by_role(psinfo, wrole);
220 	orig_desc = _phl_p2pps_get_first_noa_desc_with_cnt255(phl_info, info);
221 	if (orig_desc) {
222 		_phl_p2pps_calc_next_noa_s_time(phl_info, wrole, rpt,
223 						orig_desc, &new_desc);
224 		_os_mem_cpy(d, orig_desc, &new_desc, sizeof(new_desc));
225 		_phl_p2pps_dump_single_noa_desc(&new_desc);
226 		if(psinfo->ops.tsf32_tog_update_single_noa)
227 			psinfo->ops.tsf32_tog_update_single_noa(d, wrole, &new_desc);
228 	} else {
229 		return;
230 	}
231 }
232 #endif
233 
phl_p2pps_tsf32_tog_handler(struct phl_info_t * phl_info)234 void phl_p2pps_tsf32_tog_handler(struct phl_info_t* phl_info)
235 {
236 	void *hal = phl_info->hal;
237 	struct rtw_phl_tsf32_tog_rpt rpt = {0};
238 	struct rtw_wifi_role_t *wrole = NULL;
239 	enum rtw_hal_status h_stat;
240 
241 	h_stat = rtw_hal_get_tsf32_tog_rpt(hal, &rpt);
242 	if (h_stat != RTW_HAL_STATUS_SUCCESS)
243 		return;
244 	if (!rpt.valid) {
245 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_WARNING_, "[NOA]phl_p2pps_tsf32_tog_handler():report not valid!!\n");
246 		return;
247 	}
248 	wrole = _phl_get_role_by_band_port(phl_info, rpt.band, rpt.port);
249 	if (wrole) {
250 		if (wrole->type == PHL_RTYPE_AP) {
251 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_tsf32_tog_handler():role(%d) is AP/GO mode, handle noa update\n",
252 				wrole->id);
253 #ifdef RTW_WKARD_P2PPS_SINGLE_NOA
254 			_phl_p2pps_ap_on_tsf32_tog(phl_info, wrole, &rpt);
255 #endif
256 		} else if (wrole->type == PHL_RTYPE_STATION) {
257 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_tsf32_tog_handler():role(%d) is STA/GO mode, currently do nothing\n",
258 				wrole->id);
259 			/*Call NoA disable all?*/
260 		}
261 	} else {
262 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_WARNING_, "[NOA]phl_p2pps_tsf32_tog_handler():NULL ROLE!!, hwband = %d, hwport = %d\n",
263 			rpt.band, rpt.port);
264 	}
265 }
266 
267 void
_phl_p2pps_copy_noa_desc(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_desc * dest,struct rtw_phl_noa_desc * src)268 _phl_p2pps_copy_noa_desc(struct rtw_phl_p2pps_info *psinfo,
269 	struct rtw_phl_noa_desc *dest,
270 	struct rtw_phl_noa_desc *src)
271 {
272 	void *drvpriv = phlcom_to_drvpriv(psinfo->phl_info->phl_com);
273 
274 	_os_spinlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
275 	_os_mem_cpy(drvpriv, dest, src, sizeof(struct rtw_phl_noa_desc));
276 	_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
277 }
278 
279 void
_phl_p2pps_clear_noa_desc(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_desc * desc)280 _phl_p2pps_clear_noa_desc(struct rtw_phl_p2pps_info *psinfo,
281 	struct rtw_phl_noa_desc *desc)
282 {
283 	void *drvpriv = phlcom_to_drvpriv(psinfo->phl_info->phl_com);
284 
285 	_os_spinlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
286 	_os_mem_set(drvpriv, desc, 0, sizeof(struct rtw_phl_noa_desc));
287 	_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
288 }
289 
290 void
_phl_p2pps_noa_increase_desc(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_info * info)291 _phl_p2pps_noa_increase_desc(struct rtw_phl_p2pps_info *psinfo,
292 	struct rtw_phl_noa_info *info)
293 {
294 	void *drvpriv = phlcom_to_drvpriv(psinfo->phl_info->phl_com);
295 
296 	_os_spinlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
297 	info->en_desc_num++;
298 	_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
299 }
300 
301 void
_phl_p2pps_noa_decrease_desc(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_info * info)302 _phl_p2pps_noa_decrease_desc(struct rtw_phl_p2pps_info *psinfo,
303 	struct rtw_phl_noa_info *info)
304 {
305 	void *drvpriv = phlcom_to_drvpriv(psinfo->phl_info->phl_com);
306 
307 	_os_spinlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
308 	if (info->en_desc_num > 0)
309 		info->en_desc_num--;
310 	else
311 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_WARNING_, "[NOA]_phl_p2pps_noa_decrease_desc():info->en_desc_num == 0! Flow error\n");
312 	_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
313 }
314 
315 u8
_phl_p2pps_noa_should_activate(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_desc * in_desc)316 _phl_p2pps_noa_should_activate(struct rtw_phl_p2pps_info *psinfo,
317 	struct rtw_phl_noa_desc *in_desc)
318 {
319 	u8 ret = true;
320 	if (in_desc->tag == P2PPS_TRIG_GO) {
321 		ret = true;
322 	} else if (in_desc->tag == P2PPS_TRIG_GC) {
323 		ret = true;
324 	} else if (in_desc->tag == P2PPS_TRIG_GC_255) {
325 		ret = true;
326 	} else if (in_desc->tag == P2PPS_TRIG_2G_SCC_1AP_1STA_BT) {
327 		ret = true;
328 	} else if (in_desc->tag == P2PPS_TRIG_MCC) {
329 		ret = false;
330 #ifdef RTW_WKARD_P2PPS_NOA_MCC
331 		goto exit;
332 #endif
333 	}
334 #ifdef RTW_WKARD_P2PPS_SINGLE_NOA
335 	/*Currently should only notify MRC for limit request*/
336 	/*Under count == 255 case */
337 	if (in_desc->count != 255) {
338 		if (_phl_p2pps_query_mcc_inprog_wkard(psinfo->phl_info,
339 							in_desc->w_role)) {
340 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_WARNING_, "[NOA]_phl_p2pps_noa_should_activate():mcc in progress and noa requset != 255, currently not handling!\n");
341 			ret = false;
342 		}
343 	} else {
344 		/* open when mr ready*/
345 		/*
346 		if (phl_mr_noa_dur_lim_change(psinfo->phl_info,
347 						in_desc->w_role, in_desc)) {
348 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_should_activate():mrc take over this req!\n");
349 			ret = false;
350 		}
351 		*/
352 	}
353 #endif
354 exit:
355 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_should_activate():tag = %d, return = %d\n",
356 		in_desc->tag, ret);
357 	return ret;
358 }
359 
360 u8
_phl_p2pps_noa_is_all_disable(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_info * info)361 _phl_p2pps_noa_is_all_disable(struct rtw_phl_p2pps_info *psinfo,
362 	struct rtw_phl_noa_info *info)
363 {
364 	u8 i = 0;
365 	void *drvpriv = phlcom_to_drvpriv(psinfo->phl_info->phl_com);
366 	_os_spinlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
367 	for (i = 0; i < MAX_NOA_DESC; i++) {
368 		struct rtw_phl_noa_desc *desc = &info->noa_desc[i];
369 		if(desc->enable) {
370 			_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
371 			return false;
372 		}
373 	}
374 	_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
375 	return true;
376 }
377 
378 u8
_phl_p2pps_noa_assign_noaid(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_info * info,struct rtw_phl_noa_desc * desc)379 _phl_p2pps_noa_assign_noaid(struct rtw_phl_p2pps_info *psinfo,
380 	struct rtw_phl_noa_info *info,
381 	struct rtw_phl_noa_desc *desc)
382 {
383 	u8 max = 0, id = NOAID_NONE, i = 0;
384 	void *drvpriv = phlcom_to_drvpriv(psinfo->phl_info->phl_com);
385 
386 	_os_spinlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
387 	if (info->en_desc_num == 0) {
388 		id = 0;/*not inited flow*/
389 	} else {
390 
391 		for (i = 0; i < MAX_NOA_DESC; i++) {
392 
393 			if (info->noa_desc[i].noa_id == NOAID_NONE)
394 				continue;
395 			if (info->noa_desc[i].noa_id > max)
396 				max = info->noa_desc[i].noa_id;
397 		}
398 		if(max != 0)
399 			id = max + 1;
400 		else id = 0;
401 	}
402 	_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
403 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_assign_noaid(): Final ID = %d.\n",
404 		id);
405 	return id;
406 }
407 
408 enum rtw_phl_status
_phl_p2pps_noa_disable(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_info * noa_info,struct rtw_phl_noa_desc * noa_desc,u8 clear_desc)409 _phl_p2pps_noa_disable(struct rtw_phl_p2pps_info *psinfo,
410 	struct rtw_phl_noa_info *noa_info,
411 	struct rtw_phl_noa_desc *noa_desc,
412 	u8 clear_desc)
413 {
414 	enum rtw_phl_status ret = RTW_PHL_STATUS_FAILURE;
415 	enum rtw_hal_status hal_ret = RTW_HAL_STATUS_FAILURE;
416 	void *drvpriv = phlcom_to_drvpriv(psinfo->phl_info->phl_com);
417 	void *hal = psinfo->phl_info->hal;
418 	struct rtw_phl_stainfo_t *sta_info;
419 	struct rtw_wifi_role_t *w_role = NULL;
420 	struct phl_info_t *phl_info = psinfo->phl_info;
421 	u8 en_to_fw = 0;
422 	u8 idx = 0;
423 
424 	if (noa_info->paused && clear_desc) {
425 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_disable():NoA info is in puase state, clear desc only!\n");
426 		_phl_p2pps_clear_noa_desc(psinfo,noa_desc);
427 		return RTW_PHL_STATUS_SUCCESS;
428 	}
429 
430 	w_role = noa_desc->w_role;
431 
432 	_os_spinlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
433 	en_to_fw = (noa_desc->noa_id != NOAID_NONE && noa_desc->enable);
434 	_os_spinunlock(drvpriv, &psinfo->p2pps_lock, _bh, NULL);
435 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NoA]%s(): en_to_fw(%d), clear_desc(%d)\n",
436 		__func__, en_to_fw, clear_desc);
437 	if (en_to_fw) {
438 		sta_info = rtw_phl_get_stainfo_self(psinfo->phl_info,
439 							noa_desc->w_role);
440 		hal_ret = rtw_hal_noa_disable(hal, noa_info, noa_desc,
441 							sta_info->macid);
442 		if (hal_ret!= RTW_HAL_STATUS_SUCCESS) {
443 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_ERR_, "[NOA]_phl_p2pps_noa_disable():NoA Disable fail! tag = %d, ID = %d, HAL return = %d\n",
444 				noa_desc->tag, noa_desc->noa_id, hal_ret);
445 			ret = RTW_PHL_STATUS_FAILURE;
446 		} else {
447 			_phl_p2pps_noa_decrease_desc(psinfo,noa_info);
448 			ret = RTW_PHL_STATUS_SUCCESS;
449 			if (clear_desc)
450 				_phl_p2pps_clear_noa_desc(psinfo,noa_desc);
451 		}
452 	} else {
453 		/*not enabled to fw case*/
454 		ret = RTW_PHL_STATUS_SUCCESS;
455 		if (clear_desc)
456 			_phl_p2pps_clear_noa_desc(psinfo,noa_desc);
457 	}
458 
459 	if(RTW_PHL_STATUS_SUCCESS == ret) {
460 		if(NULL != w_role) {
461 			/* notify BTC */
462 			/* copy noa_desc array to w_role*/
463 			for (idx = 0; idx < MAX_NOA_DESC; idx ++) {
464 				_phl_p2pps_copy_noa_desc(psinfo,
465 					w_role->noa_desc + idx,
466 					noa_info->noa_desc + idx);
467 			}
468 			phl_role_noa_notify(phl_info, w_role);
469 		} else {
470 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_WARNING_, "[NOA]_phl_p2pps_noa_disable():w_role in noa_desc is NULL, not to notify to BTC\n");
471 		}
472 	}
473 
474 	return ret;
475 }
476 
_phl_p2pps_noa_disable_all(struct phl_info_t * phl,struct rtw_wifi_role_t * w_role)477 void _phl_p2pps_noa_disable_all(struct phl_info_t *phl,
478 	struct rtw_wifi_role_t *w_role)
479 {
480 	struct rtw_phl_p2pps_info *psinfo = phl_to_p2pps_info(phl);
481 	u8 role_id = get_role_idx(w_role);
482 	struct rtw_phl_noa_info *noa_info = &psinfo->noa_info[role_id];
483 	u8 i = 0;
484 
485 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_disable_all():====>\n");
486 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_disable_all():Disable all NoA for wrole(%d)!\n",
487 		role_id);
488 	_phl_p2pps_dump_noa_table(phl_to_p2pps_info(phl),noa_info);
489 	for (i = 0; i < MAX_NOA_DESC; i++) {
490 		struct rtw_phl_noa_desc *desc = &noa_info->noa_desc[i];
491 		if (desc->enable) {
492 			_phl_p2pps_noa_disable(psinfo, noa_info, desc, true);
493 		}
494 	}
495 	noa_info->paused = false;
496 	_phl_p2pps_dump_noa_table(phl_to_p2pps_info(phl),noa_info);
497 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_disable_all():<====\n");
498 }
499 
500 enum rtw_phl_status
_phl_p2pps_noa_enable(struct rtw_phl_p2pps_info * psinfo,struct rtw_phl_noa_info * noa_info,struct rtw_phl_noa_desc * noa_desc,struct rtw_phl_noa_desc * in_desc)501 _phl_p2pps_noa_enable(struct rtw_phl_p2pps_info *psinfo,
502 	struct rtw_phl_noa_info *noa_info,
503 	struct rtw_phl_noa_desc *noa_desc,
504 	struct rtw_phl_noa_desc *in_desc)
505 {
506 	enum rtw_phl_status ret = RTW_PHL_STATUS_FAILURE;
507 	enum rtw_hal_status hal_ret = RTW_HAL_STATUS_FAILURE;
508 	void *hal = psinfo->phl_info->hal;
509 	struct rtw_phl_stainfo_t *sta_info;
510 	struct rtw_wifi_role_t *w_role = NULL;
511 	struct phl_info_t *phl_info = psinfo->phl_info;
512 	u8 idx = 0;
513 
514 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NoA]%s()\n",
515 		__func__);
516 	_phl_p2pps_copy_noa_desc(psinfo, noa_desc, in_desc);
517 
518 	/* get w_role */
519 	w_role = noa_desc->w_role;
520 
521 	if(NULL != w_role) {
522 		/* notify BTC */
523 		/* copy noa_desc array to w_role */
524 		for (idx = 0; idx < MAX_NOA_DESC; idx ++) {
525 			_phl_p2pps_copy_noa_desc(psinfo,
526 				w_role->noa_desc+idx,
527 				noa_info->noa_desc+idx);
528 		}
529 		phl_role_noa_notify(phl_info, w_role);
530 	} else {
531 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_WARNING_, "[NOA]_phl_p2pps_noa_enable():w_role in noa_desc is NULL, not to notify to BTC\n");
532 	}
533 
534 	if (noa_info->paused) {
535 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_enable():NoA is in pause state, record request and leave\n");
536 		return RTW_PHL_STATUS_SUCCESS;
537 	}
538 	if (_phl_p2pps_noa_should_activate(psinfo, noa_desc)) {
539 		noa_desc->noa_id = _phl_p2pps_noa_assign_noaid(psinfo, noa_info,
540 					noa_desc);
541 		sta_info = rtw_phl_get_stainfo_self(psinfo->phl_info,
542 							noa_desc->w_role);
543 		hal_ret = rtw_hal_noa_enable(hal, noa_info, noa_desc,
544 							sta_info->macid);
545 		if (hal_ret != RTW_HAL_STATUS_SUCCESS) {
546 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_ERR_, "[NOA]_phl_p2pps_noa_enable():NoA enable fail! tag = %d, ID = %d, HAL return = %d\n",
547 				noa_desc->tag, noa_desc->noa_id, hal_ret);
548 			noa_desc->noa_id = NOAID_NONE;
549 			if (hal_ret == RTW_HAL_STATUS_RESOURCE)
550 				ret = RTW_PHL_STATUS_RESOURCE;
551 			else
552 				ret = RTW_PHL_STATUS_FAILURE;
553 		} else {
554 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]_phl_p2pps_noa_enable():NoA enable SUCCESS! tag = %d, ID = %d, HAL return = %d\n",
555 				noa_desc->tag, noa_desc->noa_id, hal_ret);
556 			_phl_p2pps_noa_increase_desc(psinfo,noa_info);
557 
558 			ret = RTW_PHL_STATUS_SUCCESS;
559 		}
560 	} else {
561 		noa_desc->noa_id = NOAID_NONE; /*not activate*/
562 		ret = RTW_PHL_STATUS_SUCCESS;
563 	}
564 	return ret;
565 }
566 
567 void
phl_p2pps_noa_resume_all(struct phl_info_t * phl,struct rtw_wifi_role_t * w_role)568 phl_p2pps_noa_resume_all(struct phl_info_t *phl,
569 	struct rtw_wifi_role_t *w_role)
570 {
571 	struct rtw_phl_p2pps_info *psinfo = phl_to_p2pps_info(phl);
572 	u8 role_idx = get_role_idx(w_role);
573 	struct rtw_phl_noa_info *noa_info = &psinfo->noa_info[role_idx];
574 	u8 i = 0;
575 
576 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_resume_all():====>\n");
577 	if (!noa_info->paused) {
578 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_resume_all():NoA not paused on role:%d\n",
579 			w_role->id);
580 		goto exit;
581 	}
582 	// _phl_p2pps_dump_noa_table(phl_to_p2pps_info(phl),noa_info);
583 	noa_info->paused = false;
584 	for (i = 0; i < MAX_NOA_DESC; i++) {
585 		struct rtw_phl_noa_desc *desc = &noa_info->noa_desc[i];
586 		if(desc->enable)
587 			_phl_p2pps_noa_enable(psinfo, noa_info, desc, desc);
588 	}
589 	// _phl_p2pps_dump_noa_table(phl_to_p2pps_info(phl),noa_info);
590 exit:
591 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_resume_all():<====\n");
592 }
593 
594 void
phl_p2pps_noa_all_role_resume(struct phl_info_t * phl_info,u8 band_idx)595 phl_p2pps_noa_all_role_resume(struct phl_info_t *phl_info, u8 band_idx)
596 {
597 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
598 	struct mr_ctl_t *mr_ctl = phlcom_to_mr_ctrl(phl_com);
599 	struct hw_band_ctl_t *band_ctrl = &(mr_ctl->band_ctrl[band_idx]);
600 	struct rtw_wifi_role_t *wrole = NULL;
601 	u8 ridx = 0;
602 
603 	for (ridx = 0; ridx < MAX_WIFI_ROLE_NUMBER; ridx++) {
604 		if (!(band_ctrl->role_map & BIT(ridx)))
605 			continue;
606 		wrole = rtw_phl_get_wrole_by_ridx(phl_info->phl_com, ridx);
607 		if (wrole == NULL)
608 			continue;
609 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]p2pps_noa_all_role_resume():role_id(%d)\n",
610 			ridx);
611 		phl_p2pps_noa_resume_all(phl_info, wrole);
612 	}
613 }
614 
615 void
phl_p2pps_noa_pause_all(struct phl_info_t * phl,struct rtw_wifi_role_t * w_role)616 phl_p2pps_noa_pause_all(struct phl_info_t *phl,
617 	struct rtw_wifi_role_t *w_role)
618 {
619 	struct rtw_phl_p2pps_info *psinfo = phl_to_p2pps_info(phl);
620 	u8 role_idx = get_role_idx(w_role);
621 	struct rtw_phl_noa_info *noa_info = &psinfo->noa_info[role_idx];
622 	u8 i = 0;
623 
624 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_pause_all():====>\n");
625 	//_phl_p2pps_dump_noa_table(phl_to_p2pps_info(phl),noa_info);
626 	if (noa_info->paused) {
627 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_pause_all():This role(%d) NoA is in pause state\n",
628 			role_idx);
629 		goto exit;
630 	}
631 	noa_info->paused = true;
632 	for (i = 0; i < MAX_NOA_DESC; i++) {
633 		struct rtw_phl_noa_desc *desc = &noa_info->noa_desc[i];
634 		_phl_p2pps_noa_disable(psinfo, noa_info, desc, false);
635 	}
636 	//_phl_p2pps_dump_noa_table(phl_to_p2pps_info(phl),noa_info);
637 exit:
638 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_pause_all():<====\n");
639 }
640 
phl_p2pps_noa_all_role_pause(struct phl_info_t * phl_info,u8 band_idx)641 void phl_p2pps_noa_all_role_pause(struct phl_info_t *phl_info, u8 band_idx)
642 {
643 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
644 	struct mr_ctl_t *mr_ctl = phlcom_to_mr_ctrl(phl_com);
645 	struct hw_band_ctl_t *band_ctrl = &(mr_ctl->band_ctrl[band_idx]);
646 	struct rtw_wifi_role_t *wrole = NULL;
647 	u8 ridx = 0;
648 
649 	for (ridx = 0; ridx < MAX_WIFI_ROLE_NUMBER; ridx++) {
650 		if (!(band_ctrl->role_map & BIT(ridx)))
651 			continue;
652 		wrole = rtw_phl_get_wrole_by_ridx(phl_info->phl_com, ridx);
653 		if (wrole == NULL)
654 			continue;
655 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_all_role_pause():role_id(%d)\n",
656 			ridx);
657 		phl_p2pps_noa_pause_all(phl_info, wrole);
658 	}
659 }
660 
phl_p2pps_noa_disable_all(struct phl_info_t * phl_info,struct rtw_wifi_role_t * w_role)661 void phl_p2pps_noa_disable_all(struct phl_info_t *phl_info,
662 	struct rtw_wifi_role_t *w_role)
663 {
664 #ifdef RTW_WKARD_P2PPS_SINGLE_NOA
665 	struct rtw_phl_noa_desc dis_desc = {0};
666 	/*for notify MR for limitation disabled*/
667 	dis_desc.enable = false;
668 	dis_desc.w_role = w_role;
669 	/*open when mr ready*/
670 	//phl_mr_noa_dur_lim_change(phl_info, w_role, &dis_desc);
671 #endif
672 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_disable_all():====>\n");
673 	_phl_p2pps_noa_disable_all(phl_info, w_role);
674 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_disable_all():Disable TSF 32 TOG for role %d\n",
675 		w_role->id);
676 	rtw_hal_tsf32_tog_disable(phl_info->hal, w_role);
677 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]phl_p2pps_noa_disable_all():<====\n");
678 }
679 
phl_p2pps_query_noa_with_cnt255(struct phl_info_t * phl_info,struct rtw_wifi_role_t * w_role,struct rtw_phl_noa_desc * desc)680 void phl_p2pps_query_noa_with_cnt255(struct phl_info_t* phl_info,
681 	struct rtw_wifi_role_t *w_role, struct rtw_phl_noa_desc *desc)
682 {
683 	struct rtw_phl_p2pps_info *psinfo = phl_to_p2pps_info(phl_info);
684 	u8 role_idx = get_role_idx(w_role);
685 	struct rtw_phl_noa_info *info = &psinfo->noa_info[role_idx];
686 	struct rtw_phl_noa_desc *tmp_desc = NULL;
687 
688 	tmp_desc = _phl_p2pps_get_first_noa_desc_with_cnt255(phl_info, info);
689 	if (tmp_desc) {
690 		_phl_p2pps_copy_noa_desc(psinfo, desc, tmp_desc);
691 	} else {
692 		desc->enable = false;
693 		desc->w_role = w_role;
694 	}
695 }
696 
697 enum rtw_phl_status
rtw_phl_p2pps_noa_update(void * phl,struct rtw_phl_noa_desc * in_desc)698 rtw_phl_p2pps_noa_update(void *phl,
699 	struct rtw_phl_noa_desc *in_desc)
700 {
701 	enum rtw_phl_status ret= RTW_PHL_STATUS_FAILURE;
702 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
703 	struct rtw_phl_p2pps_info *psinfo = phl_to_p2pps_info(phl_info);
704 	struct rtw_wifi_role_t *w_role = in_desc->w_role;
705 	u8 role_id = get_role_idx(w_role);
706 	struct rtw_phl_noa_info *noa_info = &psinfo->noa_info[role_id];
707 	u8 desc_idx = in_desc->tag;
708 	struct rtw_phl_noa_desc *noa_desc = &noa_info->noa_desc[desc_idx];
709 
710 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_update():DUMP BEFORE!\n");
711 	_phl_p2pps_dump_noa_table(psinfo, noa_info);
712 
713 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_update():cur FW en desc num = %d\n",
714 		noa_info->en_desc_num);
715 	if (in_desc->enable) {
716 		if (_phl_p2pps_noa_is_all_disable(psinfo, noa_info)) {
717 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_update():roleid(%d) Enable TSF 32 Toggle!\n",
718 					role_id);
719 			rtw_hal_tsf32_tog_enable(phl_info->hal, in_desc->w_role);
720 			/*todo set TSF_ BIT TOG H2C ON*/
721 		}
722 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_update():Tag = %d, NoA enable request!\n",
723 				in_desc->tag);
724 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_update():Tag = %d, NoA disable origninl req first!\n",
725 				in_desc->tag);
726 		_phl_p2pps_noa_disable(psinfo, noa_info, noa_desc, true);
727 		ret = _phl_p2pps_noa_enable(psinfo, noa_info, noa_desc,
728 						in_desc);
729 	} else {
730 		PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_update():Tag = %d, NoA disable request!\n",
731 			in_desc->tag);
732 		ret = _phl_p2pps_noa_disable(psinfo, noa_info, noa_desc, true);
733 		if (_phl_p2pps_noa_is_all_disable(psinfo, noa_info)) {
734 			PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_update():roleid(%d) Disable TSF 32 Toggle!\n",
735 			role_id);
736 			rtw_hal_tsf32_tog_disable(phl_info->hal, in_desc->w_role);
737 			/*todo set TSF_ BIT TOG H2C OFF*/
738 		}
739 	}
740 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_update():DUMP AFTER!\n");
741 	_phl_p2pps_dump_noa_table(psinfo, noa_info);
742 	return ret;
743 }
744 
rtw_phl_p2pps_noa_disable_all(void * phl,struct rtw_wifi_role_t * w_role)745 void rtw_phl_p2pps_noa_disable_all(void *phl,
746 	struct rtw_wifi_role_t *w_role)
747 {
748 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "[NOA]rtw_phl_p2pps_noa_disable_all()!\n");
749 	phl_p2pps_noa_disable_all((struct phl_info_t *)phl, w_role);
750 }
751 
rtw_phl_p2pps_init_ops(void * phl,struct rtw_phl_p2pps_ops * ops)752 void rtw_phl_p2pps_init_ops(void *phl,
753 	struct rtw_phl_p2pps_ops *ops)
754 {
755 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
756 	struct rtw_phl_p2pps_info *psinfo = NULL;
757 
758 	psinfo = phl_to_p2pps_info(phl_info);
759 	psinfo->ops.priv = ops->priv;
760 	psinfo->ops.tsf32_tog_update_noa = ops->tsf32_tog_update_noa;
761 	psinfo->ops.tsf32_tog_update_single_noa = ops->tsf32_tog_update_single_noa;
762 	PHL_TRACE(COMP_PHL_P2PPS, _PHL_INFO_, "rtw_phl_p2pps_init_ops(): init ok\n");
763 }
764 #endif
765 #endif
766