| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154 |
- /******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
- /* ************************************************************
- * include files
- * ************************************************************ */
- #include "mp_precomp.h"
- #include "phydm_precomp.h"
- u8
- odm_get_auto_channel_select_result(
- void *p_dm_void,
- u8 band
- )
- {
- struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
- struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
- #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
- if (band == ODM_BAND_2_4G) {
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[struct _ACS_] odm_get_auto_channel_select_result(): clean_channel_2g(%d)\n", p_acs->clean_channel_2g));
- return (u8)p_acs->clean_channel_2g;
- } else {
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("[struct _ACS_] odm_get_auto_channel_select_result(): clean_channel_5g(%d)\n", p_acs->clean_channel_5g));
- return (u8)p_acs->clean_channel_5g;
- }
- #else
- return (u8)p_acs->clean_channel_2g;
- #endif
- }
- void
- odm_auto_channel_select_setting(
- void *p_dm_void,
- boolean is_enable
- )
- {
- #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
- struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
- u16 period = 0x2710;/* 40ms in default */
- u16 nhm_type = 0x7;
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select_setting()=========>\n"));
- if (is_enable) {
- /* 20 ms */
- period = 0x1388;
- nhm_type = 0x1;
- }
- if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
- /* PHY parameters initialize for ac series */
- odm_write_2byte(p_dm_odm, ODM_REG_CCX_PERIOD_11AC + 2, period); /* 0x990[31:16]=0x2710 Time duration for NHM unit: 4us, 0x2710=40ms */
- /* odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(8)|BIT9|BIT10, nhm_type); */ /* 0x994[9:8]=3 enable CCX */
- } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
- /* PHY parameters initialize for n series */
- odm_write_2byte(p_dm_odm, ODM_REG_CCX_PERIOD_11N + 2, period); /* 0x894[31:16]=0x2710 Time duration for NHM unit: 4us, 0x2710=40ms */
- /* odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(10)|BIT9|BIT8, nhm_type); */ /* 0x890[9:8]=3 enable CCX */
- }
- #endif
- }
- void
- odm_auto_channel_select_init(
- void *p_dm_void
- )
- {
- #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
- struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
- struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
- u8 i;
- if (!(p_dm_odm->support_ability & ODM_BB_NHM_CNT))
- return;
- if (p_acs->is_force_acs_result)
- return;
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select_init()=========>\n"));
- p_acs->clean_channel_2g = 1;
- p_acs->clean_channel_5g = 36;
- for (i = 0; i < ODM_MAX_CHANNEL_2G; ++i) {
- p_acs->channel_info_2g[0][i] = 0;
- p_acs->channel_info_2g[1][i] = 0;
- }
- if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
- for (i = 0; i < ODM_MAX_CHANNEL_5G; ++i) {
- p_acs->channel_info_5g[0][i] = 0;
- p_acs->channel_info_5g[1][i] = 0;
- }
- }
- #endif
- }
- void
- odm_auto_channel_select_reset(
- void *p_dm_void
- )
- {
- #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
- struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
- struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
- if (!(p_dm_odm->support_ability & ODM_BB_NHM_CNT))
- return;
- if (p_acs->is_force_acs_result)
- return;
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select_reset()=========>\n"));
- odm_auto_channel_select_setting(p_dm_odm, true); /* for 20ms measurement */
- phydm_nhm_counter_statistics_reset(p_dm_odm);
- #endif
- }
- void
- odm_auto_channel_select(
- void *p_dm_void,
- u8 channel
- )
- {
- #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
- struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
- struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
- u8 channel_idx = 0, search_idx = 0;
- u16 max_score = 0;
- if (!(p_dm_odm->support_ability & ODM_BB_NHM_CNT)) {
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_auto_channel_select(): Return: support_ability ODM_BB_NHM_CNT is disabled\n"));
- return;
- }
- if (p_acs->is_force_acs_result) {
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_auto_channel_select(): Force 2G clean channel = %d, 5G clean channel = %d\n",
- p_acs->clean_channel_2g, p_acs->clean_channel_5g));
- return;
- }
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select(): channel = %d=========>\n", channel));
- phydm_get_nhm_counter_statistics(p_dm_odm);
- odm_auto_channel_select_setting(p_dm_odm, false);
- if (channel >= 1 && channel <= 14) {
- channel_idx = channel - 1;
- p_acs->channel_info_2g[1][channel_idx]++;
- if (p_acs->channel_info_2g[1][channel_idx] >= 2)
- p_acs->channel_info_2g[0][channel_idx] = (p_acs->channel_info_2g[0][channel_idx] >> 1) +
- (p_acs->channel_info_2g[0][channel_idx] >> 2) + (p_dm_odm->nhm_cnt_0 >> 2);
- else
- p_acs->channel_info_2g[0][channel_idx] = p_dm_odm->nhm_cnt_0;
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select(): nhm_cnt_0 = %d\n", p_dm_odm->nhm_cnt_0));
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_auto_channel_select(): Channel_Info[0][%d] = %d, Channel_Info[1][%d] = %d\n", channel_idx, p_acs->channel_info_2g[0][channel_idx], channel_idx, p_acs->channel_info_2g[1][channel_idx]));
- for (search_idx = 0; search_idx < ODM_MAX_CHANNEL_2G; search_idx++) {
- if (p_acs->channel_info_2g[1][search_idx] != 0) {
- if (p_acs->channel_info_2g[0][search_idx] >= max_score) {
- max_score = p_acs->channel_info_2g[0][search_idx];
- p_acs->clean_channel_2g = search_idx + 1;
- }
- }
- }
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("(1)odm_auto_channel_select(): 2G: clean_channel_2g = %d, max_score = %d\n",
- p_acs->clean_channel_2g, max_score));
- } else if (channel >= 36) {
- /* Need to do */
- p_acs->clean_channel_5g = channel;
- }
- #endif
- }
- #if (DM_ODM_SUPPORT_TYPE & ODM_AP)
- void
- phydm_auto_channel_select_setting_ap(
- void *p_dm_void,
- u32 setting, /* 0: STORE_DEFAULT_NHM_SETTING; 1: RESTORE_DEFAULT_NHM_SETTING, 2: ACS_NHM_SETTING */
- u32 acs_step
- )
- {
- struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
- struct rtl8192cd_priv *priv = p_dm_odm->priv;
- struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("odm_AutoChannelSelectSettingAP()=========>\n"));
- /* 3 Store Default setting */
- if (setting == STORE_DEFAULT_NHM_SETTING) {
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("STORE_DEFAULT_NHM_SETTING\n"));
- if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) { /* store reg0x990, reg0x994, reg0x998, reg0x99c, Reg0x9a0 */
- p_acs->reg0x990 = odm_read_4byte(p_dm_odm, ODM_REG_CCX_PERIOD_11AC); /* reg0x990 */
- p_acs->reg0x994 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC); /* reg0x994 */
- p_acs->reg0x998 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC); /* reg0x998 */
- p_acs->reg0x99c = odm_read_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC); /* Reg0x99c */
- p_acs->reg0x9a0 = odm_read_1byte(p_dm_odm, ODM_REG_NHM_TH8_11AC); /* Reg0x9a0, u8 */
- } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
- p_acs->reg0x890 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N); /* reg0x890 */
- p_acs->reg0x894 = odm_read_4byte(p_dm_odm, ODM_REG_CCX_PERIOD_11N); /* reg0x894 */
- p_acs->reg0x898 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N); /* reg0x898 */
- p_acs->reg0x89c = odm_read_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N); /* Reg0x89c */
- p_acs->reg0xe28 = odm_read_1byte(p_dm_odm, ODM_REG_NHM_TH8_11N); /* Reg0xe28, u8 */
- }
- }
- /* 3 Restore Default setting */
- else if (setting == RESTORE_DEFAULT_NHM_SETTING) {
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("RESTORE_DEFAULT_NHM_SETTING\n"));
- if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) { /* store reg0x990, reg0x994, reg0x998, reg0x99c, Reg0x9a0 */
- odm_write_4byte(p_dm_odm, ODM_REG_CCX_PERIOD_11AC, p_acs->reg0x990);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, p_acs->reg0x994);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, p_acs->reg0x998);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, p_acs->reg0x99c);
- odm_write_1byte(p_dm_odm, ODM_REG_NHM_TH8_11AC, p_acs->reg0x9a0);
- } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, p_acs->reg0x890);
- odm_write_4byte(p_dm_odm, ODM_REG_CCX_PERIOD_11AC, p_acs->reg0x894);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, p_acs->reg0x898);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, p_acs->reg0x89c);
- odm_write_1byte(p_dm_odm, ODM_REG_NHM_TH8_11N, p_acs->reg0xe28);
- }
- }
- /* 3 struct _ACS_ setting */
- else if (setting == ACS_NHM_SETTING) {
- ODM_RT_TRACE(p_dm_odm, ODM_COMP_ACS, ODM_DBG_LOUD, ("ACS_NHM_SETTING\n"));
- u16 period;
- period = 0x61a8;
- p_acs->acs_step = acs_step;
- if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
- /* 4 Set NHM period, 0x990[31:16]=0x61a8, Time duration for NHM unit: 4us, 0x61a8=100ms */
- odm_write_2byte(p_dm_odm, ODM_REG_CCX_PERIOD_11AC + 2, period);
- /* 4 Set NHM ignore_cca=1, ignore_txon=1, ccx_en=0 */
- odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC, BIT(8) | BIT(9) | BIT(10), 3);
- if (p_acs->acs_step == 0) {
- /* 4 Set IGI */
- odm_set_bb_reg(p_dm_odm, 0xc50, BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6), 0x3E);
- if (get_rf_mimo_mode(priv) != MIMO_1T1R)
- odm_set_bb_reg(p_dm_odm, 0xe50, BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6), 0x3E);
- /* 4 Set struct _ACS_ NHM threshold */
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0x82786e64);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffff8c);
- odm_write_1byte(p_dm_odm, ODM_REG_NHM_TH8_11AC, 0xff);
- odm_write_2byte(p_dm_odm, ODM_REG_NHM_TH9_TH10_11AC + 2, 0xffff);
- } else if (p_acs->acs_step == 1) {
- /* 4 Set IGI */
- odm_set_bb_reg(p_dm_odm, 0xc50, BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6), 0x2A);
- if (get_rf_mimo_mode(priv) != MIMO_1T1R)
- odm_set_bb_reg(p_dm_odm, 0xe50, BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6), 0x2A);
- /* 4 Set struct _ACS_ NHM threshold */
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0x5a50463c);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffff64);
- }
- } else if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
- /* 4 Set NHM period, 0x894[31:16]=0x61a8, Time duration for NHM unit: 4us, 0x61a8=100ms */
- odm_write_2byte(p_dm_odm, ODM_REG_CCX_PERIOD_11AC + 2, period);
- /* 4 Set NHM ignore_cca=1, ignore_txon=1, ccx_en=0 */
- odm_set_bb_reg(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N, BIT(8) | BIT(9) | BIT(10), 3);
- if (p_acs->acs_step == 0) {
- /* 4 Set IGI */
- odm_set_bb_reg(p_dm_odm, 0xc50, BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6), 0x3E);
- if (get_rf_mimo_mode(priv) != MIMO_1T1R)
- odm_set_bb_reg(p_dm_odm, 0xc58, BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6), 0x3E);
- /* 4 Set struct _ACS_ NHM threshold */
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0x82786e64);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffff8c);
- odm_write_1byte(p_dm_odm, ODM_REG_NHM_TH8_11N, 0xff);
- odm_write_2byte(p_dm_odm, ODM_REG_NHM_TH9_TH10_11N + 2, 0xffff);
- } else if (p_acs->acs_step == 1) {
- /* 4 Set IGI */
- odm_set_bb_reg(p_dm_odm, 0xc50, BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6), 0x2A);
- if (get_rf_mimo_mode(priv) != MIMO_1T1R)
- odm_set_bb_reg(p_dm_odm, 0xc58, BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6), 0x2A);
- /* 4 Set struct _ACS_ NHM threshold */
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0x5a50463c);
- odm_write_4byte(p_dm_odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffff64);
- }
- }
- }
- }
- void
- phydm_get_nhm_statistics_ap(
- void *p_dm_void,
- u32 idx, /* @ 2G, Real channel number = idx+1 */
- u32 acs_step
- )
- {
- struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
- struct rtl8192cd_priv *priv = p_dm_odm->priv;
- struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
- u32 value32 = 0;
- u8 i;
- p_acs->acs_step = acs_step;
- if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
- /* 4 Check if NHM result is ready */
- for (i = 0; i < 20; i++) {
- ODM_delay_ms(1);
- if (odm_get_bb_reg(p_dm_odm, REG_FPGA0_PSD_REPORT, BIT(17)))
- break;
- }
- /* 4 Get NHM Statistics */
- if (p_acs->acs_step == 1) {
- value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT7_TO_CNT4_11N);
- p_acs->nhm_cnt[idx][9] = (value32 & MASKBYTE1) >> 8;
- p_acs->nhm_cnt[idx][8] = (value32 & MASKBYTE0);
- value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT_11N); /* ODM_REG_NHM_CNT3_TO_CNT0_11N */
- p_acs->nhm_cnt[idx][7] = (value32 & MASKBYTE3) >> 24;
- p_acs->nhm_cnt[idx][6] = (value32 & MASKBYTE2) >> 16;
- p_acs->nhm_cnt[idx][5] = (value32 & MASKBYTE1) >> 8;
- } else if (p_acs->acs_step == 2) {
- value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT_11N); /* ODM_REG_NHM_CNT3_TO_CNT0_11N */
- p_acs->nhm_cnt[idx][4] = odm_read_1byte(p_dm_odm, ODM_REG_NHM_CNT7_TO_CNT4_11N);
- p_acs->nhm_cnt[idx][3] = (value32 & MASKBYTE3) >> 24;
- p_acs->nhm_cnt[idx][2] = (value32 & MASKBYTE2) >> 16;
- p_acs->nhm_cnt[idx][1] = (value32 & MASKBYTE1) >> 8;
- p_acs->nhm_cnt[idx][0] = (value32 & MASKBYTE0);
- }
- } else if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
- /* 4 Check if NHM result is ready */
- for (i = 0; i < 20; i++) {
- ODM_delay_ms(1);
- if (odm_get_bb_reg(p_dm_odm, ODM_REG_NHM_DUR_READY_11AC, BIT(16)))
- break;
- }
- if (p_acs->acs_step == 1) {
- value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT7_TO_CNT4_11AC);
- p_acs->nhm_cnt[idx][9] = (value32 & MASKBYTE1) >> 8;
- p_acs->nhm_cnt[idx][8] = (value32 & MASKBYTE0);
- value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT_11AC); /* ODM_REG_NHM_CNT3_TO_CNT0_11AC */
- p_acs->nhm_cnt[idx][7] = (value32 & MASKBYTE3) >> 24;
- p_acs->nhm_cnt[idx][6] = (value32 & MASKBYTE2) >> 16;
- p_acs->nhm_cnt[idx][5] = (value32 & MASKBYTE1) >> 8;
- } else if (p_acs->acs_step == 2) {
- value32 = odm_read_4byte(p_dm_odm, ODM_REG_NHM_CNT_11AC); /* ODM_REG_NHM_CNT3_TO_CNT0_11AC */
- p_acs->nhm_cnt[idx][4] = odm_read_1byte(p_dm_odm, ODM_REG_NHM_CNT7_TO_CNT4_11AC);
- p_acs->nhm_cnt[idx][3] = (value32 & MASKBYTE3) >> 24;
- p_acs->nhm_cnt[idx][2] = (value32 & MASKBYTE2) >> 16;
- p_acs->nhm_cnt[idx][1] = (value32 & MASKBYTE1) >> 8;
- p_acs->nhm_cnt[idx][0] = (value32 & MASKBYTE0);
- }
- }
- }
- /* #define ACS_DEBUG_INFO */ /* acs debug default off */
- #if 0
- int phydm_AutoChannelSelectAP(
- void *p_dm_void,
- u32 ACS_Type, /* 0: RXCount_Type, 1:NHM_Type */
- u32 available_chnl_num /* amount of all channels */
- )
- {
- struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
- struct _ACS_ *p_acs = &p_dm_odm->dm_acs;
- struct rtl8192cd_priv *priv = p_dm_odm->priv;
- static u32 score2G[MAX_2G_CHANNEL_NUM], score5G[MAX_5G_CHANNEL_NUM];
- u32 score[MAX_BSS_NUM], use_nhm = 0;
- u32 minScore = 0xffffffff;
- u32 tmpScore, tmpIdx = 0;
- u32 traffic_check = 0;
- u32 fa_count_weighting = 1;
- int i, j, idx = 0, idx_2G_end = -1, idx_5G_begin = -1, minChan = 0;
- struct bss_desc *pBss = NULL;
- #ifdef _DEBUG_RTL8192CD_
- char tmpbuf[400];
- int len = 0;
- #endif
- memset(score2G, '\0', sizeof(score2G));
- memset(score5G, '\0', sizeof(score5G));
- for (i = 0; i < priv->available_chnl_num; i++) {
- if (priv->available_chnl[i] <= 14)
- idx_2G_end = i;
- else
- break;
- }
- for (i = 0; i < priv->available_chnl_num; i++) {
- if (priv->available_chnl[i] > 14) {
- idx_5G_begin = i;
- break;
- }
- }
- /* DELETE */
- #ifndef CONFIG_RTL_NEW_AUTOCH
- for (i = 0; i < priv->site_survey->count; i++) {
- pBss = &priv->site_survey->bss[i];
- for (idx = 0; idx < priv->available_chnl_num; idx++) {
- if (pBss->channel == priv->available_chnl[idx]) {
- if (pBss->channel <= 14)
- setChannelScore(idx, score2G, 0, MAX_2G_CHANNEL_NUM - 1);
- else
- score5G[idx - idx_5G_begin] += 5;
- break;
- }
- }
- }
- #endif
- if (idx_2G_end >= 0)
- for (i = 0; i <= idx_2G_end; i++)
- score[i] = score2G[i];
- if (idx_5G_begin >= 0)
- for (i = idx_5G_begin; i < priv->available_chnl_num; i++)
- score[i] = score5G[i - idx_5G_begin];
- #ifdef CONFIG_RTL_NEW_AUTOCH
- {
- u32 y, ch_begin = 0, ch_end = priv->available_chnl_num;
- u32 do_ap_check = 1, ap_ratio = 0;
- if (idx_2G_end >= 0)
- ch_end = idx_2G_end + 1;
- if (idx_5G_begin >= 0)
- ch_begin = idx_5G_begin;
- #ifdef ACS_DEBUG_INFO/* for debug */
- printk("\n");
- for (y = ch_begin; y < ch_end; y++)
- printk("1. init: chnl[%d] 20M_rx[%d] 40M_rx[%d] fa_cnt[%d] score[%d]\n",
- priv->available_chnl[y],
- priv->chnl_ss_mac_rx_count[y],
- priv->chnl_ss_mac_rx_count_40M[y],
- priv->chnl_ss_fa_count[y],
- score[y]);
- printk("\n");
- #endif
- #if defined(CONFIG_RTL_88E_SUPPORT) || defined(CONFIG_WLAN_HAL_8192EE)
- if (p_dm_odm->support_ic_type & (ODM_RTL8188E | ODM_RTL8192E) && priv->pmib->dot11RFEntry.acs_type) {
- u32 tmp_score[MAX_BSS_NUM];
- memcpy(tmp_score, score, sizeof(score));
- if (find_clean_channel(priv, ch_begin, ch_end, tmp_score)) {
- /* memcpy(score, tmp_score, sizeof(score)); */
- #ifdef _DEBUG_RTL8192CD_
- printk("!! Found clean channel, select minimum FA channel\n");
- #endif
- goto USE_CLN_CH;
- }
- #ifdef _DEBUG_RTL8192CD_
- printk("!! Not found clean channel, use NHM algorithm\n");
- #endif
- use_nhm = 1;
- USE_CLN_CH:
- for (y = ch_begin; y < ch_end; y++) {
- for (i = 0; i <= 9; i++) {
- u32 val32 = priv->nhm_cnt[y][i];
- for (j = 0; j < i; j++)
- val32 *= 3;
- score[y] += val32;
- }
- #ifdef _DEBUG_RTL8192CD_
- printk("nhm_cnt_%d: H<-[ %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d]->L, score: %d\n",
- y + 1, priv->nhm_cnt[y][9], priv->nhm_cnt[y][8], priv->nhm_cnt[y][7],
- priv->nhm_cnt[y][6], priv->nhm_cnt[y][5], priv->nhm_cnt[y][4],
- priv->nhm_cnt[y][3], priv->nhm_cnt[y][2], priv->nhm_cnt[y][1],
- priv->nhm_cnt[y][0], score[y]);
- #endif
- }
- if (!use_nhm)
- memcpy(score, tmp_score, sizeof(score));
- goto choose_ch;
- }
- #endif
- /* For each channel, weighting behind channels with MAC RX counter */
- /* For each channel, weighting the channel with FA counter */
- for (y = ch_begin; y < ch_end; y++) {
- score[y] += 8 * priv->chnl_ss_mac_rx_count[y];
- if (priv->chnl_ss_mac_rx_count[y] > 30)
- do_ap_check = 0;
- if (priv->chnl_ss_mac_rx_count[y] > MAC_RX_COUNT_THRESHOLD)
- traffic_check = 1;
- #ifdef RTK_5G_SUPPORT
- if (*p_dm_odm->p_band_type == ODM_BAND_2_4G)
- #endif
- {
- if ((int)(y - 4) >= (int)ch_begin)
- score[y - 4] += 2 * priv->chnl_ss_mac_rx_count[y];
- if ((int)(y - 3) >= (int)ch_begin)
- score[y - 3] += 8 * priv->chnl_ss_mac_rx_count[y];
- if ((int)(y - 2) >= (int)ch_begin)
- score[y - 2] += 8 * priv->chnl_ss_mac_rx_count[y];
- if ((int)(y - 1) >= (int)ch_begin)
- score[y - 1] += 10 * priv->chnl_ss_mac_rx_count[y];
- if ((int)(y + 1) < (int)ch_end)
- score[y + 1] += 10 * priv->chnl_ss_mac_rx_count[y];
- if ((int)(y + 2) < (int)ch_end)
- score[y + 2] += 8 * priv->chnl_ss_mac_rx_count[y];
- if ((int)(y + 3) < (int)ch_end)
- score[y + 3] += 8 * priv->chnl_ss_mac_rx_count[y];
- if ((int)(y + 4) < (int)ch_end)
- score[y + 4] += 2 * priv->chnl_ss_mac_rx_count[y];
- }
- /* this is for CH_LOAD caculation */
- if (priv->chnl_ss_cca_count[y] > priv->chnl_ss_fa_count[y])
- priv->chnl_ss_cca_count[y] -= priv->chnl_ss_fa_count[y];
- else
- priv->chnl_ss_cca_count[y] = 0;
- }
- #ifdef ACS_DEBUG_INFO/* for debug */
- printk("\n");
- for (y = ch_begin; y < ch_end; y++)
- printk("2. after 20M check: chnl[%d] score[%d]\n", priv->available_chnl[y], score[y]);
- printk("\n");
- #endif
- for (y = ch_begin; y < ch_end; y++) {
- if (priv->chnl_ss_mac_rx_count_40M[y]) {
- score[y] += 5 * priv->chnl_ss_mac_rx_count_40M[y];
- if (priv->chnl_ss_mac_rx_count_40M[y] > 30)
- do_ap_check = 0;
- if (priv->chnl_ss_mac_rx_count_40M[y] > MAC_RX_COUNT_THRESHOLD)
- traffic_check = 1;
- #ifdef RTK_5G_SUPPORT
- if (*p_dm_odm->p_band_type == ODM_BAND_2_4G)
- #endif
- {
- if ((int)(y - 6) >= (int)ch_begin)
- score[y - 6] += 1 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y - 5) >= (int)ch_begin)
- score[y - 5] += 4 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y - 4) >= (int)ch_begin)
- score[y - 4] += 4 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y - 3) >= (int)ch_begin)
- score[y - 3] += 5 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y - 2) >= (int)ch_begin)
- score[y - 2] += (5 * priv->chnl_ss_mac_rx_count_40M[y]) / 2;
- if ((int)(y - 1) >= (int)ch_begin)
- score[y - 1] += 5 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y + 1) < (int)ch_end)
- score[y + 1] += 5 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y + 2) < (int)ch_end)
- score[y + 2] += (5 * priv->chnl_ss_mac_rx_count_40M[y]) / 2;
- if ((int)(y + 3) < (int)ch_end)
- score[y + 3] += 5 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y + 4) < (int)ch_end)
- score[y + 4] += 4 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y + 5) < (int)ch_end)
- score[y + 5] += 4 * priv->chnl_ss_mac_rx_count_40M[y];
- if ((int)(y + 6) < (int)ch_end)
- score[y + 6] += 1 * priv->chnl_ss_mac_rx_count_40M[y];
- }
- }
- }
- #ifdef ACS_DEBUG_INFO/* for debug */
- printk("\n");
- for (y = ch_begin; y < ch_end; y++)
- printk("3. after 40M check: chnl[%d] score[%d]\n", priv->available_chnl[y], score[y]);
- printk("\n");
- printk("4. do_ap_check=%d traffic_check=%d\n", do_ap_check, traffic_check);
- printk("\n");
- #endif
- if (traffic_check == 0)
- fa_count_weighting = 5;
- else
- fa_count_weighting = 1;
- for (y = ch_begin; y < ch_end; y++)
- score[y] += fa_count_weighting * priv->chnl_ss_fa_count[y];
- #ifdef ACS_DEBUG_INFO/* for debug */
- printk("\n");
- for (y = ch_begin; y < ch_end; y++)
- printk("5. after fa check: chnl[%d] score[%d]\n", priv->available_chnl[y], score[y]);
- printk("\n");
- #endif
- if (do_ap_check) {
- for (i = 0; i < priv->site_survey->count; i++) {
- pBss = &priv->site_survey->bss[i];
- for (y = ch_begin; y < ch_end; y++) {
- if (pBss->channel == priv->available_chnl[y]) {
- if (pBss->channel <= 14) {
- #ifdef ACS_DEBUG_INFO/* for debug */
- printk("\n");
- printk("chnl[%d] has ap rssi=%d bw[0x%02x]\n",
- pBss->channel, pBss->rssi, pBss->t_stamp[1]);
- printk("\n");
- #endif
- if (pBss->rssi > 60)
- ap_ratio = 4;
- else if (pBss->rssi > 35)
- ap_ratio = 2;
- else
- ap_ratio = 1;
- if ((pBss->t_stamp[1] & 0x6) == 0) {
- score[y] += 50 * ap_ratio;
- if ((int)(y - 4) >= (int)ch_begin)
- score[y - 4] += 10 * ap_ratio;
- if ((int)(y - 3) >= (int)ch_begin)
- score[y - 3] += 20 * ap_ratio;
- if ((int)(y - 2) >= (int)ch_begin)
- score[y - 2] += 30 * ap_ratio;
- if ((int)(y - 1) >= (int)ch_begin)
- score[y - 1] += 40 * ap_ratio;
- if ((int)(y + 1) < (int)ch_end)
- score[y + 1] += 40 * ap_ratio;
- if ((int)(y + 2) < (int)ch_end)
- score[y + 2] += 30 * ap_ratio;
- if ((int)(y + 3) < (int)ch_end)
- score[y + 3] += 20 * ap_ratio;
- if ((int)(y + 4) < (int)ch_end)
- score[y + 4] += 10 * ap_ratio;
- } else if ((pBss->t_stamp[1] & 0x4) == 0) {
- score[y] += 50 * ap_ratio;
- if ((int)(y - 3) >= (int)ch_begin)
- score[y - 3] += 20 * ap_ratio;
- if ((int)(y - 2) >= (int)ch_begin)
- score[y - 2] += 30 * ap_ratio;
- if ((int)(y - 1) >= (int)ch_begin)
- score[y - 1] += 40 * ap_ratio;
- if ((int)(y + 1) < (int)ch_end)
- score[y + 1] += 50 * ap_ratio;
- if ((int)(y + 2) < (int)ch_end)
- score[y + 2] += 50 * ap_ratio;
- if ((int)(y + 3) < (int)ch_end)
- score[y + 3] += 50 * ap_ratio;
- if ((int)(y + 4) < (int)ch_end)
- score[y + 4] += 50 * ap_ratio;
- if ((int)(y + 5) < (int)ch_end)
- score[y + 5] += 40 * ap_ratio;
- if ((int)(y + 6) < (int)ch_end)
- score[y + 6] += 30 * ap_ratio;
- if ((int)(y + 7) < (int)ch_end)
- score[y + 7] += 20 * ap_ratio;
- } else {
- score[y] += 50 * ap_ratio;
- if ((int)(y - 7) >= (int)ch_begin)
- score[y - 7] += 20 * ap_ratio;
- if ((int)(y - 6) >= (int)ch_begin)
- score[y - 6] += 30 * ap_ratio;
- if ((int)(y - 5) >= (int)ch_begin)
- score[y - 5] += 40 * ap_ratio;
- if ((int)(y - 4) >= (int)ch_begin)
- score[y - 4] += 50 * ap_ratio;
- if ((int)(y - 3) >= (int)ch_begin)
- score[y - 3] += 50 * ap_ratio;
- if ((int)(y - 2) >= (int)ch_begin)
- score[y - 2] += 50 * ap_ratio;
- if ((int)(y - 1) >= (int)ch_begin)
- score[y - 1] += 50 * ap_ratio;
- if ((int)(y + 1) < (int)ch_end)
- score[y + 1] += 40 * ap_ratio;
- if ((int)(y + 2) < (int)ch_end)
- score[y + 2] += 30 * ap_ratio;
- if ((int)(y + 3) < (int)ch_end)
- score[y + 3] += 20 * ap_ratio;
- }
- } else {
- if ((pBss->t_stamp[1] & 0x6) == 0)
- score[y] += 500;
- else if ((pBss->t_stamp[1] & 0x4) == 0) {
- score[y] += 500;
- if ((int)(y + 1) < (int)ch_end)
- score[y + 1] += 500;
- } else {
- score[y] += 500;
- if ((int)(y - 1) >= (int)ch_begin)
- score[y - 1] += 500;
- }
- }
- break;
- }
- }
- }
- }
- #ifdef ACS_DEBUG_INFO/* for debug */
- printk("\n");
- for (y = ch_begin; y < ch_end; y++)
- printk("6. after ap check: chnl[%d]:%d\n", priv->available_chnl[y], score[y]);
- printk("\n");
- #endif
- #ifdef SS_CH_LOAD_PROC
- /* caculate noise level -- suggested by wilson */
- for (y = ch_begin; y < ch_end; y++) {
- int fa_lv = 0, cca_lv = 0;
- if (priv->chnl_ss_fa_count[y] > 1000)
- fa_lv = 100;
- else if (priv->chnl_ss_fa_count[y] > 500)
- fa_lv = 34 * (priv->chnl_ss_fa_count[y] - 500) / 500 + 66;
- else if (priv->chnl_ss_fa_count[y] > 200)
- fa_lv = 33 * (priv->chnl_ss_fa_count[y] - 200) / 300 + 33;
- else if (priv->chnl_ss_fa_count[y] > 100)
- fa_lv = 18 * (priv->chnl_ss_fa_count[y] - 100) / 100 + 15;
- else
- fa_lv = 15 * priv->chnl_ss_fa_count[y] / 100;
- if (priv->chnl_ss_cca_count[y] > 400)
- cca_lv = 100;
- else if (priv->chnl_ss_cca_count[y] > 200)
- cca_lv = 34 * (priv->chnl_ss_cca_count[y] - 200) / 200 + 66;
- else if (priv->chnl_ss_cca_count[y] > 80)
- cca_lv = 33 * (priv->chnl_ss_cca_count[y] - 80) / 120 + 33;
- else if (priv->chnl_ss_cca_count[y] > 40)
- cca_lv = 18 * (priv->chnl_ss_cca_count[y] - 40) / 40 + 15;
- else
- cca_lv = 15 * priv->chnl_ss_cca_count[y] / 40;
- priv->chnl_ss_load[y] = (((fa_lv > cca_lv) ? fa_lv : cca_lv) * 75 + ((score[y] > 100) ? 100 : score[y]) * 25) / 100;
- DEBUG_INFO("ch:%d f=%d (%d), c=%d (%d), fl=%d, cl=%d, sc=%d, cu=%d\n",
- priv->available_chnl[y],
- priv->chnl_ss_fa_count[y], fa_thd,
- priv->chnl_ss_cca_count[y], cca_thd,
- fa_lv,
- cca_lv,
- score[y],
- priv->chnl_ss_load[y]);
- }
- #endif
- }
- #endif
- choose_ch:
- #ifdef DFS
- /* heavy weighted DFS channel */
- if (idx_5G_begin >= 0) {
- for (i = idx_5G_begin; i < priv->available_chnl_num; i++) {
- if (!priv->pmib->dot11DFSEntry.disable_DFS && is_DFS_channel(priv->available_chnl[i])
- && (score[i] != 0xffffffff))
- score[i] += 1600;
- }
- }
- #endif
- /* prevent Auto channel selecting wrong channel in 40M mode----------------- */
- if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)
- && priv->pshare->is_40m_bw) {
- #if 0
- if (GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset == 1) {
- /* Upper Primary channel, cannot select the two lowest channels */
- if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) {
- score[0] = 0xffffffff;
- score[1] = 0xffffffff;
- score[2] = 0xffffffff;
- score[3] = 0xffffffff;
- score[4] = 0xffffffff;
- score[13] = 0xffffffff;
- score[12] = 0xffffffff;
- score[11] = 0xffffffff;
- }
- /* if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) { */
- /* score[idx_5G_begin] = 0xffffffff; */
- /* score[idx_5G_begin + 1] = 0xffffffff; */
- /* } */
- } else if (GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset == 2) {
- /* Lower Primary channel, cannot select the two highest channels */
- if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) {
- score[0] = 0xffffffff;
- score[1] = 0xffffffff;
- score[2] = 0xffffffff;
- score[13] = 0xffffffff;
- score[12] = 0xffffffff;
- score[11] = 0xffffffff;
- score[10] = 0xffffffff;
- score[9] = 0xffffffff;
- }
- /* if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) { */
- /* score[priv->available_chnl_num - 2] = 0xffffffff; */
- /* score[priv->available_chnl_num - 1] = 0xffffffff; */
- /* } */
- }
- #endif
- for (i = 0; i <= idx_2G_end; ++i)
- if (priv->available_chnl[i] == 14)
- score[i] = 0xffffffff; /* mask chan14 */
- #ifdef RTK_5G_SUPPORT
- if (idx_5G_begin >= 0) {
- for (i = idx_5G_begin; i < priv->available_chnl_num; i++) {
- int ch = priv->available_chnl[i];
- if (priv->available_chnl[i] > 144)
- --ch;
- if ((ch % 4) || ch == 140 || ch == 164) /* mask ch 140, ch 165, ch 184... */
- score[i] = 0xffffffff;
- }
- }
- #endif
- }
- if (priv->pmib->dot11RFEntry.disable_ch1213) {
- for (i = 0; i <= idx_2G_end; ++i) {
- int ch = priv->available_chnl[i];
- if ((ch == 12) || (ch == 13))
- score[i] = 0xffffffff;
- }
- }
- if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_GLOBAL) ||
- (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_WORLD_WIDE)) &&
- (idx_2G_end >= 11) && (idx_2G_end < 14)) {
- score[13] = 0xffffffff; /* mask chan14 */
- score[12] = 0xffffffff; /* mask chan13 */
- score[11] = 0xffffffff; /* mask chan12 */
- }
- /* ------------------------------------------------------------------ */
- #ifdef _DEBUG_RTL8192CD_
- for (i = 0; i < priv->available_chnl_num; i++)
- len += sprintf(tmpbuf + len, "ch%d:%u ", priv->available_chnl[i], score[i]);
- strcat(tmpbuf, "\n");
- panic_printk("%s", tmpbuf);
- #endif
- if ((*p_dm_odm->p_band_type == ODM_BAND_5G)
- && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)) {
- for (i = 0; i < priv->available_chnl_num; i++) {
- if (is80MChannel(priv->available_chnl, priv->available_chnl_num, priv->available_chnl[i])) {
- tmpScore = 0;
- for (j = 0; j < 4; j++) {
- if ((tmpScore != 0xffffffff) && (score[i + j] != 0xffffffff))
- tmpScore += score[i + j];
- else
- tmpScore = 0xffffffff;
- }
- tmpScore = tmpScore / 4;
- if (minScore > tmpScore) {
- minScore = tmpScore;
- tmpScore = 0xffffffff;
- for (j = 0; j < 4; j++) {
- if (score[i + j] < tmpScore) {
- tmpScore = score[i + j];
- tmpIdx = i + j;
- }
- }
- idx = tmpIdx;
- }
- i += 3;
- }
- }
- if (minScore == 0xffffffff) {
- /* there is no 80M channels */
- priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;
- for (i = 0; i < priv->available_chnl_num; i++) {
- if (score[i] < minScore) {
- minScore = score[i];
- idx = i;
- }
- }
- }
- } else if ((*p_dm_odm->p_band_type == ODM_BAND_5G)
- && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40)) {
- for (i = 0; i < priv->available_chnl_num; i++) {
- if (is40MChannel(priv->available_chnl, priv->available_chnl_num, priv->available_chnl[i])) {
- tmpScore = 0;
- for (j = 0; j < 2; j++) {
- if ((tmpScore != 0xffffffff) && (score[i + j] != 0xffffffff))
- tmpScore += score[i + j];
- else
- tmpScore = 0xffffffff;
- }
- tmpScore = tmpScore / 2;
- if (minScore > tmpScore) {
- minScore = tmpScore;
- tmpScore = 0xffffffff;
- for (j = 0; j < 2; j++) {
- if (score[i + j] < tmpScore) {
- tmpScore = score[i + j];
- tmpIdx = i + j;
- }
- }
- idx = tmpIdx;
- }
- i += 1;
- }
- }
- if (minScore == 0xffffffff) {
- /* there is no 40M channels */
- priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;
- for (i = 0; i < priv->available_chnl_num; i++) {
- if (score[i] < minScore) {
- minScore = score[i];
- idx = i;
- }
- }
- }
- } else if ((*p_dm_odm->p_band_type == ODM_BAND_2_4G)
- && (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40)
- && (priv->available_chnl_num >= 8)) {
- u32 groupScore[14];
- memset(groupScore, 0xff, sizeof(groupScore));
- for (i = 0; i < priv->available_chnl_num - 4; i++) {
- if (score[i] != 0xffffffff && score[i + 4] != 0xffffffff) {
- groupScore[i] = score[i] + score[i + 4];
- DEBUG_INFO("groupScore, ch %d,%d: %d\n", i + 1, i + 5, groupScore[i]);
- if (groupScore[i] < minScore) {
- #ifdef AUTOCH_SS_SPEEDUP
- if (priv->pmib->miscEntry.autoch_1611_enable) {
- if (priv->available_chnl[i] == 1 || priv->available_chnl[i] == 6 || priv->available_chnl[i] == 11) {
- minScore = groupScore[i];
- idx = i;
- }
- } else
- #endif
- {
- minScore = groupScore[i];
- idx = i;
- }
- }
- }
- }
- if (score[idx] < score[idx + 4]) {
- GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;
- priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE;
- } else {
- idx = idx + 4;
- GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;
- priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW;
- }
- } else {
- for (i = 0; i < priv->available_chnl_num; i++) {
- if (score[i] < minScore) {
- #ifdef AUTOCH_SS_SPEEDUP
- if (priv->pmib->miscEntry.autoch_1611_enable) {
- if (priv->available_chnl[i] == 1 || priv->available_chnl[i] == 6 || priv->available_chnl[i] == 11) {
- minScore = score[i];
- idx = i;
- }
- } else
- #endif
- {
- minScore = score[i];
- idx = i;
- }
- }
- }
- }
- if (IS_A_CUT_8881A(priv) &&
- (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80)) {
- if ((priv->available_chnl[idx] == 36) ||
- (priv->available_chnl[idx] == 52) ||
- (priv->available_chnl[idx] == 100) ||
- (priv->available_chnl[idx] == 116) ||
- (priv->available_chnl[idx] == 132) ||
- (priv->available_chnl[idx] == 149) ||
- (priv->available_chnl[idx] == 165))
- idx++;
- else if ((priv->available_chnl[idx] == 48) ||
- (priv->available_chnl[idx] == 64) ||
- (priv->available_chnl[idx] == 112) ||
- (priv->available_chnl[idx] == 128) ||
- (priv->available_chnl[idx] == 144) ||
- (priv->available_chnl[idx] == 161) ||
- (priv->available_chnl[idx] == 177))
- idx--;
- }
- minChan = priv->available_chnl[idx];
- /* skip channel 14 if don't support ofdm */
- if ((priv->pmib->dot11RFEntry.disable_ch14_ofdm) &&
- (minChan == 14)) {
- score[idx] = 0xffffffff;
- minScore = 0xffffffff;
- for (i = 0; i < priv->available_chnl_num; i++) {
- if (score[i] < minScore) {
- minScore = score[i];
- idx = i;
- }
- }
- minChan = priv->available_chnl[idx];
- }
- #if 0
- /* Check if selected channel available for 80M/40M BW or NOT ? */
- if (*p_dm_odm->p_band_type == ODM_BAND_5G) {
- if (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_80) {
- if (!is80MChannel(priv->available_chnl, priv->available_chnl_num, minChan)) {
- /* priv->pmib->dot11n_config_entry.dot11nUse40M = HT_CHANNEL_WIDTH_20_40; */
- priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20_40;
- }
- }
- if (priv->pmib->dot11nConfigEntry.dot11nUse40M == HT_CHANNEL_WIDTH_20_40) {
- if (!is40MChannel(priv->available_chnl, priv->available_chnl_num, minChan)) {
- /* priv->pmib->dot11n_config_entry.dot11nUse40M = HT_CHANNEL_WIDTH_20; */
- priv->pshare->is_40m_bw = HT_CHANNEL_WIDTH_20;
- }
- }
- }
- #endif
- #ifdef CONFIG_RTL_NEW_AUTOCH
- RTL_W32(RXERR_RPT, RXERR_RPT_RST);
- #endif
- /* auto adjust contro-sideband */
- if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)
- && (priv->pshare->is_40m_bw == 1 || priv->pshare->is_40m_bw == 2)) {
- #ifdef RTK_5G_SUPPORT
- if (*p_dm_odm->p_band_type == ODM_BAND_5G) {
- if ((minChan > 144) ? ((minChan - 1) % 8) : (minChan % 8)) {
- GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;
- priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE;
- } else {
- GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;
- priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW;
- }
- } else
- #endif
- {
- #if 0
- #ifdef CONFIG_RTL_NEW_AUTOCH
- unsigned int ch_max;
- if (priv->available_chnl[idx_2G_end] >= 13)
- ch_max = 13;
- else
- ch_max = priv->available_chnl[idx_2G_end];
- if ((minChan >= 5) && (minChan <= (ch_max - 5))) {
- if (score[minChan + 4] > score[minChan - 4]) { /* what if some channels were cancelled? */
- GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;
- priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW;
- } else {
- GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;
- priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE;
- }
- } else
- #endif
- {
- if (minChan < 5) {
- GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE;
- priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE;
- } else if (minChan > 7) {
- GET_MIB(priv)->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW;
- priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW;
- }
- }
- #endif
- }
- }
- /* ----------------------- */
- #if defined(__ECOS) && defined(CONFIG_SDIO_HCI)
- panic_printk("Auto channel choose ch:%d\n", minChan);
- #else
- #ifdef _DEBUG_RTL8192CD_
- panic_printk("Auto channel choose ch:%d\n", minChan);
- #endif
- #endif
- #ifdef ACS_DEBUG_INFO/* for debug */
- printk("7. minChan:%d 2nd_offset:%d\n", minChan, priv->pshare->offset_2nd_chan);
- #endif
- return minChan;
- }
- #endif
- #endif
|