1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "mp_precomp.h"
19#include "phydm_precomp.h"
20
21u8 odm_get_auto_channel_select_result(void *dm_void, u8 band)
22{
23 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
24 struct acs_info *acs = &dm->dm_acs;
25 u8 result;
26
27 if (band == ODM_BAND_2_4G) {
28 ODM_RT_TRACE(
29 dm, ODM_COMP_ACS,
30 "[struct acs_info] %s(): clean_channel_2g(%d)\n",
31 __func__, acs->clean_channel_2g);
32 result = (u8)acs->clean_channel_2g;
33 } else {
34 ODM_RT_TRACE(
35 dm, ODM_COMP_ACS,
36 "[struct acs_info] %s(): clean_channel_5g(%d)\n",
37 __func__, acs->clean_channel_5g);
38 result = (u8)acs->clean_channel_5g;
39 }
40
41 return result;
42}
43
44static void odm_auto_channel_select_setting(void *dm_void, bool is_enable)
45{
46 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
47 u16 period = 0x2710;
48 u16 nhm_type = 0x7;
49
50 ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s()=========>\n", __func__);
51
52 if (is_enable) {
53
54 period = 0x1388;
55 nhm_type = 0x1;
56 }
57
58 if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
59
60
61
62
63
64 odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11AC + 2, period);
65 } else if (dm->support_ic_type & ODM_IC_11N_SERIES) {
66
67
68
69
70
71 odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11N + 2, period);
72 }
73}
74
75void odm_auto_channel_select_init(void *dm_void)
76{
77 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
78 struct acs_info *acs = &dm->dm_acs;
79 u8 i;
80
81 if (!(dm->support_ability & ODM_BB_NHM_CNT))
82 return;
83
84 if (acs->is_force_acs_result)
85 return;
86
87 ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s()=========>\n", __func__);
88
89 acs->clean_channel_2g = 1;
90 acs->clean_channel_5g = 36;
91
92 for (i = 0; i < ODM_MAX_CHANNEL_2G; ++i) {
93 acs->channel_info_2g[0][i] = 0;
94 acs->channel_info_2g[1][i] = 0;
95 }
96
97 if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
98 for (i = 0; i < ODM_MAX_CHANNEL_5G; ++i) {
99 acs->channel_info_5g[0][i] = 0;
100 acs->channel_info_5g[1][i] = 0;
101 }
102 }
103}
104
105void odm_auto_channel_select_reset(void *dm_void)
106{
107 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
108 struct acs_info *acs = &dm->dm_acs;
109
110 if (!(dm->support_ability & ODM_BB_NHM_CNT))
111 return;
112
113 if (acs->is_force_acs_result)
114 return;
115
116 ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s()=========>\n", __func__);
117
118 odm_auto_channel_select_setting(dm, true);
119 phydm_nhm_counter_statistics_reset(dm);
120}
121
122void odm_auto_channel_select(void *dm_void, u8 channel)
123{
124 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
125 struct acs_info *acs = &dm->dm_acs;
126 u8 channel_idx = 0, search_idx = 0;
127 u16 max_score = 0;
128
129 if (!(dm->support_ability & ODM_BB_NHM_CNT)) {
130 ODM_RT_TRACE(
131 dm, ODM_COMP_DIG,
132 "%s(): Return: support_ability ODM_BB_NHM_CNT is disabled\n",
133 __func__);
134 return;
135 }
136
137 if (acs->is_force_acs_result) {
138 ODM_RT_TRACE(
139 dm, ODM_COMP_DIG,
140 "%s(): Force 2G clean channel = %d, 5G clean channel = %d\n",
141 __func__, acs->clean_channel_2g, acs->clean_channel_5g);
142 return;
143 }
144
145 ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s(): channel = %d=========>\n",
146 __func__, channel);
147
148 phydm_get_nhm_counter_statistics(dm);
149 odm_auto_channel_select_setting(dm, false);
150
151 if (channel >= 1 && channel <= 14) {
152 channel_idx = channel - 1;
153 acs->channel_info_2g[1][channel_idx]++;
154
155 if (acs->channel_info_2g[1][channel_idx] >= 2)
156 acs->channel_info_2g[0][channel_idx] =
157 (acs->channel_info_2g[0][channel_idx] >> 1) +
158 (acs->channel_info_2g[0][channel_idx] >> 2) +
159 (dm->nhm_cnt_0 >> 2);
160 else
161 acs->channel_info_2g[0][channel_idx] = dm->nhm_cnt_0;
162
163 ODM_RT_TRACE(dm, ODM_COMP_ACS, "%s(): nhm_cnt_0 = %d\n",
164 __func__, dm->nhm_cnt_0);
165 ODM_RT_TRACE(
166 dm, ODM_COMP_ACS,
167 "%s(): Channel_Info[0][%d] = %d, Channel_Info[1][%d] = %d\n",
168 __func__, channel_idx,
169 acs->channel_info_2g[0][channel_idx], channel_idx,
170 acs->channel_info_2g[1][channel_idx]);
171
172 for (search_idx = 0; search_idx < ODM_MAX_CHANNEL_2G;
173 search_idx++) {
174 if (acs->channel_info_2g[1][search_idx] != 0 &&
175 acs->channel_info_2g[0][search_idx] >= max_score) {
176 max_score = acs->channel_info_2g[0][search_idx];
177 acs->clean_channel_2g = search_idx + 1;
178 }
179 }
180 ODM_RT_TRACE(
181 dm, ODM_COMP_ACS,
182 "(1)%s(): 2G: clean_channel_2g = %d, max_score = %d\n",
183 __func__, acs->clean_channel_2g, max_score);
184
185 } else if (channel >= 36) {
186
187 acs->clean_channel_5g = channel;
188 }
189}
190