blob: c827aea8726eb3fe34dc1b069503e8b61d9339cc [file] [log] [blame]
Andreas Schneider2140f1f2015-12-19 14:29:21 +01001/*
2 * Copyright (c) 2015 Andreas Schneider <asn@cryptomilk.org>
Christopher N. Hesse231dc652017-08-02 15:21:35 +02003 * Copyright (c) 2017 Christopher N. Hesse <raymanfx@gmail.com>
Andreas Schneider2140f1f2015-12-19 14:29:21 +01004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#define LOG_TAG "wifiloader"
19#define LOG_NDEBUG 0
20
21#include <errno.h>
Christopher N. Hesse231dc652017-08-02 15:21:35 +020022#include <fcntl.h>
Andreas Schneider2140f1f2015-12-19 14:29:21 +010023#include <stdio.h>
Christopher N. Hesse231dc652017-08-02 15:21:35 +020024#include <stdlib.h>
Andreas Schneider2140f1f2015-12-19 14:29:21 +010025#include <string.h>
26#include <cutils/log.h>
Christopher N. Hesse5b6ec562018-01-22 00:20:06 +010027#include <cutils/properties.h>
Christopher N. Hesse231dc652017-08-02 15:21:35 +020028#include <sys/stat.h>
29#include <sys/syscall.h>
Andreas Schneider2140f1f2015-12-19 14:29:21 +010030
Christopher N. Hesse231dc652017-08-02 15:21:35 +020031#define DEFERRED_INITCALLS "/proc/deferred_initcalls"
32
33#ifndef WIFI_DRIVER_MODULE_NAME
34#define WIFI_DRIVER_MODULE_NAME "wlan"
35#endif
36
37#ifndef WIFI_DRIVER_MODULE_PATH
38#define WIFI_DRIVER_MODULE_PATH "/system/lib/modules/" WIFI_DRIVER_MODULE_NAME ".ko"
39#endif
40
41#define finit_module(fd, params, flags) syscall(__NR_finit_module, fd, params, flags)
42
43
44static int check_module_loaded(char const *tag)
45{
46 FILE *proc;
47 char line[126];
48
49 if ((proc = fopen("/proc/modules", "r")) == NULL) {
50 ALOGW("Could not open %s: %s", "/proc/modules", strerror(errno));
51 return -errno;
52 }
53
54 while ((fgets(line, sizeof(line), proc)) != NULL) {
55 if (strncmp(line, tag, strlen(tag)) == 0) {
56 fclose(proc);
57 return 1;
58 }
59 }
60
61 fclose(proc);
62 return 0;
63}
64
65static int load_module(char const *path)
66{
67 int fd;
68
69 if (check_module_loaded(WIFI_DRIVER_MODULE_NAME) > 0) {
70 ALOGE("Driver: %s already loaded", path);
71 return -1;
72 }
73
74 fd = open(path, O_RDONLY);
75 if (fd == -1) {
76 ALOGE("Failed to open %s - error: %s", path, strerror(errno));
77 return -errno;
78 }
79
80 // load the .ko image
81 if (finit_module(fd, "", 0) != 0) {
82 ALOGE("Failed to load module %s - error: %s", path, strerror(errno));
83 close(fd);
84 return -errno;
85 }
86
Christopher N. Hesse5b6ec562018-01-22 00:20:06 +010087 // let wifi HAL know we succeeded
88 ALOGV("Successfully loaded WLAN module: %s", WIFI_DRIVER_MODULE_NAME);
89 property_set("wlan.driver.status", "ok");
90
Christopher N. Hesse231dc652017-08-02 15:21:35 +020091 close(fd);
92 return 0;
93}
Andreas Schneider2140f1f2015-12-19 14:29:21 +010094
95int main(void)
96{
97 char buf[8] = { '\0' };
98 FILE *fp;
99 size_t r;
Christopher N. Hesse231dc652017-08-02 15:21:35 +0200100 int fd;
101 struct stat st;
102
103 if (stat(WIFI_DRIVER_MODULE_PATH, &st) == 0) {
104 ALOGD("Loading WiFi kernel module: %s", WIFI_DRIVER_MODULE_PATH);
105 load_module(WIFI_DRIVER_MODULE_PATH);
106 }
Andreas Schneider2140f1f2015-12-19 14:29:21 +0100107
108 ALOGD("Trigger initcall of deferred modules\n");
109
110 fp = fopen(DEFERRED_INITCALLS, "r");
111 if (fp == NULL) {
112 ALOGE("Failed to open %s - error: %s\n",
113 DEFERRED_INITCALLS,
114 strerror(errno));
115 return -errno;
116 }
117
118 r = fread(buf, sizeof(buf), 1, fp);
119 fclose(fp);
120
121 ALOGV("%s=%s\n", DEFERRED_INITCALLS, buf);
122
123 return 0;
124}