xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/hal_g6/hal_sta.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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