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