1 /******************************************************************************
2 *
3 * Copyright(c) 2019 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 _HAL_STA_C_
16 #include "hal_headers.h"
17
18 void
_hal_sta_rssi_init(struct rtw_phl_stainfo_t * sta)19 _hal_sta_rssi_init(struct rtw_phl_stainfo_t *sta)
20 {
21 sta->hal_sta->rssi_stat.assoc_rssi = 0;
22 sta->hal_sta->rssi_stat.ma_rssi = 0;
23 }
24
25 static enum rtw_hal_status
_hal_bfee_init(struct hal_info_t * hal_info,struct rtw_phl_stainfo_t * sta)26 _hal_bfee_init(struct hal_info_t *hal_info,
27 struct rtw_phl_stainfo_t *sta)
28 {
29 enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
30 struct rtw_wifi_role_t *wrole = NULL;
31 bool enable_bfee = false;
32
33 do {
34 if(NULL == sta)
35 break;
36 wrole = sta->wrole;
37 if(NULL == wrole)
38 break;
39
40 /*only init BFee when wrole cap's bfee and sta cap 's bfer matched */
41
42 if ((wrole->proto_role_cap.he_su_bfme ||
43 wrole->proto_role_cap.he_mu_bfme) &&
44 (sta->asoc_cap.he_su_bfmr || sta->asoc_cap.he_mu_bfmr)) {
45 enable_bfee = true;
46 }
47
48 if ((wrole->proto_role_cap.vht_su_bfme ||
49 wrole->proto_role_cap.vht_mu_bfme) &&
50 (sta->asoc_cap.vht_su_bfmr || sta->asoc_cap.vht_mu_bfmr)) {
51 enable_bfee = true;
52 }
53
54 if (wrole->proto_role_cap.ht_su_bfme &&
55 sta->asoc_cap.ht_su_bfmr)
56 enable_bfee = true;
57
58 if (true == enable_bfee) {
59 /* BFee Functions */
60 if (RTW_HAL_STATUS_SUCCESS !=
61 hal_bf_hw_mac_init_bfee(hal_info,
62 sta->wrole->hw_band)) {
63 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
64 "%s : Init HW MAC BFee Fail\n",
65 __func__);
66 break;
67 }
68 /* BFee CSI parameters*/
69 hal_info->hal_com->csi_para_ctrl_sel = false;
70 if (RTW_HAL_STATUS_SUCCESS !=
71 hal_bf_set_bfee_csi_para(hal_info,
72 hal_info->hal_com->csi_para_ctrl_sel,
73 sta)) {
74 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
75 "%s : Set BFee CSI Para Fail\n",
76 __func__);
77 break;
78 }
79 #ifdef RTW_WKARD_DYNAMIC_BFEE_CAP
80 /* BB Workaround */
81 rtw_hal_bb_dcr_en(hal_info, true);
82 #endif
83
84 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
85 "%s : Enable HW BFee Function Success\n",
86 __func__);
87 }
88 hstatus = RTW_HAL_STATUS_SUCCESS;
89 } while (0);
90
91 return hstatus;
92 }
93
94 static enum rtw_hal_status
_hal_set_default_cctrl_tbl(struct hal_info_t * hal_info,struct rtw_phl_stainfo_t * sta)95 _hal_set_default_cctrl_tbl(struct hal_info_t *hal_info,
96 struct rtw_phl_stainfo_t *sta)
97 {
98 enum rtw_hal_status sts = RTW_HAL_STATUS_FAILURE;
99 struct rtw_hal_mac_ax_cctl_info cctrl, cctl_info_mask;
100 #ifdef RTW_WKARD_DEF_CMACTBL_CFG
101 u16 cfg;
102 enum rf_path path = (hal_info->hal_com->rfpath_tx_num == 1)?RF_PATH_B:RF_PATH_AB;
103 #endif
104 _os_mem_set(hal_to_drvpriv(hal_info), &cctrl, 0, sizeof(struct rtw_hal_mac_ax_cctl_info));
105 _os_mem_set(hal_to_drvpriv(hal_info), &cctl_info_mask, 0, sizeof(struct rtw_hal_mac_ax_cctl_info));
106
107 if (NULL == sta)
108 goto out;
109
110 cctrl.txpwr_mode = 0;
111 cctl_info_mask.txpwr_mode = 0x7;
112 #ifdef RTW_WKARD_DEF_CMACTBL_CFG
113 cfg = rtw_hal_bb_cfg_cmac_tx_ant(hal_info, path);
114 cctrl.ntx_path_en = cfg & 0x0f;
115 cctl_info_mask.ntx_path_en = 0xF;
116 cctrl.path_map_a = ((cfg>>4) & 0x03);
117 cctl_info_mask.path_map_a = 0x3;
118 cctrl.path_map_b = ((cfg>>6) & 0x03);
119 cctl_info_mask.path_map_b = 0x3;
120 cctrl.path_map_c = ((cfg>>8) & 0x03);
121 cctl_info_mask.path_map_c = 0x3;
122 cctrl.path_map_d = ((cfg>>10) & 0x03);
123 cctl_info_mask.path_map_d = 0x3;
124 #else
125 cctrl.ntx_path_en = 0x3;
126 cctl_info_mask.ntx_path_en = 0xF;
127 cctrl.path_map_a = 0x0;
128 cctl_info_mask.path_map_a = 0x3;
129 cctrl.path_map_b = 0x1;
130 cctl_info_mask.path_map_b = 0x3;
131 cctrl.path_map_c = 0x2;
132 cctl_info_mask.path_map_c = 0x3;
133 cctrl.path_map_d = 0x3;
134 cctl_info_mask.path_map_d = 0x3;
135 #endif
136 cctrl.antsel_a = 0x0;
137 cctl_info_mask.antsel_a = 0x1;
138 cctrl.antsel_b = 0x0;
139 cctl_info_mask.antsel_b = 0x1;
140 cctrl.antsel_c = 0x0;
141 cctl_info_mask.antsel_c = 0x1;
142 cctrl.antsel_d = 0x0;
143 cctl_info_mask.antsel_d = 0x1;
144 cctrl.doppler_ctrl = 0;
145 cctl_info_mask.doppler_ctrl = 0x3;
146 cctrl.txpwr_tolerence = 0;
147 cctl_info_mask.txpwr_tolerence = 0xF;
148
149 #ifdef CONFIG_PHL_DEFAULT_MGNT_Q_RPT_EN
150 cctrl.mgq_rpt_en = 1;
151 cctl_info_mask.mgq_rpt_en = 1;
152 #endif
153 sts = rtw_hal_cmc_tbl_cfg(hal_info, &cctrl ,&cctl_info_mask, sta->macid);
154
155 out:
156 return sts;
157 }
158
159 static enum rtw_hal_status
_hal_update_cctrl_tbl(struct hal_info_t * hal_info,struct rtw_phl_stainfo_t * sta)160 _hal_update_cctrl_tbl(struct hal_info_t *hal_info,
161 struct rtw_phl_stainfo_t *sta)
162 {
163 struct rtw_wifi_role_t *wrole = sta->wrole;
164 enum rtw_hal_status sts = RTW_HAL_STATUS_FAILURE;
165 struct rtw_hal_mac_ax_cctl_info cctrl, cctl_info_mask;
166
167 _os_mem_set(hal_to_drvpriv(hal_info), &cctrl, 0, sizeof(struct rtw_hal_mac_ax_cctl_info));
168 _os_mem_set(hal_to_drvpriv(hal_info), &cctl_info_mask, 0, sizeof(struct rtw_hal_mac_ax_cctl_info));
169
170 if (NULL == sta)
171 goto out;
172
173 /*TODO - update cctrl tab from stainfo*/
174 cctrl.disrtsfb = 1;
175 cctl_info_mask.disrtsfb = 1;
176
177 cctrl.disdatafb = 1;
178 cctl_info_mask.disdatafb = 1;
179
180 /*
181 if (!cctrl.disdatafb)
182 cctrl.arfr_ctrl = rtw_hal_bb_get_arfr_idx(hal_info, sta);
183 */
184
185 if (wrole->cap.rty_lmt_rts == 0xFF) {
186 cctrl.rts_txcnt_lmt_sel = 0;
187 } else {
188 cctrl.rts_txcnt_lmt_sel = 1;
189 cctrl.rts_txcnt_lmt = wrole->cap.rty_lmt_rts & 0xF;
190 cctl_info_mask.rts_txcnt_lmt = 0xF;
191 }
192 cctl_info_mask.rts_txcnt_lmt_sel = 1;
193 cctrl.rts_rty_lowest_rate = (sta->chandef.band == BAND_ON_24G) ? (RTW_DATA_RATE_CCK1) : (RTW_DATA_RATE_OFDM6);
194 cctl_info_mask.rts_rty_lowest_rate = 0xF;
195
196 if (wrole->cap.rty_lmt == 0xFF) {
197 cctrl.data_txcnt_lmt_sel = 0;
198 } else {
199 cctrl.data_txcnt_lmt_sel = 1;
200 cctrl.data_tx_cnt_lmt = wrole->cap.rty_lmt & 0x3F;
201 cctl_info_mask.data_tx_cnt_lmt = 0x3F;
202 }
203 cctl_info_mask.data_txcnt_lmt_sel = 1;
204
205 /* hana_todo: follow wd agg_num settings before updating cmac tbl while addba handshake is ready */
206 /* cctrl.max_agg_num_sel = 1;
207 cctl_info_mask.max_agg_num_sel = 1;
208
209 cctrl.max_agg_num = sta->asoc_cap.num_ampdu - 1;
210 cctl_info_mask.max_agg_num = 0xFF;
211 */
212 if (cctrl.max_agg_num > 0x3F) {
213 cctrl.ba_bmap = 1;
214 cctl_info_mask.ba_bmap = 0x3;
215 }
216
217 if (sta->wrole->type == PHL_RTYPE_STATION || sta->wrole->type == PHL_RTYPE_TDLS) {
218 cctrl.uldl = 1;
219 cctl_info_mask.uldl = 1;
220 } else {
221 cctrl.uldl = 0;
222 cctl_info_mask.uldl = 1;
223 }
224
225 cctrl.multi_port_id = sta->wrole->hw_port;
226 cctl_info_mask.multi_port_id = 0x7;
227
228 if (sta->wrole->type == PHL_RTYPE_AP) {
229 cctrl.data_dcm = 0; /*(sta->asoc_cap.dcm_max_const_rx > 0)*/
230 cctl_info_mask.data_dcm = 1;
231 }
232
233 if (sta->asoc_cap.pkt_padding == 3) {
234 /* follow PPE threshold */
235 u8 ppe16 = 0, ppe8 = 0;
236 u8 nss = sta->asoc_cap.nss_rx;
237
238 /* bw = 20MHz */
239 ppe16 = (sta->asoc_cap.ppe_thr[nss - 1][CHANNEL_WIDTH_20] & 0x7);
240 ppe8 = (sta->asoc_cap.ppe_thr[nss - 1][CHANNEL_WIDTH_20]>>3) & 0x7;
241
242 if ((ppe16 != 7) && (ppe8 == 7)) {
243 cctrl.nominal_pkt_padding = 2;
244 cctl_info_mask.nominal_pkt_padding = 0x3;
245 } else if (ppe8 != 7) {
246 cctrl.nominal_pkt_padding = 1;
247 cctl_info_mask.nominal_pkt_padding = 0x3;
248 } else {
249 cctrl.nominal_pkt_padding = 0;
250 cctl_info_mask.nominal_pkt_padding = 0x3;
251 }
252 /* bw = 40MHz */
253 ppe16 = (sta->asoc_cap.ppe_thr[nss - 1][CHANNEL_WIDTH_40] & 0x7);
254 ppe8 = (sta->asoc_cap.ppe_thr[nss - 1][CHANNEL_WIDTH_40]>>3) & 0x7;
255
256 if ((ppe16 != 7) && (ppe8 == 7)) {
257 cctrl.nominal_pkt_padding40 = 2;
258 cctl_info_mask.nominal_pkt_padding40 = 0x3;
259 } else if (ppe8 != 7) {
260 cctrl.nominal_pkt_padding40 = 1;
261 cctl_info_mask.nominal_pkt_padding40 = 0x3;
262 } else {
263 cctrl.nominal_pkt_padding40 = 0;
264 cctl_info_mask.nominal_pkt_padding40 = 0x3;
265 }
266 /* bw = 80MHz */
267 ppe16 = (sta->asoc_cap.ppe_thr[nss - 1][CHANNEL_WIDTH_80] & 0x7);
268 ppe8 = (sta->asoc_cap.ppe_thr[nss - 1][CHANNEL_WIDTH_80]>>3) & 0x7;
269
270 if ((ppe16 != 7) && (ppe8 == 7)) {
271 cctrl.nominal_pkt_padding80 = 2;
272 cctl_info_mask.nominal_pkt_padding80 = 0x3;
273 } else if (ppe8 != 7) {
274 cctrl.nominal_pkt_padding80 = 1;
275 cctl_info_mask.nominal_pkt_padding80 = 0x3;
276 } else {
277 cctrl.nominal_pkt_padding80 = 0;
278 cctl_info_mask.nominal_pkt_padding80 = 0x3;
279 }
280 } else {
281 cctrl.nominal_pkt_padding = sta->asoc_cap.pkt_padding;
282 cctrl.nominal_pkt_padding40 = sta->asoc_cap.pkt_padding;
283 cctrl.nominal_pkt_padding80 = sta->asoc_cap.pkt_padding;
284 cctl_info_mask.nominal_pkt_padding = 0x3;
285 cctl_info_mask.nominal_pkt_padding40 = 0x3;
286 cctl_info_mask.nominal_pkt_padding80 = 0x3;
287 }
288
289 if (sta->wmode&WLAN_MD_11AX) {
290 /**
291 * bsr_queue_size_format:
292 * 1: buffer status unit is 802.11, HE mode
293 * 0: buffer status unit is 802.11, legacy mode
294 **/
295 cctrl.bsr_queue_size_format = 1;
296 cctl_info_mask.bsr_queue_size_format = 1;
297 }
298
299 sts = rtw_hal_cmc_tbl_cfg(hal_info, &cctrl, &cctl_info_mask, sta->macid);
300
301 out:
302 return sts;
303 }
304
305 static enum rtw_hal_status
_hal_update_dctrl_tbl(struct hal_info_t * hal_info,struct rtw_phl_stainfo_t * sta)306 _hal_update_dctrl_tbl(struct hal_info_t *hal_info,
307 struct rtw_phl_stainfo_t *sta)
308 {
309 enum rtw_hal_status sts = RTW_HAL_STATUS_FAILURE;
310 struct mac_ax_dctl_info dctrl, dctl_info_mask;
311
312 if (NULL == sta)
313 goto out;
314
315 _os_mem_set(hal_to_drvpriv(hal_info), &dctrl, 0, sizeof(struct mac_ax_dctl_info));
316 _os_mem_set(hal_to_drvpriv(hal_info), &dctl_info_mask, 0, sizeof(struct mac_ax_dctl_info));
317
318 #ifdef CONFIG_PHL_CSUM_OFFLOAD_RX
319 dctrl.chksum_offload_en = 1;
320 dctl_info_mask.chksum_offload_en = 1;
321 dctrl.with_llc = 1;
322 dctl_info_mask.with_llc = 1;
323 #endif /*CONFIG_PHL_CSUM_OFFLOAD_RX*/
324 sts = rtw_hal_dmc_tbl_cfg(hal_info, &dctrl, &dctl_info_mask, sta->macid);
325
326 out:
327 return sts;
328 }
329
330 enum rtw_hal_status
_hal_update_ba_cam(struct hal_info_t * hal_info,u8 valid,u16 macid,u8 dialog_token,u16 timeout,u16 start_seq_num,u16 ba_policy,u16 tid,u16 buf_size,u8 camid)331 _hal_update_ba_cam(struct hal_info_t *hal_info, u8 valid, u16 macid,
332 u8 dialog_token, u16 timeout, u16 start_seq_num,
333 u16 ba_policy, u16 tid, u16 buf_size, u8 camid)
334 {
335 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
336 void *drv = hal_to_drvpriv(hal_info);
337 struct mac_ax_bacam_info ba_cam = {0};
338 FUNCIN();
339 _os_mem_set(drv, &ba_cam, 0, sizeof(ba_cam));
340 ba_cam.valid = valid;
341 ba_cam.init_req = 1;
342 ba_cam.entry_idx = camid;
343 ba_cam.tid = tid;
344 ba_cam.macid = (u8)macid;
345 if (buf_size > 64)
346 ba_cam.bmap_size = 4;
347 else
348 ba_cam.bmap_size = 0;
349 ba_cam.ssn = start_seq_num;
350
351 PHL_INFO("[BACAM] ba_cam.valid = %d, ba_cam.init_req = %d, ba_cam.entry_idx = %d\n",
352 ba_cam.valid,
353 ba_cam.init_req,
354 ba_cam.entry_idx);
355 PHL_INFO("[BACAM] ba_cam.tid = %d, ba_cam.macid = %d, ba_cam.bmap_size = %d\n",
356 ba_cam.tid,
357 ba_cam.macid,
358 ba_cam.bmap_size);
359 PHL_INFO("[BACAM] ba_cam.ssn = 0x%X\n",
360 ba_cam.ssn);
361
362 hal_status = rtw_hal_bacam_cfg(hal_info, &ba_cam);
363
364 if (RTW_HAL_STATUS_FAILURE == hal_status) {
365 PHL_WARN("rtw_hal_bacam_cfg fail 0x%08X\n", hal_status);
366
367 }
368
369 FUNCOUT();
370 return hal_status;
371 }
372
373 enum rtw_hal_status
rtw_hal_start_ba_session(void * hal,struct rtw_phl_stainfo_t * sta,u8 dialog_token,u16 timeout,u16 start_seq_num,u16 ba_policy,u16 tid,u16 buf_size)374 rtw_hal_start_ba_session(void *hal, struct rtw_phl_stainfo_t *sta,
375 u8 dialog_token, u16 timeout, u16 start_seq_num,
376 u16 ba_policy, u16 tid, u16 buf_size)
377 {
378 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
379 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
380 u8 idx = 0;
381
382 if (sta->hal_sta->ba_ctl.count == MAX_BAENTRY) {
383 PHL_INFO("No avail standard entry found\n");
384 if (tid != 0)
385 goto out;
386 else {
387 for (idx = 0; idx < MAX_BAENTRY; idx++) {
388 if (sta->hal_sta->ba_ctl.tid[idx] != 0) {
389 PHL_INFO("Remove old entry(%d) tid(%d)\n",
390 idx, sta->hal_sta->ba_ctl.tid[idx]);
391 hal_status = _hal_update_ba_cam(hal_info, 0, sta->macid, 0,
392 0, 0, 0, 0, 0, idx);
393 if (hal_status == RTW_HAL_STATUS_SUCCESS) {
394 sta->hal_sta->ba_ctl.used_map[idx] = false;
395 sta->hal_sta->ba_ctl.count--;
396 break;
397 }
398 } else {
399 PHL_INFO("Use existing entry(%d)\n", idx);
400 sta->hal_sta->ba_ctl.used_map[idx] = false;
401 sta->hal_sta->ba_ctl.count--;
402 break;
403 }
404 }
405 }
406 }
407 for (idx = 0; idx < MAX_BAENTRY; idx++) {
408 if (!sta->hal_sta->ba_ctl.used_map[idx])
409 break;
410 }
411 if (idx == MAX_BAENTRY) {
412 PHL_WARN("No avail standard entry found but count is(%d)\n",
413 sta->hal_sta->ba_ctl.count);
414 goto out;
415 }
416 hal_status = _hal_update_ba_cam(hal_info, 1, sta->macid, dialog_token,
417 timeout, start_seq_num, ba_policy, tid,
418 buf_size, idx);
419 if (RTW_HAL_STATUS_SUCCESS != hal_status)
420 goto out;
421
422 sta->hal_sta->ba_ctl.used_map[idx] = 1;
423 sta->hal_sta->ba_ctl.tid[idx] = (u8)tid;
424 sta->hal_sta->ba_ctl.count++;
425 out:
426 return hal_status;
427 }
428
429 enum rtw_hal_status
rtw_hal_stop_ba_session(void * hal,struct rtw_phl_stainfo_t * sta,u16 tid)430 rtw_hal_stop_ba_session(void *hal, struct rtw_phl_stainfo_t *sta, u16 tid)
431 {
432 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
433 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
434 u8 i;
435
436 for (i = 0; i < MAX_BAENTRY; i++) {
437 if (sta->hal_sta->ba_ctl.used_map[i] &&
438 ((u8)tid == sta->hal_sta->ba_ctl.tid[i])) {
439 hal_status = _hal_update_ba_cam(hal_info, 0, sta->macid, 0,
440 0, 0, 0, 0, 0, i);
441 break;
442 }
443 }
444 if (RTW_HAL_STATUS_SUCCESS != hal_status)
445 goto out;
446 sta->hal_sta->ba_ctl.used_map[i] = 0;
447 sta->hal_sta->ba_ctl.tid[i] = 0xff;
448 sta->hal_sta->ba_ctl.count--;
449 out:
450 return hal_status;
451 }
452
453
454
455 enum rtw_hal_status
rtw_hal_stainfo_init(void * hal,struct rtw_phl_stainfo_t * sta)456 rtw_hal_stainfo_init(void *hal, struct rtw_phl_stainfo_t *sta)
457 {
458 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
459 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
460 void *drv = hal_to_drvpriv(hal_info);
461
462 sta->hal_sta = _os_mem_alloc(drv, sizeof(struct rtw_hal_stainfo_t));
463 if (sta->hal_sta == NULL) {
464 PHL_ERR("alloc hal_sta failed\n");
465 goto error_exit;
466 }
467
468 sta->hal_sta->hw_cfg_tab =
469 _os_mem_alloc(drv, sizeof(struct rtw_hw_cfg_tab));
470 if (sta->hal_sta->hw_cfg_tab == NULL) {
471 PHL_ERR("alloc hw_cfg_tab failed\n");
472 goto error_hsta_mem;
473 }
474
475 hal_status = rtw_hal_bb_stainfo_init(hal_info, sta);
476 if (hal_status != RTW_HAL_STATUS_SUCCESS) {
477 PHL_ERR("alloc bb_stainfo failed\n");
478 goto error_hw_cfg_tab;
479 }
480 /* Init lock for tx statistics */
481 _os_spinlock_init(drv, &sta->hal_sta->trx_stat.tx_sts_lock);
482 /* Init STA RSSI Statistics */
483 _hal_sta_rssi_init(sta);
484
485 return hal_status;
486
487 error_hw_cfg_tab :
488 if (sta->hal_sta->hw_cfg_tab) {
489 _os_mem_free(drv, sta->hal_sta->hw_cfg_tab,
490 sizeof(struct rtw_hw_cfg_tab));
491 sta->hal_sta->hw_cfg_tab = NULL;
492 }
493 error_hsta_mem :
494 if (sta->hal_sta) {
495 _os_mem_free(drv, sta->hal_sta,
496 sizeof(struct rtw_hal_stainfo_t));
497 sta->hal_sta = NULL;
498 }
499 error_exit :
500 return hal_status;
501 }
502
503 enum rtw_hal_status
rtw_hal_stainfo_deinit(void * hal,struct rtw_phl_stainfo_t * sta)504 rtw_hal_stainfo_deinit(void *hal, struct rtw_phl_stainfo_t *sta)
505 {
506 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
507 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
508 void *drv = hal_to_drvpriv(hal_info);
509
510 if (sta->hal_sta) {
511 /* Free lock for tx statistics */
512 _os_spinlock_free(drv, &sta->hal_sta->trx_stat.tx_sts_lock);
513 hal_status = rtw_hal_bb_stainfo_deinit(hal_info, sta);
514 if (hal_status != RTW_HAL_STATUS_SUCCESS)
515 PHL_ERR("bb_stainfo deinit failed\n");
516
517 if (sta->hal_sta->hw_cfg_tab) {
518 _os_mem_free(drv, sta->hal_sta->hw_cfg_tab,
519 sizeof(struct rtw_hw_cfg_tab));
520 sta->hal_sta->hw_cfg_tab = NULL;
521 }
522
523 _os_mem_free(drv, sta->hal_sta,
524 sizeof(struct rtw_hal_stainfo_t));
525 sta->hal_sta = NULL;
526 }
527
528 return hal_status;
529 }
_hal_sta_set_default_value(struct hal_info_t * hal_info,struct rtw_phl_stainfo_t * sta)530 static void _hal_sta_set_default_value(struct hal_info_t *hal_info,
531 struct rtw_phl_stainfo_t *sta)
532 {
533 u8 i;
534 sta->hal_sta->ra_info.ra_registered = false;
535 sta->hal_sta->ba_ctl.count = 0;
536 for (i = 0; i<MAX_BAENTRY; i++) {
537 sta->hal_sta->ba_ctl.tid[i] = 0xff;
538 sta->hal_sta->ba_ctl.used_map[i] = 0;
539 }
540 }
541
542 enum rtw_hal_status
rtw_hal_add_sta_entry(void * hal,struct rtw_phl_stainfo_t * sta)543 rtw_hal_add_sta_entry(void *hal, struct rtw_phl_stainfo_t *sta)
544 {
545 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
546
547 _hal_sta_set_default_value(hal_info, sta);
548
549 /*add mac address-cam*/
550 if (rtw_hal_mac_addr_cam_add_entry(hal_info, sta) !=
551 RTW_HAL_STATUS_SUCCESS) {
552 PHL_ERR("rtw_hal_mac_addr_cam_add_entry failed\n");
553 goto _exit;
554 }
555
556 /*update default cmac table*/
557 if (_hal_set_default_cctrl_tbl(hal_info, sta) !=
558 RTW_HAL_STATUS_SUCCESS) {
559 PHL_WARN("_hal_set_default_cctrl_tbl failed\n");
560 /* goto _exit; */ /* shall be unmark after header FW is ready */
561 }
562
563 if (_hal_update_dctrl_tbl(hal_info, sta) !=
564 RTW_HAL_STATUS_SUCCESS) {
565 PHL_WARN("_hal_set_default_dctrl_tbl failed\n");
566 /* goto _exit; */
567 }
568
569 /*add bb stainfo*/
570 if (rtw_hal_bb_stainfo_add(hal_info, sta) !=
571 RTW_HAL_STATUS_SUCCESS) {
572 PHL_ERR("rtw_hal_bb_stainfo_add failed\n");
573 goto _err_bbsta_add;
574 }
575 return RTW_HAL_STATUS_SUCCESS;
576
577 _err_bbsta_add:
578 rtw_hal_mac_addr_cam_del_entry(hal_info, sta);
579 _exit:
580 return RTW_HAL_STATUS_FAILURE;
581 }
582
583 enum rtw_hal_status
rtw_hal_update_sta_entry(void * hal,struct rtw_phl_stainfo_t * sta,bool is_connect)584 rtw_hal_update_sta_entry(void *hal, struct rtw_phl_stainfo_t *sta,
585 bool is_connect)
586 {
587 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
588 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
589 enum phl_upd_mode mode = PHL_UPD_STA_CON_DISCONN;
590
591 /*update cmac table*/
592 if (RTW_HAL_STATUS_SUCCESS != _hal_update_cctrl_tbl(hal_info, sta))
593 PHL_WARN("_hal_update_cctrl_tbl failed\n");
594
595 /*update dmac table*/
596 if (RTW_HAL_STATUS_SUCCESS != _hal_update_dctrl_tbl(hal_info, sta))
597 PHL_WARN("_hal_update_dctrl_tbl failed\n");
598
599 /*change mac address-cam & mac_h2c_join_info*/
600 hal_status = rtw_hal_mac_addr_cam_change_entry(hal_info, sta, mode, is_connect);
601 if (hal_status != RTW_HAL_STATUS_SUCCESS) {
602 PHL_ERR("rtw_hal_mac_addr_cam_change_entry failed\n");
603 }
604
605 if (is_connect) {
606
607 if (RTW_HAL_STATUS_SUCCESS != _hal_bfee_init(hal_info, sta)) {
608 PHL_ERR("_hal_bfee_init Fail!\n");
609 }
610
611 if (sta->hal_sta->rssi_stat.assoc_rssi == 0
612 #ifdef CONFIG_PHL_TDLS
613 /* There is no association frame for TDLS connection */
614 && sta->wrole->type != PHL_RTYPE_TDLS
615 #endif
616 ) {
617 PHL_ERR("%s macid:%d assoc_rssi == 0\n", __func__, sta->macid);
618 _os_warn_on(1);
619 }
620
621 hal_status = rtw_hal_bb_upt_ramask(hal_info, sta);
622 if (hal_status != RTW_HAL_STATUS_SUCCESS)
623 PHL_ERR("rtw_hal_bb_upt_ramask failed\n");
624
625 hal_status = rtw_hal_bb_ra_register(hal_info, sta);
626 if (hal_status != RTW_HAL_STATUS_SUCCESS)
627 PHL_ERR("rtw_hal_bb_ra_register failed\n");
628 hal_info->hal_com->assoc_sta_cnt++;
629
630 if (sta->wmode & WLAN_MD_11AX) {
631 rtw_hal_bb_set_sta_id(hal_info, sta->aid, sta->wrole->hw_band);
632 rtw_hal_bb_set_bss_color(hal_info, sta->asoc_cap.bsscolor,
633 sta->wrole->hw_band);
634 rtw_hal_bb_set_tb_pwr_ofst(hal_info, 0, sta->wrole->hw_band);
635 }
636 /* reset rssi stat value */
637 sta->hal_sta->rssi_stat.ma_rssi_mgnt = 0;
638 }
639 else {
640 hal_status = rtw_hal_bb_ra_deregister(hal_info, sta);
641 if (hal_status != RTW_HAL_STATUS_SUCCESS)
642 PHL_ERR("rtw_hal_bb_ra_deregister failed\n");
643 hal_info->hal_com->assoc_sta_cnt--;
644 /* reset drv rssi_stat */
645 _hal_sta_rssi_init(sta);
646 _hal_sta_set_default_value(hal_info, sta);
647 }
648 /* reset bb rssi_stat */
649 rtw_hal_bb_media_status_update(hal_info, sta, is_connect);
650
651 return hal_status;
652 }
653
654 enum rtw_hal_status
rtw_hal_change_sta_entry(void * hal,struct rtw_phl_stainfo_t * sta,enum phl_upd_mode mode)655 rtw_hal_change_sta_entry(void *hal, struct rtw_phl_stainfo_t *sta,
656 enum phl_upd_mode mode)
657 {
658 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
659 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
660 bool is_connect = false;
661
662 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s: sta->macid(0x%X), mode(%d)\n",
663 __FUNCTION__, sta->macid , mode);
664 /*update cmac table*/
665 if (RTW_HAL_STATUS_SUCCESS != _hal_update_cctrl_tbl(hal_info, sta))
666 PHL_WARN("_hal_update_cctrl_tbl failed\n");
667
668 /*update dmac table*/
669 if (RTW_HAL_STATUS_SUCCESS != _hal_update_dctrl_tbl(hal_info, sta))
670 PHL_WARN("_hal_update_dctrl_tbl failed\n");
671
672 /*change mac address-cam & mac_h2c_join_info */
673 is_connect = (sta->wrole->mstate == MLME_LINKED) ? true : false;
674 hal_status = rtw_hal_mac_addr_cam_change_entry(hal_info, sta, mode, is_connect);
675 if (hal_status != RTW_HAL_STATUS_SUCCESS)
676 PHL_ERR("rtw_hal_mac_addr_cam_change_entry failed\n");
677
678 hal_status = rtw_hal_bb_ra_update(hal_info, sta);
679 if (hal_status != RTW_HAL_STATUS_SUCCESS)
680 PHL_ERR("rtw_hal_bb_ra_update failed\n");
681
682 return hal_status;
683 }
684
685 enum rtw_hal_status
rtw_hal_del_sta_entry(void * hal,struct rtw_phl_stainfo_t * sta)686 rtw_hal_del_sta_entry(void *hal, struct rtw_phl_stainfo_t *sta)
687 {
688 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
689 enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
690
691 _hal_sta_set_default_value(hal_info, sta);
692
693 hal_status = rtw_hal_mac_addr_cam_del_entry(hal_info, sta);
694 if (hal_status != RTW_HAL_STATUS_SUCCESS)
695 PHL_ERR("mac_addr_cam_del_entry failed\n");
696
697 hal_status = rtw_hal_bb_stainfo_delete(hal_info, sta);
698 if (hal_status != RTW_HAL_STATUS_SUCCESS)
699 PHL_ERR("bb_stainfo deinit failed\n");
700
701 return hal_status;
702 }
703
rtw_hal_get_sta_rssi(struct rtw_phl_stainfo_t * sta)704 u8 rtw_hal_get_sta_rssi(struct rtw_phl_stainfo_t *sta)
705 {
706 u8 rssi = (sta->hal_sta->rssi_stat.rssi >> 1);
707
708 return rssi;
709 }
710
rtw_hal_get_sta_rssi_bcn(struct rtw_phl_stainfo_t * sta)711 u8 rtw_hal_get_sta_rssi_bcn(struct rtw_phl_stainfo_t *sta)
712 {
713 u8 rssi = (sta->hal_sta->rssi_stat.rssi_bcn >> 1);
714
715 return rssi;
716 }
717
rtw_hal_is_sta_linked(void * hal,struct rtw_phl_stainfo_t * sta)718 bool rtw_hal_is_sta_linked(void *hal, struct rtw_phl_stainfo_t *sta)
719 {
720 return (sta->hal_sta->ra_info.ra_registered == true) ? true : false;
721 }
722
723 enum rtw_hal_status
rtw_hal_set_edca(void * hal,struct rtw_wifi_role_t * wrole,u8 ac,u32 edca)724 rtw_hal_set_edca(void *hal, struct rtw_wifi_role_t *wrole, u8 ac, u32 edca)
725 {
726 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
727 enum rtw_hal_status hal_status;
728
729
730 hal_status = rtw_hal_mac_set_edca(hal_info->hal_com, wrole->hw_band,
731 wrole->hw_wmm, ac, edca);
732
733 return hal_status;
734 }
735
736 enum rtw_hal_status
rtw_hal_cfg_tx_ampdu(void * hal,struct rtw_phl_stainfo_t * sta)737 rtw_hal_cfg_tx_ampdu(void *hal, struct rtw_phl_stainfo_t *sta)
738 {
739 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
740 enum rtw_hal_status hsts = RTW_HAL_STATUS_FAILURE;
741
742 /* update ampdu configuration */
743 if (64 == sta->asoc_cap.num_ampdu)
744 hsts = rtw_hal_mac_set_hw_ampdu_cfg(hal_info, 0, 0x3F, 0xA5);
745 else if (128 == sta->asoc_cap.num_ampdu)
746 hsts = rtw_hal_mac_set_hw_ampdu_cfg(hal_info, 0, 0x7F, 0xAB);
747
748 if (RTW_HAL_STATUS_SUCCESS != hsts)
749 goto out;
750
751 /* todo: update cmac table */
752
753 out:
754 return hsts;
755 }
756
757 enum rtw_hal_status
rtw_hal_set_sta_rx_sts(struct rtw_phl_stainfo_t * sta,u8 rst,struct rtw_r_meta_data * meta)758 rtw_hal_set_sta_rx_sts(struct rtw_phl_stainfo_t *sta, u8 rst,
759 struct rtw_r_meta_data *meta)
760 {
761 if (rst) {
762 sta->hal_sta->trx_stat.rx_ok_cnt = 0;
763 sta->hal_sta->trx_stat.rx_err_cnt = 0;
764 } else {
765 if (meta->crc32 || meta->icverr)
766 sta->hal_sta->trx_stat.rx_err_cnt++;
767 else
768 sta->hal_sta->trx_stat.rx_ok_cnt++;
769 }
770 /* TODO: rx_rate_plurality */
771 return RTW_HAL_STATUS_SUCCESS;
772 }
773
774 enum rtw_hal_status
rtw_hal_query_rainfo(void * hal,struct rtw_hal_stainfo_t * hal_sta,struct rtw_phl_rainfo * phl_rainfo)775 rtw_hal_query_rainfo(void *hal, struct rtw_hal_stainfo_t *hal_sta,
776 struct rtw_phl_rainfo *phl_rainfo)
777 {
778 enum rtw_hal_status hal_sts = RTW_HAL_STATUS_FAILURE;
779
780 hal_sts = rtw_hal_bb_query_rainfo(hal, hal_sta, phl_rainfo);
781
782
783 return hal_sts;
784 }
785
786 /**
787 * rtw_hal_query_txsts_rpt() - get txok and tx retry info
788 * @hal: struct hal_info_t *
789 * @macid: indicate the first macid that you want to query.
790 * Return rtw_hal_bb_query_txsts_rpt's return value in enum rtw_hal_status type.
791 */
792 enum rtw_hal_status
rtw_hal_query_txsts_rpt(void * hal,u16 macid)793 rtw_hal_query_txsts_rpt(void *hal, u16 macid)
794 {
795 struct hal_info_t *hal_info = (struct hal_info_t *)hal;
796 /*get tx ok and tx retry statistics*/
797 if (RTW_HAL_STATUS_SUCCESS != rtw_hal_bb_query_txsts_rpt(hal_info, macid, 0xFFFF))
798 return RTW_HAL_STATUS_FAILURE;
799 else
800 return RTW_HAL_STATUS_SUCCESS;
801 }
802
803