blob: 34256a40fd02d692a525aff31bf8a691bbcd03ef [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001#include "loader_pwr.h"
2#include <string.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <fcntl.h>
6#include <errno.h>
7#include <unistd.h>
8// For directory operation
9#include <dirent.h>
10#include <sys/ioctl.h>
11#include <sys/utsname.h>
12
13#ifdef LOG_TAG
14#undef LOG_TAG
15#endif
16#define LOG_TAG "wmt_loader"
17
18#define WCN_COMBO_LOADER_CHIP_ID_PROP "persist.mtk.wcn.combo.chipid"
19#ifndef ALOGI
20#define ALOGI printf
21#endif
22#ifndef PROPERTY_VALUE_MAX
23#define PROPERTY_VALUE_MAX (128)
24#endif
25
26#define WCN_COMBO_LOADER_DEV "/dev/wmtdetect"
27#define WCN_COMBO_DEF_CHIPID "0x6582"
28#define WMT_MODULES_PRE "/system/lib/modules/"
29#define WMT_KO_PATH_PREFIX "/lib/modules/"
30#define WMT_WIFI_MODULE_PATH "/kernel/drivers/misc/mediatek/connectivity/wlan/wmt_chrdev_wifi.ko"
31#define WMT_WLAN_MODULE_PATH "/kernel/drivers/misc/mediatek/connectivity/wlan/gen3/wlan_gen3.ko"
32/* connectivity modules are built out of kernel tree */
33#define WMT_OUT_KO_PATH_PREFIX "/lib/modules/mt66xx/"
34#define WMT_OUT_WMT_WIFI_MODULE_PATH "wmt_chrdev_wifi.ko"
35#define WMT_OUT_WLAN_MODULE_PATH "wlan_drv_gen3.ko"
36
37#define WMT_MODULES_SUFF ".ko"
38#define WMT_IOC_MAGIC 'w'
39#define COMBO_IOCTL_GET_CHIP_ID _IOR(WMT_IOC_MAGIC, 0, int)
40#define COMBO_IOCTL_SET_CHIP_ID _IOW(WMT_IOC_MAGIC, 1, int)
41#define COMBO_IOCTL_EXT_CHIP_DETECT _IOR(WMT_IOC_MAGIC, 2, int)
42#define COMBO_IOCTL_GET_SOC_CHIP_ID _IOR(WMT_IOC_MAGIC, 3, int)
43#define COMBO_IOCTL_DO_MODULE_INIT _IOR(WMT_IOC_MAGIC, 4, int)
44#define COMBO_IOCTL_MODULE_CLEANUP _IOR(WMT_IOC_MAGIC, 5, int)
45#define COMBO_IOCTL_EXT_CHIP_PWR_ON _IOR(WMT_IOC_MAGIC, 6, int)
46#define COMBO_IOCTL_EXT_CHIP_PWR_OFF _IOR(WMT_IOC_MAGIC, 7, int)
47#define COMBO_IOCTL_DO_SDIO_AUDOK _IOR(WMT_IOC_MAGIC, 8, int)
48
49
50
51#define STP_WMT_MODULE_PRE_FIX "mtk_stp_wmt"
52#define STP_BT_MODULE_PRE_FIX "mtk_stp_bt"
53#define STP_GPS_MODULE_PRE_FIX "mtk_stp_gps"
54#define HIF_SDIO_MODULE_PRE_FIX "mtk_hif_sdio"
55#define STP_SDIO_MODULE_PRE_FIX "mtk_stp_sdio"
56#define STP_UART_MODULE_PRE_FIX "mtk_stp_uart"
57
58
59
60static int gLoaderFd = -1;
61
62static char DRIVER_MODULE_PATH[64] = {0};
63static char DRIVER_MODULE_ARG[8] = "";
64static int chipid_array[] = {
650x6620,
660x6628,
670x6630,
680x6572,
690x6582,
700x6592,
710x8127,
720x6571,
730x6752,
740x6735,
750x0321,
760x0335,
770x0337,
780x8163,
790x6580,
800x6755,
810x0326,
820x6797,
830x0279
84};
85static char chip_version[PROPERTY_VALUE_MAX] = {0};
86
87static int g_remove_ko_flag = 1;
88
89
90extern int init_module(void *, unsigned long, const char *);
91extern int delete_module(const char *, unsigned int);
92extern int load_fm_module(int chip_id);
93//extern int load_wifi_module(int chip_id);
94extern int load_ant_module(int chip_id);
95// insmod
96static int is_chipId_vaild(int chipid) {
97 int iret;
98 unsigned char i;
99 iret = -1;
100
101 for (i = 0; i < sizeof(chipid_array)/sizeof(0x6630); i++) {
102 if (chipid == chipid_array[i]) {
103 ALOGI("is_chipId_vaild: %d :0x%x!\n", i, chipid);
104 iret = 0;
105 break;
106 }
107 }
108 return iret;
109}
110
111int do_kernel_module_init(int gLoaderFd, int chipId) {
112 int iRet = 0;
113 if (gLoaderFd < 0) {
114 ALOGI("invalid gLoaderFd: %d\n", gLoaderFd);
115 return -1;
116 }
117
118 iRet = ioctl(gLoaderFd, COMBO_IOCTL_MODULE_CLEANUP, chipId);
119 if (iRet) {
120 ALOGI("do WMT-DETECT module cleanup failed: %d\n", iRet);
121 return -2;
122 }
123 iRet = ioctl(gLoaderFd, COMBO_IOCTL_DO_MODULE_INIT, chipId);
124 if (iRet) {
125 ALOGI("do kernel module init failed: %d\n", iRet);
126 return -3;
127 }
128 ALOGI("do kernel module init succeed: %d\n", iRet);
129 return 0;
130}
131
132void *load_file(const char *fn, unsigned *_sz)
133{
134 char *data;
135 int sz;
136 int fd;
137 data = 0;
138
139 fd = open(fn, O_RDONLY);
140 if(fd < 0) return 0;
141
142 sz = lseek(fd, 0, SEEK_END);
143 if(sz < 0)
144 goto oops;
145
146 if(lseek(fd, 0, SEEK_SET) != 0)
147 goto oops;
148
149 data = (char*) malloc(sz + 1);
150 if(data == 0)
151 goto oops;
152
153 if(read(fd, data, sz) != sz)
154 goto oops;
155
156 close(fd); data[sz] = 0;
157
158 if(_sz)
159 *_sz = sz;
160
161 return data;
162
163oops:
164 close(fd);
165 if(data != 0)
166 free(data);
167
168 return 0;
169}
170
171//insmod
172static int insmod(const char *filename, const char *args)
173{
174 void *module;
175 unsigned int size;
176 int ret;
177
178 module = load_file(filename, &size);
179 if (!module)
180 return -1;
181
182 ret = init_module(module, size, args);
183
184 free(module);
185
186 return ret;
187}
188
189
190int load_wifi_module(int chip_id)
191{
192 int ret = -1;
193 struct utsname utsname;
194 char wifi_module_path[100] = "";
195 char wlan_module_path[100] = "";
196
197 if (!(uname(&utsname))) {
198 /* Use modules built within kernel tree */
199 sprintf(wifi_module_path, "%s%s%s", WMT_KO_PATH_PREFIX, utsname.release, WMT_WIFI_MODULE_PATH);
200 sprintf(wlan_module_path, "%s%s%s", WMT_KO_PATH_PREFIX, utsname.release, WMT_WLAN_MODULE_PATH);
201 } else
202 return -1;
203
204 if ((access(wifi_module_path,0) < 0) && (access(wlan_module_path,0) < 0))
205 {
206 /* Use modules built out of kernel tree */
207 printf("Use modules built out of kernel tree\n");
208 memset(wifi_module_path, 0, sizeof(wifi_module_path));
209 memset(wlan_module_path, 0, sizeof(wlan_module_path));
210 sprintf(wifi_module_path, "%s%s", WMT_OUT_KO_PATH_PREFIX, WMT_OUT_WMT_WIFI_MODULE_PATH);
211 sprintf(wlan_module_path, "%s%s", WMT_OUT_KO_PATH_PREFIX, WMT_OUT_WLAN_MODULE_PATH);
212 }
213
214 if (chip_id == 0x6630) {
215 //insert 6630 driver
216 if(0 == insmod(wifi_module_path, DRIVER_MODULE_ARG)){
217 ret = 0;
218 printf("Success to insmod wmt wifi module\n");
219 } else
220 printf("Fail to insmod wmt wifi module %s\n", wifi_module_path);
221
222 if(0 == insmod(wlan_module_path, DRIVER_MODULE_ARG)){
223 ret = 0;
224 printf("Success to insmod wlan module\n");
225 } else
226 printf("Fail to insmod wlan module %s\n", wlan_module_path);
227 }
228
229 return ret;
230}
231
232
233/* TBD in platform-specific way */
234static int get_persist_chip_id(char *str, size_t len) { return -1; }
235static int set_persist_chip_id(int id) { return 0; }
236static void set_proc_owner(void) { }
237static void update_driver_ready(void) { }
238
239int main(int argc, char *argv[]) {
240 int iRet = -1;
241 int noextChip = -1;
242 int chipId = -1;
243 int count = 0;
244 char chipidStr[PROPERTY_VALUE_MAX] = {0};
245 char readyStr[PROPERTY_VALUE_MAX] = {0};
246 int loadFmResult = -1;
247 int loadAntResult = -1;
248 int loadWlanResult = -1;
249 int retryCounter = 1;
250 int autokRet = 0;
251 do {
252 gLoaderFd = open(WCN_COMBO_LOADER_DEV, O_RDWR | O_NOCTTY);
253 if (gLoaderFd < 0) {
254 count++;
255 ALOGI("Can't open device node(%s) count(%d)\n", WCN_COMBO_LOADER_DEV, count);
256 usleep(300000);
257 } else
258 break;
259 } while (1);
260
261 // read from system property
262 chipId = get_persist_chip_id(chipidStr, sizeof(chipidStr));
263
264 if (-1 != is_chipId_vaild(chipId)) {
265 /*valid chipid detected*/
266 ALOGI("key:(%s)-value:(%s),chipId:0x%04x,iRet(%d)\n",
267 WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr, chipId, iRet);
268 if (0x6630 == chipId) {
269 retryCounter = 10;
270 /*trigger autok process, incase last autok process is
271 interrupted by abnormal power off or battery down*/
272 do {
273 /*power on combo chip*/
274 iRet = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_PWR_ON);
275 if (0 != iRet) {
276 ALOGI("external combo chip power on failed\n");
277 noextChip = 1;
278 } else {
279 /*detect is there is an external combo chip*/
280 noextChip = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_DETECT, NULL);
281 }
282
283 if (noextChip) {
284 // do nothing
285 ALOGI("no external combo chip detected\n");
286 } else {
287 ALOGI("external combo chip detected\n");
288 chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_CHIP_ID, NULL);
289 ALOGI("chipid (0x%x) detected\n", chipId);
290 }
291
292 if (0 == noextChip) {
293 autokRet = ioctl(gLoaderFd, COMBO_IOCTL_DO_SDIO_AUDOK, chipId);
294 if (0 != autokRet) {
295 ALOGI("do SDIO3.0 autok failed\n");
296 } else {
297 ALOGI("do SDIO3.0 autok succeed\n");
298 }
299 }
300 iRet = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_PWR_OFF);
301 if (0 != iRet) {
302 ALOGI("external combo chip power off failed\n");
303 } else {
304 ALOGI("external combo chip power off succeed\n");
305 }
306 if ((0 == noextChip) && (-1 == chipId)) {
307 /*extenral chip detected, but no valid chipId detected, retry*/
308 retryCounter--;
309 ALOGI("chipId detect failed, retrying, left retryCounter:%d\n", retryCounter);
310 usleep(500000);
311 } else
312 break;
313 }while (0 < retryCounter);
314 chipId = 0x6630;
315 }
316 } else {
317 /*trigger external combo chip detect and chip identification process*/
318 do {
319 /*power on combo chip*/
320 iRet = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_PWR_ON);
321 if (0 != iRet) {
322 ALOGI("external combo chip power on failed\n");
323 noextChip = 1;
324 } else {
325 /*detect is there is an external combo chip*/
326 noextChip = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_DETECT, NULL);
327 }
328
329 if (noextChip) { // use soc itself
330 ALOGI("no external combo chip detected, get current soc chipid\n");
331 chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_SOC_CHIP_ID, NULL);
332 ALOGI("soc chipid (0x%x) detected\n", chipId);
333 } else {
334 ALOGI("external combo chip detected\n");
335 chipId = ioctl(gLoaderFd, COMBO_IOCTL_GET_CHIP_ID, NULL);
336 ALOGI("chipid (0x%x) detected\n", chipId);
337 }
338
339 sprintf(chipidStr, "0x%04x", chipId);
340 iRet = set_persist_chip_id(chipId);
341 if (0 != iRet) {
342 ALOGI("set property(%s) to %s failed,iRet:%d, errno:%d\n",
343 WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr, iRet, errno);
344 } else {
345 ALOGI("set property(%s) to %s succeed.\n", WCN_COMBO_LOADER_CHIP_ID_PROP, chipidStr);
346 }
347 if (0 == noextChip) {
348 autokRet = ioctl(gLoaderFd, COMBO_IOCTL_DO_SDIO_AUDOK, chipId);
349 if (0 != autokRet) {
350 ALOGI("do SDIO3.0 autok failed\n");
351 } else {
352 ALOGI("do SDIO3.0 autok succeed\n");
353 }
354 }
355 iRet = ioctl(gLoaderFd, COMBO_IOCTL_EXT_CHIP_PWR_OFF);
356 if (0 != iRet) {
357 ALOGI("external combo chip power off failed\n");
358 } else {
359 ALOGI("external combo chip power off succeed\n");
360 }
361 if ((0 == noextChip) && (-1 == chipId)) {
362 /*extenral chip detected, but no valid chipId detected, retry*/
363 retryCounter--;
364 usleep(500000);
365 ALOGI("chipId detect failed, retrying, left retryCounter:%d\n", retryCounter);
366 } else
367 break;
368 }while (0 < retryCounter);
369 }
370
371 /*set chipid to kernel*/
372 ioctl(gLoaderFd, COMBO_IOCTL_SET_CHIP_ID, chipId);
373
374 if (g_remove_ko_flag) {
375 if ((0x0321 == chipId) || (0x0335 == chipId) || (0x0337 == chipId)) {
376 chipId = 0x6735;
377 }
378 if (0x0326 == chipId) {
379 chipId = 0x6755;
380 }
381 if (0x0279 == chipId) {
382 chipId = 0x6797;
383 }
384 do_kernel_module_init(gLoaderFd, chipId);
385 if (gLoaderFd >= 0) {
386 close(gLoaderFd);
387 gLoaderFd = -1;
388 }
389
390 } else {
391#if 0
392 if (gLoaderFd >= 0) {
393 close(gLoaderFd);
394 gLoaderFd = -1;
395 }
396 ALOGI("rmmod mtk_wmt_detect\n");
397 rmmod("mtk_wmt_detect");
398 /*INSERT TARGET MODULE TO KERNEL*/
399 iRet = insert_wmt_modules(chipId, 0, -1);
400 /*this process should never fail*/
401 if (iRet) {
402 ALOGI("insert wmt modules fail(%d):(%d)\n", iRet, __LINE__);
403 /*goto done;*/
404 }
405
406 loadFmResult = load_fm_module(chipId);
407 if (loadFmResult) {
408 ALOGI("load FM modules fail(%d):(%d)\n", iRet, __LINE__);
409 /*continue, we cannot let this process interrupted by subsystem module load fail*/
410 /*goto done;*/
411 }
412
413 loadAntResult = load_ant_module(chipId);
414 if (loadAntResult) {
415 ALOGI("load ANT modules fail(%d):(%d)\n", iRet, __LINE__);
416 /*continue, we cannot let this process interrupted by subsystem module load fail*/
417 /*goto done;*/
418 }
419
420 loadWlanResult = load_wifi_module(chipId);
421 if (loadWlanResult) {
422 ALOGI("load WIFI modules fail(%d):(%d)\n", iRet, __LINE__);
423 /*continue, we cannot let this process interrupted by subsystem module load fail*/
424 /*goto done;*/
425 }
426#endif
427 }
428
429 // chown to set proc owner
430 set_proc_owner();
431 if (0/*0x6630 == chipId*/) {
432 retryCounter = 0;
433 int i_ret = -1;
434 do {
435 i_ret = loader_wmt_pwr_ctrl(1);
436 if (0 == i_ret)
437 break;
438 else {
439 loader_wmt_pwr_ctrl(0);
440 ALOGI("power on %x failed, retrying, retry counter:%d\n", chipId, retryCounter);
441 usleep(1000000);
442 }
443 retryCounter++;
444 } while (retryCounter < 20);
445 }
446
447 //insmod wmt_chrdev_wifi.ko & wlan_gen3.ko
448 loadWlanResult = load_wifi_module(chipId);
449 if (loadWlanResult) {
450 ALOGI("load WIFI modules fail(%d):(%d)\n", iRet, __LINE__);
451 }
452
453 // update wmt driver ready
454 update_driver_ready();
455
456 return iRet;
457}
458
459
460