xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8189fs/hal/phydm/phydm_rssi_monitor.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017  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  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 
26 /*@************************************************************
27  * include files
28  ************************************************************/
29 
30 #include "mp_precomp.h"
31 #include "phydm_precomp.h"
32 
33 #ifdef PHYDM_SUPPORT_RSSI_MONITOR
34 
phydm_rssi_monitor_h2c(void * dm_void,u8 macid)35 void phydm_rssi_monitor_h2c(void *dm_void, u8 macid)
36 {
37 	struct dm_struct *dm = (struct dm_struct *)dm_void;
38 	struct ra_table *ra_t = &dm->dm_ra_table;
39 	struct cmn_sta_info *sta = dm->phydm_sta_info[macid];
40 	struct ra_sta_info *ra = NULL;
41 	#ifdef CONFIG_BEAMFORMING
42 	struct bf_cmn_info *bf = NULL;
43 	#endif
44 	u8 h2c[H2C_MAX_LENGTH] = {0};
45 	u8 stbc_en, ldpc_en;
46 	u8 bf_en = 0;
47 	u8 is_rx, is_tx;
48 
49 	if (is_sta_active(sta)) {
50 		ra = &sta->ra_info;
51 	} else {
52 		PHYDM_DBG(dm, DBG_RSSI_MNTR, "[Warning] %s\n", __func__);
53 		return;
54 	}
55 
56 	PHYDM_DBG(dm, DBG_RSSI_MNTR, "%s ======>\n", __func__);
57 	PHYDM_DBG(dm, DBG_RSSI_MNTR, "MACID=%d\n", sta->mac_id);
58 
59 	is_rx = (ra->txrx_state == RX_STATE) ? 1 : 0;
60 	is_tx = (ra->txrx_state == TX_STATE) ? 1 : 0;
61 	stbc_en = (sta->stbc_en) ? 1 : 0;
62 	ldpc_en = (sta->ldpc_en) ? 1 : 0;
63 
64 	#ifdef CONFIG_BEAMFORMING
65 	bf = &sta->bf_info;
66 
67 	if ((bf->ht_beamform_cap & BEAMFORMING_HT_BEAMFORMEE_ENABLE) ||
68 	    (bf->vht_beamform_cap & BEAMFORMING_VHT_BEAMFORMEE_ENABLE))
69 		bf_en = 1;
70 	#endif
71 
72 	PHYDM_DBG(dm, DBG_RSSI_MNTR, "RA_th_ofst=(( %s%d ))\n",
73 		  ((ra_t->ra_ofst_direc) ? "+" : "-"), ra_t->ra_th_ofst);
74 
75 	h2c[0] = sta->mac_id;
76 	h2c[1] = 0;
77 	h2c[2] = sta->rssi_stat.rssi;
78 	h2c[3] = is_rx | (stbc_en << 1) |
79 		     ((dm->noisy_decision & 0x1) << 2) | (bf_en << 6);
80 	h2c[4] = (ra_t->ra_th_ofst & 0x7f) |
81 		     ((ra_t->ra_ofst_direc & 0x1) << 7);
82 	h2c[5] = 0;
83 	h2c[6] = ((ra_t->ra_trigger_mode) << 2);
84 
85 	PHYDM_DBG(dm, DBG_RSSI_MNTR, "PHYDM h2c[0x42]=0x%x %x %x %x %x %x %x\n",
86 		  h2c[6], h2c[5], h2c[4], h2c[3], h2c[2], h2c[1], h2c[0]);
87 
88 	#if (RTL8188E_SUPPORT)
89 	if (dm->support_ic_type == ODM_RTL8188E)
90 		odm_ra_set_rssi_8188e(dm, sta->mac_id, sta->rssi_stat.rssi);
91 	else
92 	#endif
93 	{
94 		odm_fill_h2c_cmd(dm, ODM_H2C_RSSI_REPORT, H2C_MAX_LENGTH, h2c);
95 	}
96 }
97 
98 #if (DM_ODM_SUPPORT_TYPE == ODM_AP)
phydm_sta_rssi_init(void * dm_void,u8 macid,u8 init_rssi)99 void phydm_sta_rssi_init(void *dm_void, u8 macid, u8 init_rssi)
100 {
101 	struct dm_struct *dm = (struct dm_struct *)dm_void;
102 	struct cmn_sta_info *sta = NULL;
103 	struct rssi_info *rssi_t = NULL;
104 
105 	PHYDM_DBG(dm, DBG_RSSI_MNTR, "%s ======>\n", __func__);
106 
107 	sta = dm->phydm_sta_info[macid];
108 	rssi_t = &sta->rssi_stat;
109 
110 	rssi_t->rssi_acc = (init_rssi << RSSI_MA);
111 	rssi_t->rssi = init_rssi;
112 }
113 #endif
phydm_calculate_rssi_min_max(void * dm_void)114 void phydm_calculate_rssi_min_max(void *dm_void)
115 {
116 	struct dm_struct *dm = (struct dm_struct *)dm_void;
117 	struct cmn_sta_info *sta;
118 	s8 rssi_max_tmp = 0, rssi_min_tmp = 100;
119 	u8 i;
120 	u8 sta_cnt = 0;
121 
122 	if (!dm->is_linked)
123 		return;
124 
125 	PHYDM_DBG(dm, DBG_RSSI_MNTR, "%s ======>\n", __func__);
126 
127 	for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
128 		sta = dm->phydm_sta_info[i];
129 		if (is_sta_active(sta)) {
130 			sta_cnt++;
131 
132 			if (sta->rssi_stat.rssi < rssi_min_tmp) {
133 				rssi_min_tmp = sta->rssi_stat.rssi;
134 				dm->rssi_min_macid = i;
135 			}
136 
137 			if (sta->rssi_stat.rssi > rssi_max_tmp) {
138 				rssi_max_tmp = sta->rssi_stat.rssi;
139 				dm->rssi_max_macid = i;
140 			}
141 
142 			/*@[Send RSSI to FW]*/
143 			if (!sta->ra_info.disable_ra)
144 				phydm_rssi_monitor_h2c(dm, i);
145 
146 			if (sta_cnt == dm->number_linked_client)
147 				break;
148 		}
149 	}
150 	dm->pre_rssi_min = dm->rssi_min;
151 
152 #if (DM_ODM_SUPPORT_TYPE == ODM_AP)
153 	if (dm->number_linked_client == 0)
154 		return;
155 #endif
156 	dm->rssi_max = (u8)rssi_max_tmp;
157 	dm->rssi_min = (u8)rssi_min_tmp;
158 }
159 
phydm_rssi_monitor_check(void * dm_void)160 void phydm_rssi_monitor_check(void *dm_void)
161 {
162 	struct dm_struct *dm = (struct dm_struct *)dm_void;
163 
164 	if (!(dm->support_ability & ODM_BB_RSSI_MONITOR))
165 		return;
166 
167 	/*@for AP watchdog period = 1 sec*/
168 	if ((dm->phydm_sys_up_time % 2) == 1)
169 		return;
170 
171 	PHYDM_DBG(dm, DBG_RSSI_MNTR, "%s ======>\n", __func__);
172 
173 	phydm_calculate_rssi_min_max(dm);
174 
175 	PHYDM_DBG(dm, DBG_RSSI_MNTR, "RSSI {max, min} = {%d, %d}\n",
176 		  dm->rssi_max, dm->rssi_min);
177 }
178 
phydm_rssi_monitor_init(void * dm_void)179 void phydm_rssi_monitor_init(void *dm_void)
180 {
181 	struct dm_struct *dm = (struct dm_struct *)dm_void;
182 	struct ra_table *ra_tab = &dm->dm_ra_table;
183 
184 	dm->pre_rssi_min = 0;
185 	dm->rssi_max = 0;
186 	dm->rssi_min = 0;
187 }
188 
189 #endif
190