blob: 212d671231c49f9bc231d4b3a0505129b5c24305 [file] [log] [blame]
R. Andrew Ohana81c2e052012-10-03 19:52:52 -07001/*
2 * Copyright (C) 2012, The CyanogenMod Project
3 * Daniel Hillenbrand <codeworkx@cyanogenmod.com>
4 * Marco Hillenbrand <marco.hillenbrand@googlemail.com>
Paul Keith59ba89e2017-02-07 12:30:45 -06005 * Copyright (C) 2017, The LineageOS Project
R. Andrew Ohana81c2e052012-10-03 19:52:52 -07006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
Andreas Schneider2b601792015-01-26 23:14:17 +010020#define LOG_TAG "macloader"
21#define LOG_NDEBUG 0
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070022
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
Andreas Schneider3ff947b2015-01-26 22:56:30 +010026#include <sys/types.h>
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070027#include <sys/stat.h>
Andreas Schneider3ff947b2015-01-26 22:56:30 +010028#include <fcntl.h>
Andreas Schneider7f517d72015-01-26 23:19:03 +010029#include <unistd.h>
Andreas Schneider7558b9d2015-01-26 23:29:18 +010030#include <pwd.h>
Caio Schnepper02c9c712015-10-10 02:14:28 -030031#include <errno.h>
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070032
Andreas Schneider2b601792015-01-26 23:14:17 +010033#include <cutils/log.h>
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070034
Paul Keith59ba89e2017-02-07 12:30:45 -060035#include <samsung_macloader.h>
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070036
37enum Type {
38 NONE,
39 MURATA,
40 SEMCOSH,
Andreas Schneiderf3ba7202015-01-03 19:29:28 +010041 SEMCOVE,
42 SEMCO3RD,
Christopher N. Hesse0ed56702015-01-25 17:38:23 +010043 SEMCO,
Andreas Schneiderf3ba7202015-01-03 19:29:28 +010044 WISOL
R. Andrew Ohana81c2e052012-10-03 19:52:52 -070045};
46
Andreas Schneider3ff947b2015-01-26 22:56:30 +010047static int wifi_change_nvram_calibration(const char *nvram_file,
48 const char *type)
49{
50 int len;
51 int fd = -1;
52 int ret = 0;
53 struct stat sb;
54 char nvram_str[1024] = { 0 };
55
56 if (nvram_file == NULL || type == NULL) {
57 return -1;
58 }
59
60 ret = stat(nvram_file, &sb);
61 if (ret != 0) {
62 ALOGE("Failed to check for NVRAM calibration file '%s' - error: %s",
63 nvram_file,
64 strerror(errno));
65 return -1;
66 }
67
68 ALOGD("Using NVRAM calibration file: %s\n", nvram_file);
69
70 fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_NVRAM_PATH_PARAM, O_WRONLY));
71 if (fd < 0) {
72 ALOGE("Failed to open wifi nvram config path %s - error: %s",
73 WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
74 return -1;
75 }
76
77 len = strlen(nvram_file) + 1;
78 if (TEMP_FAILURE_RETRY(write(fd, nvram_file, len)) != len) {
79 ALOGE("Failed to write to wifi config path %s - error: %s",
80 WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
81 ret = -1;
82 goto out;
83 }
84
85 snprintf(nvram_str, sizeof(nvram_str), "%s_%s",
86 nvram_file, type);
87
88 ALOGD("Changing NVRAM calibration file for %s chipset\n", type);
89
90 ret = stat(nvram_str, &sb);
91 if (ret != 0) {
92 ALOGW("NVRAM calibration file '%s' doesn't exist", nvram_str);
93 /*
94 * We were able to write the default calibration file. So
95 * continue here without returning an error.
96 */
97 ret = 0;
98 goto out;
99 }
100
101 len = strlen(nvram_str) + 1;
102 if (TEMP_FAILURE_RETRY(write(fd, nvram_str, len)) != len) {
103 ALOGW("Failed to write to wifi config path %s - error: %s",
104 WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
105 /*
106 * We were able to write the default calibration file. So
107 * continue here without returning an error.
108 */
109 ret = 0;
110 goto out;
111 }
112
113 ALOGD("NVRAM calibration file set to '%s'\n", nvram_str);
114
115 ret = 0;
116out:
117 if (fd != -1) {
118 close(fd);
119 }
120 return ret;
121}
122
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700123int main() {
124 FILE* file;
125 FILE* cidfile;
126 char* str;
127 char mac_addr_half[9];
128 int ret = -1;
129 int amode;
130 enum Type type = NONE;
131
132 /* open mac addr file */
133 file = fopen(MACADDR_PATH, "r");
codeworkx84f8d1d2012-12-13 17:23:45 +0100134 if (file == 0) {
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700135 fprintf(stderr, "open(%s) failed\n", MACADDR_PATH);
136 ALOGE("Can't open %s\n", MACADDR_PATH);
137 return -1;
138 }
139
140 /* get and compare mac addr */
141 str = fgets(mac_addr_half, 9, file);
Andreas Schneider3a73bd32015-01-26 23:30:13 +0100142 fclose(file);
codeworkx84f8d1d2012-12-13 17:23:45 +0100143 if (str == 0) {
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700144 fprintf(stderr, "fgets() from file %s failed\n", MACADDR_PATH);
145 ALOGE("Can't read from %s\n", MACADDR_PATH);
146 return -1;
147 }
148
Liam Alford2fccbdf2013-11-21 13:55:42 +0000149 /* murata
150 ref: http://hwaddress.com/?q=ACT */
151 if (strncasecmp(mac_addr_half, "00:0e:6d", 9) == 0 ||
152 strncasecmp(mac_addr_half, "00:13:e0", 9) == 0 ||
153 strncasecmp(mac_addr_half, "00:21:e8", 9) == 0 ||
154 strncasecmp(mac_addr_half, "00:26:e8", 9) == 0 ||
155 strncasecmp(mac_addr_half, "00:37:6d", 9) == 0 ||
156 strncasecmp(mac_addr_half, "00:60:57", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300157 strncasecmp(mac_addr_half, "00:ae:fa", 9) == 0 ||
Liam Alford2fccbdf2013-11-21 13:55:42 +0000158 strncasecmp(mac_addr_half, "04:46:65", 9) == 0 ||
159 strncasecmp(mac_addr_half, "10:5f:06", 9) == 0 ||
JustArchi300ecd32014-09-28 23:55:36 +0200160 strncasecmp(mac_addr_half, "10:a5:d0", 9) == 0 ||
RGIBa7a0ecd2016-12-11 15:08:09 +0100161 strncasecmp(mac_addr_half, "10:d5:42", 9) == 0 ||
Liam Alford2fccbdf2013-11-21 13:55:42 +0000162 strncasecmp(mac_addr_half, "14:7d:c5", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300163 strncasecmp(mac_addr_half, "1c:99:4c", 9) == 0 ||
Liam Alford2fccbdf2013-11-21 13:55:42 +0000164 strncasecmp(mac_addr_half, "20:02:af", 9) == 0 ||
165 strncasecmp(mac_addr_half, "40:f3:08", 9) == 0 ||
166 strncasecmp(mac_addr_half, "44:a7:cf", 9) == 0 ||
167 strncasecmp(mac_addr_half, "5c:da:d4", 9) == 0 ||
168 strncasecmp(mac_addr_half, "5c:f8:a1", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300169 strncasecmp(mac_addr_half, "60:21:c0", 9) == 0 ||
170 strncasecmp(mac_addr_half, "60:f1:89", 9) == 0 ||
JustArchi300ecd32014-09-28 23:55:36 +0200171 strncasecmp(mac_addr_half, "78:4b:87", 9) == 0 ||
RGIB1bf77692016-12-10 11:37:34 +0100172 strncasecmp(mac_addr_half, "78:52:1a", 9) == 0 ||
Liam Alford2fccbdf2013-11-21 13:55:42 +0000173 strncasecmp(mac_addr_half, "88:30:8a", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300174 strncasecmp(mac_addr_half, "90:b6:86", 9) == 0 ||
175 strncasecmp(mac_addr_half, "98:f1:70", 9) == 0 ||
176 strncasecmp(mac_addr_half, "a0:cc:2b", 9) == 0 ||
177 strncasecmp(mac_addr_half, "a4:08:ea", 9) == 0 ||
178 strncasecmp(mac_addr_half, "b0:72:bf", 9) == 0 ||
179 strncasecmp(mac_addr_half, "b8:d7:af", 9) == 0 ||
RGIB1bf77692016-12-10 11:37:34 +0100180 strncasecmp(mac_addr_half, "c8:14:79", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300181 strncasecmp(mac_addr_half, "d0:e4:4a", 9) == 0 ||
182 strncasecmp(mac_addr_half, "d8:c4:6a", 9) == 0 ||
183 strncasecmp(mac_addr_half, "dc:ef:ca", 9) == 0 ||
MarcKed973a7b2014-12-30 17:52:55 +0100184 strncasecmp(mac_addr_half, "f0:27:65", 9) == 0 ||
Kevin F. Haggertyb2159232016-10-29 10:28:23 -0600185 strncasecmp(mac_addr_half, "fc:c2:de", 9) == 0 ||
186 strncasecmp(mac_addr_half, "fc:db:b3", 9) == 0) {
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700187 type = MURATA;
188 }
189
190 /* semcosh */
MarcKea81d58b2014-12-10 19:12:54 +0100191 if (strncasecmp(mac_addr_half, "34:23:ba", 9) == 0 ||
192 strncasecmp(mac_addr_half, "38:aa:3c", 9) == 0 ||
193 strncasecmp(mac_addr_half, "5c:0a:5b", 9) == 0 ||
194 strncasecmp(mac_addr_half, "88:32:9b", 9) == 0 ||
195 strncasecmp(mac_addr_half, "90:18:7c", 9) == 0 ||
Ethan Chen727dea72013-07-31 13:18:51 -0700196 strncasecmp(mac_addr_half, "cc:3a:61", 9) == 0) {
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700197 type = SEMCOSH;
198 }
199
Andreas Schneiderf3ba7202015-01-03 19:29:28 +0100200 /* semco3rd */
Fevaxe9b45af2017-01-24 19:32:17 -0300201 if (strncasecmp(mac_addr_half, "2c:0e:3d", 9) == 0 ||
202 strncasecmp(mac_addr_half, "54:88:0e", 9) == 0 ||
203 strncasecmp(mac_addr_half, "84:38:38", 9) == 0 ||
204 strncasecmp(mac_addr_half, "8c:f5:a3", 9) == 0 ||
Kevin F. Haggerty1d092982016-11-30 05:38:41 -0700205 strncasecmp(mac_addr_half, "ac:36:13", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300206 strncasecmp(mac_addr_half, "ac:5f:3e", 9) == 0 ||
207 strncasecmp(mac_addr_half, "b4:79:a7", 9) == 0 ||
208 strncasecmp(mac_addr_half, "c0:97:27", 9) == 0 ||
Kevin F. Haggertyb2159232016-10-29 10:28:23 -0600209 strncasecmp(mac_addr_half, "c0:bd:d1", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300210 strncasecmp(mac_addr_half, "c8:ba:94", 9) == 0 ||
211 strncasecmp(mac_addr_half, "d0:25:44", 9) == 0 ||
Kevin F. Haggertyd4ee3592016-10-22 09:59:15 -0600212 strncasecmp(mac_addr_half, "e8:50:8b", 9) == 0 ||
213 strncasecmp(mac_addr_half, "ec:1f:72", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300214 strncasecmp(mac_addr_half, "ec:9b:f3", 9) == 0 ||
Kevin F. Haggertyd4ee3592016-10-22 09:59:15 -0600215 strncasecmp(mac_addr_half, "f0:25:b7", 9) == 0 ||
Fevaxe9b45af2017-01-24 19:32:17 -0300216 strncasecmp(mac_addr_half, "f4:09:d8", 9) == 0 ||
217 strncasecmp(mac_addr_half, "f8:04:2e", 9) == 0) {
Andreas Schneiderf3ba7202015-01-03 19:29:28 +0100218 type = SEMCO3RD;
219 }
220
Christopher N. Hesse0ed56702015-01-25 17:38:23 +0100221 /* semco */
Fevaxe9b45af2017-01-24 19:32:17 -0300222 if (strncasecmp(mac_addr_half, "4c:66:41", 9) == 0 ||
223 strncasecmp(mac_addr_half, "51:f6:6b", 9) == 0 ||
Christopher N. Hessec7dd07a2017-02-09 18:00:32 +0100224 strncasecmp(mac_addr_half, "ec:9b:f3", 9) == 0 ||
225 strncasecmp(mac_addr_half, "d8:c4:e9", 9) == 0) {
Christopher N. Hesse0ed56702015-01-25 17:38:23 +0100226 type = SEMCO;
227 }
228
Andreas Schneiderf3ba7202015-01-03 19:29:28 +0100229 /* wisol */
Paul Keith6e351572017-02-07 14:27:33 -0600230 if (strncasecmp(mac_addr_half, "48:5a:3f", 9) == 0 ||
231 strncasecmp(mac_addr_half, "70:2c:1f", 9) == 0) {
Andreas Schneiderf3ba7202015-01-03 19:29:28 +0100232 type = WISOL;
233 }
234
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700235 if (type != NONE) {
Andreas Schneider3ff947b2015-01-26 22:56:30 +0100236 const char *nvram_file;
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100237 const char *type_str;
Andreas Schneider7558b9d2015-01-26 23:29:18 +0100238 struct passwd *pwd;
239 int fd;
240
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700241 /* open cid file */
242 cidfile = fopen(CID_PATH, "w");
243 if(cidfile == 0) {
244 fprintf(stderr, "open(%s) failed\n", CID_PATH);
245 ALOGE("Can't open %s\n", CID_PATH);
246 return -1;
247 }
248
249 switch(type) {
250 case NONE:
251 return -1;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700252 case MURATA:
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100253 type_str = "murata";
254 break;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700255 case SEMCOSH:
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100256 type_str = "semcosh";
257 break;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700258 case SEMCOVE:
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100259 type_str = "semcove";
260 break;
Andreas Schneiderf3ba7202015-01-03 19:29:28 +0100261 case SEMCO3RD:
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100262 type_str = "semco3rd";
Andreas Schneiderf3ba7202015-01-03 19:29:28 +0100263 break;
Christopher N. Hesse0ed56702015-01-25 17:38:23 +0100264 case SEMCO:
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100265 type_str = "semco";
266 break;
Andreas Schneiderf3ba7202015-01-03 19:29:28 +0100267 case WISOL:
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100268 type_str = "wisol";
Andreas Schneiderf3ba7202015-01-03 19:29:28 +0100269 break;
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100270 }
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700271
Andreas Schneiderc7212d02015-01-26 22:45:26 +0100272 ALOGI("Settting wifi type to %s in %s\n", type_str, CID_PATH);
273
274 ret = fputs(type_str, cidfile);
codeworkx84f8d1d2012-12-13 17:23:45 +0100275 if (ret != 0) {
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700276 ALOGE("Can't write to %s\n", CID_PATH);
Andreas Schneiderca1a0ee2015-01-26 22:49:49 +0100277 return 1;
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700278 }
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700279
Andreas Schneider7f517d72015-01-26 23:19:03 +0100280 /* Change permissions of cid file */
281 ALOGD("Change permissions of %s\n", CID_PATH);
282
283 fd = fileno(cidfile);
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700284 amode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
Andreas Schneider7f517d72015-01-26 23:19:03 +0100285 ret = fchmod(fd, amode);
Andreas Schneider7f517d72015-01-26 23:19:03 +0100286 if (ret != 0) {
Andreas Schneider7558b9d2015-01-26 23:29:18 +0100287 fclose(cidfile);
Andreas Schneider7f517d72015-01-26 23:19:03 +0100288 ALOGE("Can't set permissions on %s - %s\n",
289 CID_PATH, strerror(errno));
290 return 1;
291 }
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700292
Andreas Schneider7558b9d2015-01-26 23:29:18 +0100293 pwd = getpwnam("system");
294 if (pwd == NULL) {
295 fclose(cidfile);
296 ALOGE("Failed to find 'system' user - %s\n",
297 strerror(errno));
298 return 1;
299 }
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700300
Andreas Schneider7558b9d2015-01-26 23:29:18 +0100301 ret = fchown(fd, pwd->pw_uid, pwd->pw_gid);
302 fclose(cidfile);
303 if (ret != 0) {
304 ALOGE("Failed to change owner of %s - %s\n",
305 CID_PATH, strerror(errno));
306 return 1;
307 }
Andreas Schneider3ff947b2015-01-26 22:56:30 +0100308
309 nvram_file = WIFI_DRIVER_NVRAM_PATH;
310 if (nvram_file != NULL) {
311 ret = wifi_change_nvram_calibration(nvram_file, type_str);
312 if (ret != 0) {
313 return 1;
314 }
315 }
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700316 } else {
317 /* delete cid file if no specific type */
318 ALOGD("Deleting file %s\n", CID_PATH);
319 remove(CID_PATH);
320 }
R. Andrew Ohana81c2e052012-10-03 19:52:52 -0700321 return 0;
322}