1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3 
4 #include "../include/rtw_iol.h"
5 
Checkcondition(const u32 condition,const u32 hex)6 static bool Checkcondition(const u32  condition, const u32  hex)
7 {
8 	u32 _board     = (hex & 0x000000FF);
9 	u32 _interface = (hex & 0x0000FF00) >> 8;
10 	u32 _platform  = (hex & 0x00FF0000) >> 16;
11 	u32 cond = condition;
12 
13 	if (condition == 0xCDCDCDCD)
14 		return true;
15 
16 	cond = condition & 0x000000FF;
17 	if ((_board == cond) && cond != 0x00)
18 		return false;
19 
20 	cond = condition & 0x0000FF00;
21 	cond = cond >> 8;
22 	if ((_interface & cond) == 0 && cond != 0x07)
23 		return false;
24 
25 	cond = condition & 0x00FF0000;
26 	cond = cond >> 16;
27 	if ((_platform & cond) == 0 && cond != 0x0F)
28 		return false;
29 	return true;
30 }
31 
32 /******************************************************************************
33 *                           MAC_REG.TXT
34 ******************************************************************************/
35 
36 static u32 array_MAC_REG_8188E[] = {
37 		0x026, 0x00000041,
38 		0x027, 0x00000035,
39 		0x428, 0x0000000A,
40 		0x429, 0x00000010,
41 		0x430, 0x00000000,
42 		0x431, 0x00000001,
43 		0x432, 0x00000002,
44 		0x433, 0x00000004,
45 		0x434, 0x00000005,
46 		0x435, 0x00000006,
47 		0x436, 0x00000007,
48 		0x437, 0x00000008,
49 		0x438, 0x00000000,
50 		0x439, 0x00000000,
51 		0x43A, 0x00000001,
52 		0x43B, 0x00000002,
53 		0x43C, 0x00000004,
54 		0x43D, 0x00000005,
55 		0x43E, 0x00000006,
56 		0x43F, 0x00000007,
57 		0x440, 0x0000005D,
58 		0x441, 0x00000001,
59 		0x442, 0x00000000,
60 		0x444, 0x00000015,
61 		0x445, 0x000000F0,
62 		0x446, 0x0000000F,
63 		0x447, 0x00000000,
64 		0x458, 0x00000041,
65 		0x459, 0x000000A8,
66 		0x45A, 0x00000072,
67 		0x45B, 0x000000B9,
68 		0x460, 0x00000066,
69 		0x461, 0x00000066,
70 		0x480, 0x00000008,
71 		0x4C8, 0x000000FF,
72 		0x4C9, 0x00000008,
73 		0x4CC, 0x000000FF,
74 		0x4CD, 0x000000FF,
75 		0x4CE, 0x00000001,
76 		0x4D3, 0x00000001,
77 		0x500, 0x00000026,
78 		0x501, 0x000000A2,
79 		0x502, 0x0000002F,
80 		0x503, 0x00000000,
81 		0x504, 0x00000028,
82 		0x505, 0x000000A3,
83 		0x506, 0x0000005E,
84 		0x507, 0x00000000,
85 		0x508, 0x0000002B,
86 		0x509, 0x000000A4,
87 		0x50A, 0x0000005E,
88 		0x50B, 0x00000000,
89 		0x50C, 0x0000004F,
90 		0x50D, 0x000000A4,
91 		0x50E, 0x00000000,
92 		0x50F, 0x00000000,
93 		0x512, 0x0000001C,
94 		0x514, 0x0000000A,
95 		0x516, 0x0000000A,
96 		0x525, 0x0000004F,
97 		0x550, 0x00000010,
98 		0x551, 0x00000010,
99 		0x559, 0x00000002,
100 		0x55D, 0x000000FF,
101 		0x605, 0x00000030,
102 		0x608, 0x0000000E,
103 		0x609, 0x0000002A,
104 		0x620, 0x000000FF,
105 		0x621, 0x000000FF,
106 		0x622, 0x000000FF,
107 		0x623, 0x000000FF,
108 		0x624, 0x000000FF,
109 		0x625, 0x000000FF,
110 		0x626, 0x000000FF,
111 		0x627, 0x000000FF,
112 		0x652, 0x00000020,
113 		0x63C, 0x0000000A,
114 		0x63D, 0x0000000A,
115 		0x63E, 0x0000000E,
116 		0x63F, 0x0000000E,
117 		0x640, 0x00000040,
118 		0x66E, 0x00000005,
119 		0x700, 0x00000021,
120 		0x701, 0x00000043,
121 		0x702, 0x00000065,
122 		0x703, 0x00000087,
123 		0x708, 0x00000021,
124 		0x709, 0x00000043,
125 		0x70A, 0x00000065,
126 		0x70B, 0x00000087,
127 };
128 
odm_ConfigMAC_8188E(struct odm_dm_struct * pDM_Odm,u32 Addr,u8 Data)129 static void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data)
130 {
131 	rtw_write8(pDM_Odm->Adapter, Addr, Data);
132 }
133 
ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct * dm_odm)134 int ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *dm_odm)
135 {
136 	#define READ_NEXT_PAIR(v1, v2, i) do { i += 2; v1 = array[i]; v2 = array[i + 1]; } while (0)
137 
138 	u32     hex         = 0;
139 	u32     i;
140 	u32     array_len    = ARRAY_SIZE(array_MAC_REG_8188E);
141 	u32    *array       = array_MAC_REG_8188E;
142 	bool	biol = false;
143 
144 	struct adapter *adapt =  dm_odm->Adapter;
145 	struct xmit_frame	*pxmit_frame = NULL;
146 	u8 bndy_cnt = 1;
147 	hex += ODM_ITRF_USB << 8;
148 	hex += ODM_CE << 16;
149 	hex += 0xFF000000;
150 
151 	biol = rtw_IOL_applied(adapt);
152 
153 	if (biol) {
154 		pxmit_frame = rtw_IOL_accquire_xmit_frame(adapt);
155 		if (!pxmit_frame) {
156 			pr_info("rtw_IOL_accquire_xmit_frame failed\n");
157 			return -ENOMEM;
158 		}
159 	}
160 
161 	for (i = 0; i < array_len; i += 2) {
162 		u32 v1 = array[i];
163 		u32 v2 = array[i + 1];
164 
165 		/*  This (offset, data) pair meets the condition. */
166 		if (v1 < 0xCDCDCDCD) {
167 				if (biol) {
168 					if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
169 						bndy_cnt++;
170 					rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF);
171 				} else {
172 					odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2);
173 				}
174 				continue;
175 		} else { /*  This line is the start line of branch. */
176 			if (!Checkcondition(array[i], hex)) {
177 				/*  Discard the following (offset, data) pairs. */
178 				READ_NEXT_PAIR(v1, v2, i);
179 				while (v2 != 0xDEAD &&
180 				       v2 != 0xCDEF &&
181 				       v2 != 0xCDCD && i < array_len - 2) {
182 					READ_NEXT_PAIR(v1, v2, i);
183 				}
184 				i -= 2; /*  prevent from for-loop += 2 */
185 			} else { /*  Configure matched pairs and skip to end of if-else. */
186 				READ_NEXT_PAIR(v1, v2, i);
187 				while (v2 != 0xDEAD &&
188 				       v2 != 0xCDEF &&
189 				       v2 != 0xCDCD && i < array_len - 2) {
190 					if (biol) {
191 						if (rtw_IOL_cmd_boundary_handle(pxmit_frame))
192 							bndy_cnt++;
193 						rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF);
194 					} else {
195 						odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2);
196 					}
197 
198 					READ_NEXT_PAIR(v1, v2, i);
199 				}
200 				while (v2 != 0xDEAD && i < array_len - 2)
201 					READ_NEXT_PAIR(v1, v2, i);
202 			}
203 		}
204 	}
205 	if (biol) {
206 		if (!rtl8188e_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) {
207 			pr_info("~~~ MAC IOL_exec_cmds Failed !!!\n");
208 			return -1;
209 		}
210 	}
211 	return 0;
212 }
213