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 #include "mp_precomp.h"
30 #include "phydm_precomp.h"
31 #ifdef PHYDM_PRIMARY_CCA
32
phydm_write_dynamic_cca(void * dm_void,u8 curr_mf_state)33 void phydm_write_dynamic_cca(
34 void *dm_void,
35 u8 curr_mf_state
36
37 )
38 {
39 struct dm_struct *dm = (struct dm_struct *)dm_void;
40 struct phydm_pricca_struct *pri_cca = &dm->dm_pri_cca;
41
42 if (pri_cca->mf_state == curr_mf_state)
43 return;
44
45 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
46 if (curr_mf_state == MF_USC_LSC) {
47 odm_set_bb_reg(dm, R_0xc6c, 0x180, MF_USC_LSC);
48 /*@40M OFDM MF CCA threshold*/
49 odm_set_bb_reg(dm, R_0xc84, 0xf0000000,
50 pri_cca->cca_th_40m_bkp);
51 } else {
52 odm_set_bb_reg(dm, R_0xc6c, 0x180, curr_mf_state);
53 /*@40M OFDM MF CCA threshold*/
54 odm_set_bb_reg(dm, R_0xc84, 0xf0000000, 0);
55 }
56 }
57
58 pri_cca->mf_state = curr_mf_state;
59 PHYDM_DBG(dm, DBG_PRI_CCA, "Set CCA at ((%s SB)), 0xc6c[8:7]=((%d))\n",
60 ((curr_mf_state == MF_USC_LSC) ? "D" :
61 ((curr_mf_state == MF_LSC) ? "L" : "U")), curr_mf_state);
62 }
63
phydm_primary_cca_reset(void * dm_void)64 void phydm_primary_cca_reset(
65 void *dm_void)
66 {
67 struct dm_struct *dm = (struct dm_struct *)dm_void;
68 struct phydm_pricca_struct *pri_cca = &dm->dm_pri_cca;
69
70 PHYDM_DBG(dm, DBG_PRI_CCA, "[PriCCA] Reset\n");
71 pri_cca->mf_state = 0xff;
72 pri_cca->pre_bw = (enum channel_width)0xff;
73 phydm_write_dynamic_cca(dm, MF_USC_LSC);
74 }
75
phydm_primary_cca_11n(void * dm_void)76 void phydm_primary_cca_11n(
77 void *dm_void)
78 {
79 struct dm_struct *dm = (struct dm_struct *)dm_void;
80 struct phydm_pricca_struct *pri_cca = &dm->dm_pri_cca;
81 enum channel_width curr_bw = (enum channel_width)*dm->band_width;
82
83 if (!(dm->support_ability & ODM_BB_PRIMARY_CCA))
84 return;
85
86 if (!dm->is_linked) {
87 PHYDM_DBG(dm, DBG_PRI_CCA, "[PriCCA][No Link!!!]\n");
88
89 if (pri_cca->pri_cca_is_become_linked) {
90 phydm_primary_cca_reset(dm);
91 pri_cca->pri_cca_is_become_linked = dm->is_linked;
92 }
93 return;
94 } else {
95 if (!pri_cca->pri_cca_is_become_linked) {
96 PHYDM_DBG(dm, DBG_PRI_CCA, "[PriCCA][Linked !!!]\n");
97 pri_cca->pri_cca_is_become_linked = dm->is_linked;
98 }
99 }
100
101 if (curr_bw != pri_cca->pre_bw) {
102 PHYDM_DBG(dm, DBG_PRI_CCA, "[Primary CCA] start ==>\n");
103 pri_cca->pre_bw = curr_bw;
104
105 if (curr_bw == CHANNEL_WIDTH_40) {
106 if (*dm->sec_ch_offset == SECOND_CH_AT_LSB) {
107 /* Primary CH @ upper sideband*/
108 PHYDM_DBG(dm, DBG_PRI_CCA,
109 "BW40M, Primary CH at USB\n");
110 phydm_write_dynamic_cca(dm, MF_USC);
111 } else {
112 /*Primary CH @ lower sideband*/
113 PHYDM_DBG(dm, DBG_PRI_CCA,
114 "BW40M, Primary CH at LSB\n");
115 phydm_write_dynamic_cca(dm, MF_LSC);
116 }
117 } else {
118 PHYDM_DBG(dm, DBG_PRI_CCA, "Not BW40M, USB + LSB\n");
119 phydm_primary_cca_reset(dm);
120 }
121 }
122 }
123
124 boolean
odm_dynamic_primary_cca_dup_rts(void * dm_void)125 odm_dynamic_primary_cca_dup_rts(void *dm_void)
126 {
127 struct dm_struct *dm = (struct dm_struct *)dm_void;
128 struct phydm_pricca_struct *pri_cca = &dm->dm_pri_cca;
129
130 return pri_cca->dup_rts_flag;
131 }
132
phydm_primary_cca_init(void * dm_void)133 void phydm_primary_cca_init(void *dm_void)
134 {
135 struct dm_struct *dm = (struct dm_struct *)dm_void;
136 struct phydm_pricca_struct *pri_cca = &dm->dm_pri_cca;
137
138 if (!(dm->support_ability & ODM_BB_PRIMARY_CCA))
139 return;
140
141 if (!(dm->support_ic_type & ODM_IC_11N_SERIES))
142 return;
143
144 PHYDM_DBG(dm, DBG_PRI_CCA, "[PriCCA] Init ==>\n");
145 #if (RTL8188E_SUPPORT == 1) || (RTL8192E_SUPPORT == 1)
146 pri_cca->dup_rts_flag = 0;
147 pri_cca->intf_flag = 0;
148 pri_cca->intf_type = 0;
149 pri_cca->monitor_flag = 0;
150 pri_cca->pri_cca_flag = 0;
151 pri_cca->ch_offset = 0;
152 #endif
153 pri_cca->mf_state = 0xff;
154 pri_cca->pre_bw = (enum channel_width)0xff;
155 pri_cca->cca_th_40m_bkp = (u8)odm_get_bb_reg(dm, R_0xc84, 0xf0000000);
156 }
157
phydm_primary_cca(void * dm_void)158 void phydm_primary_cca(void *dm_void)
159 {
160 #ifdef PHYDM_PRIMARY_CCA
161 struct dm_struct *dm = (struct dm_struct *)dm_void;
162
163 if (!(dm->support_ic_type & ODM_IC_11N_SERIES))
164 return;
165
166 if (!(dm->support_ability & ODM_BB_PRIMARY_CCA))
167 return;
168
169 phydm_primary_cca_11n(dm);
170
171 #endif
172 }
173 #endif
174