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