Linux-libre 4.15.7-gnu
[librecmc/linux-libre.git] / drivers / staging / rtlwifi / phydm / rtl8822b / halhwimg8822b_mac.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2016  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 /*Image2HeaderVersion: 3.2*/
27 #include "../mp_precomp.h"
28 #include "../phydm_precomp.h"
29 #include <linux/kernel.h>
30
31 static bool check_positive(struct phy_dm_struct *dm, const u32 condition1,
32                            const u32 condition2, const u32 condition3,
33                            const u32 condition4)
34 {
35         u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/
36                          ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/
37                          ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/
38                          ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */
39                          ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/
40
41         u32 cond1 = condition1, cond2 = condition2, cond3 = condition3,
42             cond4 = condition4;
43
44         u8 cut_version_for_para =
45                 (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version;
46         u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type;
47
48         u32 driver1 = cut_version_for_para << 24 |
49                       (dm->support_interface & 0xF0) << 16 |
50                       dm->support_platform << 16 | pkg_type_for_para << 12 |
51                       (dm->support_interface & 0x0F) << 8 | _board_type;
52
53         u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 |
54                       (dm->type_alna & 0xFF) << 16 |
55                       (dm->type_apa & 0xFF) << 24;
56
57         u32 driver3 = 0;
58
59         u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) |
60                       (dm->type_alna & 0xFF00) << 8 |
61                       (dm->type_apa & 0xFF00) << 16;
62
63         ODM_RT_TRACE(
64                 dm, ODM_COMP_INIT,
65                 "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n",
66                 __func__, cond1, cond2, cond3, cond4);
67         ODM_RT_TRACE(
68                 dm, ODM_COMP_INIT,
69                 "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n",
70                 __func__, driver1, driver2, driver3, driver4);
71
72         ODM_RT_TRACE(dm, ODM_COMP_INIT,
73                      "  (Platform, Interface) = (0x%X, 0x%X)\n",
74                      dm->support_platform, dm->support_interface);
75         ODM_RT_TRACE(dm, ODM_COMP_INIT,
76                      "  (Board, Package) = (0x%X, 0x%X)\n",
77                      dm->board_type, dm->package_type);
78
79         /*============== value Defined Check ===============*/
80         /*QFN type [15:12] and cut version [27:24] need to do value check*/
81
82         if (((cond1 & 0x0000F000) != 0) &&
83             ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
84                 return false;
85         if (((cond1 & 0x0F000000) != 0) &&
86             ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
87                 return false;
88
89         /*=============== Bit Defined Check ================*/
90         /* We don't care [31:28] */
91
92         cond1 &= 0x00FF0FFF;
93         driver1 &= 0x00FF0FFF;
94
95         if ((cond1 & driver1) == cond1) {
96                 u32 bit_mask = 0;
97
98                 if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/
99                         return true;
100
101                 if ((cond1 & BIT(0)) != 0) /*GLNA*/
102                         bit_mask |= 0x000000FF;
103                 if ((cond1 & BIT(1)) != 0) /*GPA*/
104                         bit_mask |= 0x0000FF00;
105                 if ((cond1 & BIT(2)) != 0) /*ALNA*/
106                         bit_mask |= 0x00FF0000;
107                 if ((cond1 & BIT(3)) != 0) /*APA*/
108                         bit_mask |= 0xFF000000;
109
110                 if (((cond2 & bit_mask) == (driver2 & bit_mask)) &&
111                     ((cond4 & bit_mask) ==
112                      (driver4 &
113                       bit_mask))) /* board_type of each RF path is matched*/
114                         return true;
115                 else
116                         return false;
117         } else {
118                 return false;
119         }
120 }
121
122 /******************************************************************************
123  *                           mac_reg.TXT
124  ******************************************************************************/
125
126 static u32 array_mp_8822b_mac_reg[] = {
127         0x029,  0x000000F9, 0x420,  0x00000080, 0x421,  0x0000000F,
128         0x428,  0x0000000A, 0x429,  0x00000010, 0x430,  0x00000000,
129         0x431,  0x00000000, 0x432,  0x00000000, 0x433,  0x00000001,
130         0x434,  0x00000004, 0x435,  0x00000005, 0x436,  0x00000007,
131         0x437,  0x00000008, 0x43C,  0x00000004, 0x43D,  0x00000005,
132         0x43E,  0x00000007, 0x43F,  0x00000008, 0x440,  0x0000005D,
133         0x441,  0x00000001, 0x442,  0x00000000, 0x444,  0x00000010,
134         0x445,  0x000000F0, 0x446,  0x00000001, 0x447,  0x000000FE,
135         0x448,  0x00000000, 0x449,  0x00000000, 0x44A,  0x00000000,
136         0x44B,  0x00000040, 0x44C,  0x00000010, 0x44D,  0x000000F0,
137         0x44E,  0x0000003F, 0x44F,  0x00000000, 0x450,  0x00000000,
138         0x451,  0x00000000, 0x452,  0x00000000, 0x453,  0x00000040,
139         0x455,  0x00000070, 0x45E,  0x00000004, 0x49C,  0x00000010,
140         0x49D,  0x000000F0, 0x49E,  0x00000000, 0x49F,  0x00000006,
141         0x4A0,  0x000000E0, 0x4A1,  0x00000003, 0x4A2,  0x00000000,
142         0x4A3,  0x00000040, 0x4A4,  0x00000015, 0x4A5,  0x000000F0,
143         0x4A6,  0x00000000, 0x4A7,  0x00000006, 0x4A8,  0x000000E0,
144         0x4A9,  0x00000000, 0x4AA,  0x00000000, 0x4AB,  0x00000000,
145         0x7DA,  0x00000008, 0x1448, 0x00000006, 0x144A, 0x00000006,
146         0x144C, 0x00000006, 0x144E, 0x00000006, 0x4C8,  0x000000FF,
147         0x4C9,  0x00000008, 0x4CA,  0x00000020, 0x4CB,  0x00000020,
148         0x4CC,  0x000000FF, 0x4CD,  0x000000FF, 0x4CE,  0x00000001,
149         0x4CF,  0x00000008, 0x500,  0x00000026, 0x501,  0x000000A2,
150         0x502,  0x0000002F, 0x503,  0x00000000, 0x504,  0x00000028,
151         0x505,  0x000000A3, 0x506,  0x0000005E, 0x507,  0x00000000,
152         0x508,  0x0000002B, 0x509,  0x000000A4, 0x50A,  0x0000005E,
153         0x50B,  0x00000000, 0x50C,  0x0000004F, 0x50D,  0x000000A4,
154         0x50E,  0x00000000, 0x50F,  0x00000000, 0x512,  0x0000001C,
155         0x514,  0x0000000A, 0x516,  0x0000000A, 0x521,  0x0000002F,
156         0x525,  0x0000004F, 0x551,  0x00000010, 0x559,  0x00000002,
157         0x55C,  0x00000050, 0x55D,  0x000000FF, 0x577,  0x0000000B,
158         0x5BE,  0x00000064, 0x605,  0x00000030, 0x608,  0x0000000E,
159         0x609,  0x00000022, 0x60C,  0x00000018, 0x6A0,  0x000000FF,
160         0x6A1,  0x000000FF, 0x6A2,  0x000000FF, 0x6A3,  0x000000FF,
161         0x6A4,  0x000000FF, 0x6A5,  0x000000FF, 0x6DE,  0x00000084,
162         0x620,  0x000000FF, 0x621,  0x000000FF, 0x622,  0x000000FF,
163         0x623,  0x000000FF, 0x624,  0x000000FF, 0x625,  0x000000FF,
164         0x626,  0x000000FF, 0x627,  0x000000FF, 0x638,  0x00000050,
165         0x63C,  0x0000000A, 0x63D,  0x0000000A, 0x63E,  0x0000000E,
166         0x63F,  0x0000000E, 0x640,  0x00000040, 0x642,  0x00000040,
167         0x643,  0x00000000, 0x652,  0x000000C8, 0x66E,  0x00000005,
168         0x718,  0x00000040, 0x7D4,  0x00000098,
169
170 };
171
172 void odm_read_and_config_mp_8822b_mac_reg(struct phy_dm_struct *dm)
173 {
174         u32 i = 0;
175         u8 c_cond;
176         bool is_matched = true, is_skipped = false;
177         u32 *array = array_mp_8822b_mac_reg;
178
179         u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
180
181         ODM_RT_TRACE(dm, ODM_COMP_INIT,
182                      "===> %s\n", __func__);
183
184         for (; (i + 1) < ARRAY_SIZE(array_mp_8822b_mac_reg); i = i + 2) {
185                 v1 = array[i];
186                 v2 = array[i + 1];
187
188                 if (v1 & BIT(31)) { /* positive condition*/
189                         c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
190                         if (c_cond == COND_ENDIF) { /*end*/
191                                 is_matched = true;
192                                 is_skipped = false;
193                                 ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n");
194                         } else if (c_cond == COND_ELSE) { /*else*/
195                                 is_matched = is_skipped ? false : true;
196                                 ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n");
197                         } else { /*if , else if*/
198                                 pre_v1 = v1;
199                                 pre_v2 = v2;
200                                 ODM_RT_TRACE(dm, ODM_COMP_INIT,
201                                              "IF or ELSE IF\n");
202                         }
203                 } else if (v1 & BIT(30)) { /*negative condition*/
204                         if (is_skipped) {
205                                 is_matched = false;
206                                 continue;
207                         }
208
209                         if (check_positive(dm, pre_v1, pre_v2, v1, v2)) {
210                                 is_matched = true;
211                                 is_skipped = true;
212                         } else {
213                                 is_matched = false;
214                                 is_skipped = false;
215                         }
216                 } else if (is_matched) {
217                         odm_config_mac_8822b(dm, v1, (u8)v2);
218                 }
219         }
220 }
221
222 u32 odm_get_version_mp_8822b_mac_reg(void) { return 67; }