1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7 
8 #include <linux/kernel.h>
9 #include "odm_precomp.h"
10 
CheckPositive(struct dm_odm_t * pDM_Odm,const u32 Condition1,const u32 Condition2)11 static bool CheckPositive(
12 	struct dm_odm_t *pDM_Odm, const u32 Condition1, const u32 Condition2
13 )
14 {
15 	u8 _BoardType =
16 		((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /*  _GLNA */
17 		((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /*  _GPA */
18 		((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /*  _ALNA */
19 		((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /*  _APA */
20 		((pDM_Odm->BoardType & BIT2) >> 2) << 4;  /*  _BT */
21 
22 	u32   cond1   = Condition1, cond2 = Condition2;
23 	u32    driver1 =
24 		pDM_Odm->CutVersion       << 24 |
25 		pDM_Odm->SupportPlatform  << 16 |
26 		pDM_Odm->PackageType      << 12 |
27 		pDM_Odm->SupportInterface << 8  |
28 		_BoardType;
29 
30 	u32 driver2 =
31 		pDM_Odm->TypeGLNA <<  0 |
32 		pDM_Odm->TypeGPA  <<  8 |
33 		pDM_Odm->TypeALNA << 16 |
34 		pDM_Odm->TypeAPA  << 24;
35 
36 
37 	/*  Value Defined Check =============== */
38 	/* QFN Type [15:12] and Cut Version [27:24] need to do value check */
39 
40 	if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
41 		return false;
42 	if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
43 		return false;
44 
45 	/*  Bit Defined Check ================ */
46 	/*  We don't care [31:28] and [23:20] */
47 	/*  */
48 	cond1   &= 0x000F0FFF;
49 	driver1 &= 0x000F0FFF;
50 
51 	if ((cond1 & driver1) == cond1) {
52 		u32 bitMask = 0;
53 		if ((cond1 & 0x0F) == 0) /*  BoardType is DONTCARE */
54 			return true;
55 
56 		if ((cond1 & BIT0) != 0) /* GLNA */
57 			bitMask |= 0x000000FF;
58 		if ((cond1 & BIT1) != 0) /* GPA */
59 			bitMask |= 0x0000FF00;
60 		if ((cond1 & BIT2) != 0) /* ALNA */
61 			bitMask |= 0x00FF0000;
62 		if ((cond1 & BIT3) != 0) /* APA */
63 			bitMask |= 0xFF000000;
64 
65 		if ((cond2 & bitMask) == (driver2 & bitMask)) /*  BoardType of each RF path is matched */
66 			return true;
67 	}
68 	return false;
69 }
70 
CheckNegative(struct dm_odm_t * pDM_Odm,const u32 Condition1,const u32 Condition2)71 static bool CheckNegative(
72 	struct dm_odm_t *pDM_Odm, const u32 Condition1, const u32 Condition2
73 )
74 {
75 	return true;
76 }
77 
78 /******************************************************************************
79 *                           MAC_REG.TXT
80 ******************************************************************************/
81 
82 static u32 Array_MP_8723B_MAC_REG[] = {
83 		0x02F, 0x00000030,
84 		0x035, 0x00000000,
85 		0x039, 0x00000008,
86 		0x04E, 0x000000E0,
87 		0x064, 0x00000000,
88 		0x067, 0x00000020,
89 		0x428, 0x0000000A,
90 		0x429, 0x00000010,
91 		0x430, 0x00000000,
92 		0x431, 0x00000000,
93 		0x432, 0x00000000,
94 		0x433, 0x00000001,
95 		0x434, 0x00000004,
96 		0x435, 0x00000005,
97 		0x436, 0x00000007,
98 		0x437, 0x00000008,
99 		0x43C, 0x00000004,
100 		0x43D, 0x00000005,
101 		0x43E, 0x00000007,
102 		0x43F, 0x00000008,
103 		0x440, 0x0000005D,
104 		0x441, 0x00000001,
105 		0x442, 0x00000000,
106 		0x444, 0x00000010,
107 		0x445, 0x00000000,
108 		0x446, 0x00000000,
109 		0x447, 0x00000000,
110 		0x448, 0x00000000,
111 		0x449, 0x000000F0,
112 		0x44A, 0x0000000F,
113 		0x44B, 0x0000003E,
114 		0x44C, 0x00000010,
115 		0x44D, 0x00000000,
116 		0x44E, 0x00000000,
117 		0x44F, 0x00000000,
118 		0x450, 0x00000000,
119 		0x451, 0x000000F0,
120 		0x452, 0x0000000F,
121 		0x453, 0x00000000,
122 		0x456, 0x0000005E,
123 		0x460, 0x00000066,
124 		0x461, 0x00000066,
125 		0x4C8, 0x000000FF,
126 		0x4C9, 0x00000008,
127 		0x4CC, 0x000000FF,
128 		0x4CD, 0x000000FF,
129 		0x4CE, 0x00000001,
130 		0x500, 0x00000026,
131 		0x501, 0x000000A2,
132 		0x502, 0x0000002F,
133 		0x503, 0x00000000,
134 		0x504, 0x00000028,
135 		0x505, 0x000000A3,
136 		0x506, 0x0000005E,
137 		0x507, 0x00000000,
138 		0x508, 0x0000002B,
139 		0x509, 0x000000A4,
140 		0x50A, 0x0000005E,
141 		0x50B, 0x00000000,
142 		0x50C, 0x0000004F,
143 		0x50D, 0x000000A4,
144 		0x50E, 0x00000000,
145 		0x50F, 0x00000000,
146 		0x512, 0x0000001C,
147 		0x514, 0x0000000A,
148 		0x516, 0x0000000A,
149 		0x525, 0x0000004F,
150 		0x550, 0x00000010,
151 		0x551, 0x00000010,
152 		0x559, 0x00000002,
153 		0x55C, 0x00000050,
154 		0x55D, 0x000000FF,
155 		0x605, 0x00000030,
156 		0x608, 0x0000000E,
157 		0x609, 0x0000002A,
158 		0x620, 0x000000FF,
159 		0x621, 0x000000FF,
160 		0x622, 0x000000FF,
161 		0x623, 0x000000FF,
162 		0x624, 0x000000FF,
163 		0x625, 0x000000FF,
164 		0x626, 0x000000FF,
165 		0x627, 0x000000FF,
166 		0x638, 0x00000050,
167 		0x63C, 0x0000000A,
168 		0x63D, 0x0000000A,
169 		0x63E, 0x0000000E,
170 		0x63F, 0x0000000E,
171 		0x640, 0x00000040,
172 		0x642, 0x00000040,
173 		0x643, 0x00000000,
174 		0x652, 0x000000C8,
175 		0x66E, 0x00000005,
176 		0x700, 0x00000021,
177 		0x701, 0x00000043,
178 		0x702, 0x00000065,
179 		0x703, 0x00000087,
180 		0x708, 0x00000021,
181 		0x709, 0x00000043,
182 		0x70A, 0x00000065,
183 		0x70B, 0x00000087,
184 		0x765, 0x00000018,
185 		0x76E, 0x00000004,
186 
187 };
188 
ODM_ReadAndConfig_MP_8723B_MAC_REG(struct dm_odm_t * pDM_Odm)189 void ODM_ReadAndConfig_MP_8723B_MAC_REG(struct dm_odm_t *pDM_Odm)
190 {
191 	u32 i = 0;
192 	u32 ArrayLen = ARRAY_SIZE(Array_MP_8723B_MAC_REG);
193 	u32 *Array = Array_MP_8723B_MAC_REG;
194 
195 	for (i = 0; i < ArrayLen; i += 2) {
196 		u32 v1 = Array[i];
197 		u32 v2 = Array[i+1];
198 
199 		/*  This (offset, data) pair doesn't care the condition. */
200 		if (v1 < 0x40000000) {
201 			odm_ConfigMAC_8723B(pDM_Odm, v1, (u8)v2);
202 			continue;
203 		} else {
204 			/*  This line is the beginning of branch. */
205 			bool bMatched = true;
206 			u8  cCond  = (u8)((v1 & (BIT29|BIT28)) >> 28);
207 
208 			if (cCond == COND_ELSE) { /*  ELSE, ENDIF */
209 				bMatched = true;
210 				READ_NEXT_PAIR(v1, v2, i);
211 			} else if (!CheckPositive(pDM_Odm, v1, v2)) {
212 				bMatched = false;
213 				READ_NEXT_PAIR(v1, v2, i);
214 				READ_NEXT_PAIR(v1, v2, i);
215 			} else {
216 				READ_NEXT_PAIR(v1, v2, i);
217 				if (!CheckNegative(pDM_Odm, v1, v2))
218 					bMatched = false;
219 				else
220 					bMatched = true;
221 				READ_NEXT_PAIR(v1, v2, i);
222 			}
223 
224 			if (!bMatched) {
225 				/*  Condition isn't matched. Discard the following (offset, data) pairs. */
226 				while (v1 < 0x40000000 && i < ArrayLen-2)
227 					READ_NEXT_PAIR(v1, v2, i);
228 
229 				i -= 2; /*  prevent from for-loop += 2 */
230 			} else { /*  Configure matched pairs and skip to end of if-else. */
231 				while (v1 < 0x40000000 && i < ArrayLen-2) {
232 					odm_ConfigMAC_8723B(pDM_Odm, v1, (u8)v2);
233 					READ_NEXT_PAIR(v1, v2, i);
234 				}
235 
236 				/*  Keeps reading until ENDIF. */
237 				cCond = (u8)((v1 & (BIT29|BIT28)) >> 28);
238 				while (cCond != COND_ENDIF && i < ArrayLen-2) {
239 					READ_NEXT_PAIR(v1, v2, i);
240 					cCond = (u8)((v1 & (BIT29|BIT28)) >> 28);
241 				}
242 			}
243 		}
244 	}
245 }
246