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 
71 /******************************************************************************
72 *                           MAC_REG.TXT
73 ******************************************************************************/
74 
75 static u32 Array_MP_8723B_MAC_REG[] = {
76 		0x02F, 0x00000030,
77 		0x035, 0x00000000,
78 		0x039, 0x00000008,
79 		0x04E, 0x000000E0,
80 		0x064, 0x00000000,
81 		0x067, 0x00000020,
82 		0x428, 0x0000000A,
83 		0x429, 0x00000010,
84 		0x430, 0x00000000,
85 		0x431, 0x00000000,
86 		0x432, 0x00000000,
87 		0x433, 0x00000001,
88 		0x434, 0x00000004,
89 		0x435, 0x00000005,
90 		0x436, 0x00000007,
91 		0x437, 0x00000008,
92 		0x43C, 0x00000004,
93 		0x43D, 0x00000005,
94 		0x43E, 0x00000007,
95 		0x43F, 0x00000008,
96 		0x440, 0x0000005D,
97 		0x441, 0x00000001,
98 		0x442, 0x00000000,
99 		0x444, 0x00000010,
100 		0x445, 0x00000000,
101 		0x446, 0x00000000,
102 		0x447, 0x00000000,
103 		0x448, 0x00000000,
104 		0x449, 0x000000F0,
105 		0x44A, 0x0000000F,
106 		0x44B, 0x0000003E,
107 		0x44C, 0x00000010,
108 		0x44D, 0x00000000,
109 		0x44E, 0x00000000,
110 		0x44F, 0x00000000,
111 		0x450, 0x00000000,
112 		0x451, 0x000000F0,
113 		0x452, 0x0000000F,
114 		0x453, 0x00000000,
115 		0x456, 0x0000005E,
116 		0x460, 0x00000066,
117 		0x461, 0x00000066,
118 		0x4C8, 0x000000FF,
119 		0x4C9, 0x00000008,
120 		0x4CC, 0x000000FF,
121 		0x4CD, 0x000000FF,
122 		0x4CE, 0x00000001,
123 		0x500, 0x00000026,
124 		0x501, 0x000000A2,
125 		0x502, 0x0000002F,
126 		0x503, 0x00000000,
127 		0x504, 0x00000028,
128 		0x505, 0x000000A3,
129 		0x506, 0x0000005E,
130 		0x507, 0x00000000,
131 		0x508, 0x0000002B,
132 		0x509, 0x000000A4,
133 		0x50A, 0x0000005E,
134 		0x50B, 0x00000000,
135 		0x50C, 0x0000004F,
136 		0x50D, 0x000000A4,
137 		0x50E, 0x00000000,
138 		0x50F, 0x00000000,
139 		0x512, 0x0000001C,
140 		0x514, 0x0000000A,
141 		0x516, 0x0000000A,
142 		0x525, 0x0000004F,
143 		0x550, 0x00000010,
144 		0x551, 0x00000010,
145 		0x559, 0x00000002,
146 		0x55C, 0x00000050,
147 		0x55D, 0x000000FF,
148 		0x605, 0x00000030,
149 		0x608, 0x0000000E,
150 		0x609, 0x0000002A,
151 		0x620, 0x000000FF,
152 		0x621, 0x000000FF,
153 		0x622, 0x000000FF,
154 		0x623, 0x000000FF,
155 		0x624, 0x000000FF,
156 		0x625, 0x000000FF,
157 		0x626, 0x000000FF,
158 		0x627, 0x000000FF,
159 		0x638, 0x00000050,
160 		0x63C, 0x0000000A,
161 		0x63D, 0x0000000A,
162 		0x63E, 0x0000000E,
163 		0x63F, 0x0000000E,
164 		0x640, 0x00000040,
165 		0x642, 0x00000040,
166 		0x643, 0x00000000,
167 		0x652, 0x000000C8,
168 		0x66E, 0x00000005,
169 		0x700, 0x00000021,
170 		0x701, 0x00000043,
171 		0x702, 0x00000065,
172 		0x703, 0x00000087,
173 		0x708, 0x00000021,
174 		0x709, 0x00000043,
175 		0x70A, 0x00000065,
176 		0x70B, 0x00000087,
177 		0x765, 0x00000018,
178 		0x76E, 0x00000004,
179 
180 };
181 
ODM_ReadAndConfig_MP_8723B_MAC_REG(struct dm_odm_t * pDM_Odm)182 void ODM_ReadAndConfig_MP_8723B_MAC_REG(struct dm_odm_t *pDM_Odm)
183 {
184 	u32 i = 0;
185 	u32 ArrayLen = ARRAY_SIZE(Array_MP_8723B_MAC_REG);
186 	u32 *Array = Array_MP_8723B_MAC_REG;
187 
188 	for (i = 0; i < ArrayLen; i += 2) {
189 		u32 v1 = Array[i];
190 		u32 v2 = Array[i+1];
191 
192 		/*  This (offset, data) pair doesn't care the condition. */
193 		if (v1 < 0x40000000) {
194 			odm_ConfigMAC_8723B(pDM_Odm, v1, (u8)v2);
195 			continue;
196 		} else {
197 			/*  This line is the beginning of branch. */
198 			bool bMatched = true;
199 			u8  cCond  = (u8)((v1 & (BIT29|BIT28)) >> 28);
200 
201 			if (cCond == COND_ELSE) { /*  ELSE, ENDIF */
202 				bMatched = true;
203 				READ_NEXT_PAIR(v1, v2, i);
204 			} else if (!CheckPositive(pDM_Odm, v1, v2)) {
205 				bMatched = false;
206 				READ_NEXT_PAIR(v1, v2, i);
207 				READ_NEXT_PAIR(v1, v2, i);
208 			} else {
209 				READ_NEXT_PAIR(v1, v2, i);
210 				bMatched = true;
211 				READ_NEXT_PAIR(v1, v2, i);
212 			}
213 
214 			if (!bMatched) {
215 				/*  Condition isn't matched. Discard the following (offset, data) pairs. */
216 				while (v1 < 0x40000000 && i < ArrayLen-2)
217 					READ_NEXT_PAIR(v1, v2, i);
218 
219 				i -= 2; /*  prevent from for-loop += 2 */
220 			} else { /*  Configure matched pairs and skip to end of if-else. */
221 				while (v1 < 0x40000000 && i < ArrayLen-2) {
222 					odm_ConfigMAC_8723B(pDM_Odm, v1, (u8)v2);
223 					READ_NEXT_PAIR(v1, v2, i);
224 				}
225 
226 				/*  Keeps reading until ENDIF. */
227 				cCond = (u8)((v1 & (BIT29|BIT28)) >> 28);
228 				while (cCond != COND_ENDIF && i < ArrayLen-2) {
229 					READ_NEXT_PAIR(v1, v2, i);
230 					cCond = (u8)((v1 & (BIT29|BIT28)) >> 28);
231 				}
232 			}
233 		}
234 	}
235 }
236