Minor optimization: don't include code for routers not supported by the wifi driver...
[tomato.git] / release / src / router / rc / init.c
blobc8eef5381e381bae5d0ebc4ce63e8df625c78c15
1 /*
3 Copyright 2005, Broadcom Corporation
4 All Rights Reserved.
6 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
7 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
8 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
9 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
13 #include "rc.h"
15 #include <termios.h>
16 #include <dirent.h>
17 #include <sys/ioctl.h>
18 #include <sys/mount.h>
19 #include <time.h>
20 #include <errno.h>
21 #include <paths.h>
22 #include <sys/wait.h>
23 #include <sys/reboot.h>
24 #include <sys/klog.h>
25 #ifdef LINUX26
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #endif
29 #include <wlutils.h>
30 #include <bcmdevs.h>
32 #define SHELL "/bin/sh"
35 enum {
36 RESTART,
37 STOP,
38 START,
39 USER1,
40 IDLE,
41 REBOOT,
42 HALT,
43 INIT
46 static int fatalsigs[] = {
47 SIGILL,
48 SIGABRT,
49 SIGFPE,
50 SIGPIPE,
51 SIGBUS,
52 SIGSYS,
53 SIGTRAP,
54 SIGPWR
57 static int initsigs[] = {
58 SIGHUP,
59 SIGUSR1,
60 SIGUSR2,
61 SIGINT,
62 SIGQUIT,
63 SIGTERM
66 static char *defenv[] = {
67 "TERM=vt100",
68 "HOME=/",
69 "PATH=/usr/bin:/bin:/usr/sbin:/sbin",
70 "SHELL=" SHELL,
71 "USER=root",
72 NULL
75 static int noconsole = 0;
76 static volatile int state = INIT;
77 static volatile int signaled = -1;
80 /* Set terminal settings to reasonable defaults */
81 static void set_term(int fd)
83 struct termios tty;
85 tcgetattr(fd, &tty);
87 /* set control chars */
88 tty.c_cc[VINTR] = 3; /* C-c */
89 tty.c_cc[VQUIT] = 28; /* C-\ */
90 tty.c_cc[VERASE] = 127; /* C-? */
91 tty.c_cc[VKILL] = 21; /* C-u */
92 tty.c_cc[VEOF] = 4; /* C-d */
93 tty.c_cc[VSTART] = 17; /* C-q */
94 tty.c_cc[VSTOP] = 19; /* C-s */
95 tty.c_cc[VSUSP] = 26; /* C-z */
97 /* use line dicipline 0 */
98 tty.c_line = 0;
100 /* Make it be sane */
101 tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
102 tty.c_cflag |= CREAD|HUPCL|CLOCAL;
105 /* input modes */
106 tty.c_iflag = ICRNL | IXON | IXOFF;
108 /* output modes */
109 tty.c_oflag = OPOST | ONLCR;
111 /* local modes */
112 tty.c_lflag =
113 ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
115 tcsetattr(fd, TCSANOW, &tty);
118 static int console_init(void)
120 int fd;
122 /* Clean up */
123 ioctl(0, TIOCNOTTY, 0);
124 close(0);
125 close(1);
126 close(2);
127 setsid();
129 /* Reopen console */
130 if ((fd = open(_PATH_CONSOLE, O_RDWR)) < 0) {
131 /* Avoid debug messages is redirected to socket packet if no exist a UART chip, added by honor, 2003-12-04 */
132 open("/dev/null", O_RDONLY);
133 open("/dev/null", O_WRONLY);
134 open("/dev/null", O_WRONLY);
135 perror(_PATH_CONSOLE);
136 return errno;
138 dup2(fd, 0);
139 dup2(fd, 1);
140 dup2(fd, 2);
142 ioctl(0, TIOCSCTTY, 1);
143 tcsetpgrp(0, getpgrp());
144 set_term(0);
146 return 0;
150 * Waits for a file descriptor to change status or unblocked signal
151 * @param fd file descriptor
152 * @param timeout seconds to wait before timing out or 0 for no timeout
153 * @return 1 if descriptor changed status or 0 if timed out or -1 on error
155 static int waitfor(int fd, int timeout)
157 fd_set rfds;
158 struct timeval tv = { timeout, 0 };
160 FD_ZERO(&rfds);
161 FD_SET(fd, &rfds);
162 return select(fd + 1, &rfds, NULL, NULL, (timeout > 0) ? &tv : NULL);
165 static pid_t run_shell(int timeout, int nowait)
167 pid_t pid;
168 int sig;
170 /* Wait for user input */
171 if (waitfor(STDIN_FILENO, timeout) <= 0) return 0;
173 switch (pid = fork()) {
174 case -1:
175 perror("fork");
176 return 0;
177 case 0:
178 /* Reset signal handlers set for parent process */
179 for (sig = 0; sig < (_NSIG-1); sig++)
180 signal(sig, SIG_DFL);
182 /* Reopen console */
183 console_init();
184 printf("\n\nTomato %s\n\n", tomato_version);
186 /* Now run it. The new program will take over this PID,
187 * so nothing further in init.c should be run. */
188 execve(SHELL, (char *[]) { SHELL, NULL }, defenv);
190 /* We're still here? Some error happened. */
191 perror(SHELL);
192 exit(errno);
193 default:
194 if (nowait) {
195 return pid;
197 else {
198 waitpid(pid, NULL, 0);
199 return 0;
204 static void shutdn(int rb)
206 int i;
207 int act;
208 sigset_t ss;
210 _dprintf("shutdn rb=%d\n", rb);
212 sigemptyset(&ss);
213 for (i = 0; i < sizeof(fatalsigs) / sizeof(fatalsigs[0]); i++)
214 sigaddset(&ss, fatalsigs[i]);
215 for (i = 0; i < sizeof(initsigs) / sizeof(initsigs[0]); i++)
216 sigaddset(&ss, initsigs[i]);
217 sigaddset(&ss, SIGCHLD);
218 sigprocmask(SIG_BLOCK, &ss, NULL);
220 for (i = 30; i > 0; --i) {
221 if (((act = check_action()) == ACT_IDLE) || (act == ACT_REBOOT)) break;
222 cprintf("Busy with %d. Waiting before shutdown... %d\n", act, i);
223 sleep(1);
225 set_action(ACT_REBOOT);
227 cprintf("TERM\n");
228 kill(-1, SIGTERM);
229 sleep(2);
230 sync();
232 cprintf("KILL\n");
233 kill(-1, SIGKILL);
234 sleep(1);
235 sync();
237 umount("/jffs"); // may hang if not
238 sleep(1);
240 if (rb != -1) {
241 led(LED_WLAN, 0);
242 if (rb == 0) {
243 for (i = 4; i > 0; --i) {
244 led(LED_DMZ, 1);
245 led(LED_WHITE, 1);
246 usleep(250000);
247 led(LED_DMZ, 0);
248 led(LED_WHITE, 0);
249 usleep(250000);
254 reboot(rb ? RB_AUTOBOOT : RB_HALT_SYSTEM);
256 do {
257 sleep(1);
258 } while (1);
261 static void handle_fatalsigs(int sig)
263 _dprintf("fatal sig=%d\n", sig);
264 shutdn(-1);
267 void handle_reap(int sig)
269 while (waitpid(-1, NULL, WNOHANG) > 0) {
274 static void handle_initsigs(int sig)
276 // TRACE_PT("sig=%d state=%d, signaled=%d\n", sig, state, signaled);
278 switch (sig) {
279 case SIGHUP:
280 signaled = RESTART;
281 break;
282 case SIGUSR1:
283 signaled = USER1;
284 break;
285 case SIGUSR2:
286 signaled = START;
287 break;
288 case SIGINT:
289 signaled = STOP;
290 break;
291 case SIGTERM:
292 signaled = REBOOT;
293 break;
294 case SIGQUIT:
295 signaled = HALT;
296 break;
300 static int check_nv(const char *name, const char *value)
302 const char *p;
303 if (!nvram_match("manual_boot_nv", "1")) {
304 if (((p = nvram_get(name)) == NULL) || (strcmp(p, value) != 0)) {
305 // cprintf("Error: Critical variable %s is invalid. Resetting.\n", name);
306 nvram_set(name, value);
307 return 1;
310 return 0;
313 static void check_bootnv(void)
315 int dirty;
316 int hardware;
317 int model;
319 model = get_model();
320 dirty = 0;
322 switch (model) {
323 case MODEL_WTR54GS:
324 dirty |= check_nv("vlan0hwname", "et0");
325 dirty |= check_nv("vlan1hwname", "et0");
326 dirty |= check_nv("vlan0ports", "0 5*");
327 dirty |= check_nv("vlan1ports", "1 5");
328 break;
329 case MODEL_WL500GP:
330 dirty |= check_nv("sdram_init", "0x0009"); // 32MB; defaults: 0x000b, 0x0009
331 dirty |= check_nv("vlan1ports", "0 5"); // default: 0 5u
332 break;
333 case MODEL_WL500W:
334 /* fix WL500W mac adresses for WAN port */
335 if (nvram_match("et1macaddr", "00:90:4c:a1:00:2d"))
336 dirty |= check_nv("et1macaddr", nvram_get("et0macaddr"));
337 break;
338 case MODEL_WL500GE:
339 dirty |= check_nv("vlan1ports", "0 5"); // default: 0 5u
340 break;
341 case MODEL_WL500GPv2:
342 if (nvram_match("vlan1ports", "4 5u"))
343 dirty |= check_nv("vlan1ports", "4 5");
344 else if (nvram_match("vlan1ports", "0 5u")) // 520GU?
345 dirty |= check_nv("vlan1ports", "0 5");
346 break;
347 case MODEL_WL520GU:
348 dirty |= check_nv("vlan1ports", "0 5");
349 break;
350 case MODEL_DIR320:
351 dirty |= check_nv("vlan1hwname", "et0");
352 dirty |= check_nv("vlan1ports", "0 5");
353 break;
354 #ifdef CONFIG_BCMWL5
355 case MODEL_WNR3500L:
356 dirty |= check_nv("boardflags", "0x00000710"); // needed to enable USB
357 dirty |= check_nv("vlan1ports", "4 3 2 1 8*");
358 dirty |= check_nv("vlan2ports", "0 8");
359 dirty |= check_nv("ledbh0", "7");
360 break;
361 case MODEL_RTN10:
362 dirty |= check_nv("vlan1ports", "4 5");
363 break;
364 case MODEL_RTN12:
365 dirty |= check_nv("vlan0ports", "3 2 1 0 5*");
366 dirty |= check_nv("vlan1ports", "4 5");
367 break;
368 case MODEL_RTN16:
369 dirty |= check_nv("vlan2hwname", "et0");
370 dirty |= check_nv("vlan1ports", "4 3 2 1 8*");
371 dirty |= check_nv("vlan2ports", "0 8");
372 break;
373 case MODEL_WRT160Nv3:
374 if (nvram_match("clkdivsf", "4")) {
375 // fix lan port numbering on CSE41, CSE51
376 dirty |= check_nv("vlan1ports", "4 3 2 1 5*");
378 break;
379 #endif
381 case MODEL_WRT54G:
382 if (strncmp(nvram_safe_get("pmon_ver"), "CFE", 3) != 0) return;
384 hardware = check_hw_type();
385 if (!nvram_get("boardtype") ||
386 !nvram_get("boardnum") ||
387 !nvram_get("boardflags") ||
388 !nvram_get("clkfreq") ||
389 !nvram_get("os_flash_addr") ||
390 !nvram_get("dl_ram_addr") ||
391 !nvram_get("os_ram_addr") ||
392 !nvram_get("scratch") ||
393 !nvram_get("et0macaddr") ||
394 ((hardware != HW_BCM4704_BCM5325F) && (!nvram_get("vlan0ports") || !nvram_get("vlan0hwname")))) {
395 cprintf("Unable to find critical settings, erasing NVRAM\n");
396 mtd_erase("nvram");
397 goto REBOOT;
400 dirty |= check_nv("aa0", "3");
401 dirty |= check_nv("wl0gpio0", "136");
402 dirty |= check_nv("wl0gpio2", "0");
403 dirty |= check_nv("wl0gpio3", "0");
404 dirty |= check_nv("cctl", "0");
405 dirty |= check_nv("ccode", "0");
407 switch (hardware) {
408 case HW_BCM5325E:
409 /* Lower the DDR ram drive strength , the value will be stable for all boards
410 Latency 3 is more stable for all ddr 20050420 by honor */
411 dirty |= check_nv("sdram_init", "0x010b");
412 dirty |= check_nv("sdram_config", "0x0062");
413 if (!nvram_match("debug_clkfix", "0")) {
414 dirty |= check_nv("clkfreq", "216");
416 if (dirty) {
417 nvram_set("sdram_ncdl", "0x0");
419 dirty |= check_nv("pa0itssit", "62");
420 dirty |= check_nv("pa0b0", "0x15eb");
421 dirty |= check_nv("pa0b1", "0xfa82");
422 dirty |= check_nv("pa0b2", "0xfe66");
423 //dirty |= check_nv("pa0maxpwr", "0x4e");
424 break;
425 case HW_BCM5352E: // G v4, GS v3, v4
426 dirty |= check_nv("sdram_init", "0x010b");
427 dirty |= check_nv("sdram_config", "0x0062");
428 if (dirty) {
429 nvram_set("sdram_ncdl", "0x0");
431 dirty |= check_nv("pa0itssit", "62");
432 dirty |= check_nv("pa0b0", "0x168b");
433 dirty |= check_nv("pa0b1", "0xfabf");
434 dirty |= check_nv("pa0b2", "0xfeaf");
435 //dirty |= check_nv("pa0maxpwr", "0x4e");
436 dirty |= check_nv("vlan0ports", "3 2 1 0 5*");
437 break;
438 case HW_BCM5354G:
439 dirty |= check_nv("pa0itssit", "62");
440 dirty |= check_nv("pa0b0", "0x1326");
441 dirty |= check_nv("pa0b1", "0xFB51");
442 dirty |= check_nv("pa0b2", "0xFE87");
443 //dirty |= check_nv("pa0maxpwr", "0x4e");
444 break;
445 case HW_BCM4704_BCM5325F:
446 // nothing to do
447 break;
448 default:
449 dirty |= check_nv("pa0itssit", "62");
450 dirty |= check_nv("pa0b0", "0x170c");
451 dirty |= check_nv("pa0b1", "0xfa24");
452 dirty |= check_nv("pa0b2", "0xfe70");
453 //dirty |= check_nv("pa0maxpwr", "0x48");
454 break;
456 break;
458 } // switch (model)
460 if (dirty) {
461 nvram_commit();
462 REBOOT: // do a simple reboot
463 sync();
464 reboot(RB_AUTOBOOT);
465 exit(0);
469 static int init_nvram(void)
471 unsigned long features;
472 int model;
473 const char *mfr;
474 const char *name;
475 char s[256];
476 unsigned long bf;
477 unsigned long n;
479 model = get_model();
480 sprintf(s, "%d", model);
481 nvram_set("t_model", s);
483 mfr = "Broadcom";
484 name = NULL;
485 features = 0;
486 switch (model) {
487 case MODEL_WRT54G:
488 mfr = "Linksys";
489 name = "WRT54G/GS/GL";
490 switch (check_hw_type()) {
491 case HW_BCM4712:
492 nvram_set("gpio2", "adm_eecs");
493 nvram_set("gpio3", "adm_eesk");
494 nvram_unset("gpio4");
495 nvram_set("gpio5", "adm_eedi");
496 nvram_set("gpio6", "adm_rc");
497 break;
498 case HW_BCM4702:
499 nvram_unset("gpio2");
500 nvram_unset("gpio3");
501 nvram_unset("gpio4");
502 nvram_unset("gpio5");
503 nvram_unset("gpio6");
504 break;
505 case HW_BCM5352E:
506 nvram_set("opo", "0x0008");
507 nvram_set("ag0", "0x02");
508 // drop
509 default:
510 nvram_set("gpio2", "ses_led");
511 nvram_set("gpio3", "ses_led2");
512 nvram_set("gpio4", "ses_button");
513 features = SUP_SES | SUP_WHAM_LED;
514 break;
516 break;
517 case MODEL_WTR54GS:
518 mfr = "Linksys";
519 name = "WTR54GS";
520 if (!nvram_match("t_fix1", (char *)name)) {
521 nvram_set("vlan_enable", "1");
522 nvram_set("lan_ifnames", "vlan0 eth1");
523 nvram_set("gpio2", "ses_button");
524 nvram_set("reset_gpio", "7");
527 nvram_set("pa0itssit", "62");
528 nvram_set("pa0b0", "0x1542");
529 nvram_set("pa0b1", "0xfacb");
530 nvram_set("pa0b2", "0xfec7");
531 //nvram_set("pa0maxpwr", "0x4c");
532 features = SUP_SES;
533 break;
534 case MODEL_WRTSL54GS:
535 mfr = "Linksys";
536 name = "WRTSL54GS";
537 features = SUP_SES | SUP_WHAM_LED;
538 break;
539 case MODEL_WHRG54S:
540 mfr = "Buffalo";
541 name = "WHR-G54S";
542 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
543 break;
544 case MODEL_WHRHPG54:
545 case MODEL_WZRRSG54HP:
546 case MODEL_WZRHPG54:
547 mfr = "Buffalo";
548 features = SUP_SES | SUP_AOSS_LED | SUP_HPAMP;
549 switch (model) {
550 case MODEL_WZRRSG54HP:
551 name = "WZR-RS-G54HP";
552 break;
553 case MODEL_WZRHPG54:
554 name = "WZR-HP-G54";
555 break;
556 default:
557 name = "WHR-HP-G54";
558 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU | SUP_HPAMP;
559 break;
562 bf = strtoul(nvram_safe_get("boardflags"), NULL, 0);
563 switch (bf) {
564 case 0x0758:
565 case 0x1758:
566 case 0x2758:
567 case 0x3758:
568 if (nvram_match("wlx_hpamp", "")) {
569 if (nvram_get_int("wl_txpwr") > 10) nvram_set("wl_txpwr", "10");
570 nvram_set("wlx_hpamp", "1");
571 nvram_set("wlx_hperx", "0");
574 n = bf;
575 if (nvram_match("wlx_hpamp", "0")) {
576 n &= ~0x2000UL;
578 else {
579 n |= 0x2000UL;
581 if (nvram_match("wlx_hperx", "0")) {
582 n |= 0x1000UL;
584 else {
585 n &= ~0x1000UL;
587 if (bf != n) {
588 sprintf(s, "0x%lX", n);
589 nvram_set("boardflags", s);
591 break;
592 default:
593 syslog(LOG_WARNING, "Unexpected: boardflag=%lX", bf);
594 break;
596 break;
597 case MODEL_WBRG54:
598 mfr = "Buffalo";
599 name = "WBR-G54";
600 nvram_set("wl0gpio0", "130");
601 break;
602 case MODEL_WBR2G54:
603 mfr = "Buffalo";
604 name = "WBR2-G54";
605 features = SUP_SES | SUP_AOSS_LED;
606 break;
607 case MODEL_WHR2A54G54:
608 mfr = "Buffalo";
609 name = "WHR2-A54G54";
610 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
611 break;
612 case MODEL_WHR3AG54:
613 mfr = "Buffalo";
614 name = "WHR3-AG54";
615 features = SUP_SES | SUP_AOSS_LED;
616 break;
617 case MODEL_WZRG54:
618 mfr = "Buffalo";
619 name = "WZR-G54";
620 features = SUP_SES | SUP_AOSS_LED;
621 break;
622 case MODEL_WZRRSG54:
623 mfr = "Buffalo";
624 name = "WZR-RS-G54";
625 features = SUP_SES | SUP_AOSS_LED;
626 break;
627 case MODEL_WVRG54NF:
628 mfr = "Buffalo";
629 name = "WVR-G54-NF";
630 features = SUP_SES;
631 break;
632 case MODEL_WZRG108:
633 mfr = "Buffalo";
634 name = "WZR-G108";
635 features = SUP_SES | SUP_AOSS_LED;
636 break;
637 case MODEL_RT390W:
638 mfr = "Fuji";
639 name = "RT390W";
640 break;
641 case MODEL_WR850GV1:
642 mfr = "Motorola";
643 name = "WR850G v1";
644 features = SUP_NONVE;
645 break;
646 case MODEL_WR850GV2:
647 mfr = "Motorola";
648 name = "WR850G v2/v3";
649 features = SUP_NONVE;
650 break;
651 case MODEL_WL500GP:
652 mfr = "Asus";
653 name = "WL-500gP";
654 features = SUP_SES;
655 if (!nvram_match("t_fix1", (char *)name)) {
656 nvram_set("t_fix1", name);
657 nvram_set("lan_ifnames", "vlan0 eth1 eth2 eth3"); // set to "vlan0 eth2" by DD-WRT; default: vlan0 eth1
658 // !!TB - WLAN LED fix
659 nvram_set("wl0gpio0", "136");
661 break;
662 case MODEL_WL500W:
663 mfr = "Asus";
664 name = "WL-500W";
665 features = SUP_SES | SUP_80211N;
666 /* fix AIR LED */
667 if (!nvram_get("wl0gpio0") || nvram_match("wl0gpio0", "2"))
668 nvram_set("wl0gpio0", "0x88");
669 break;
670 case MODEL_WL500GE:
671 mfr = "Asus";
672 name = "WL-500gE";
673 // features = ?
674 break;
675 case MODEL_WX6615GT:
676 mfr = "SparkLAN";
677 name = "WX-6615GT";
678 // features = ?
679 break;
680 case MODEL_MN700:
681 mfr = "Microsoft";
682 name = "MN-700";
683 break;
684 case MODEL_WR100:
685 mfr = "Viewsonic";
686 name = "WR100";
687 break;
688 case MODEL_WLA2G54L:
689 mfr = "Buffalo";
690 name = "WLA2-G54L";
691 if (!nvram_match("t_fix1", (char *)name)) {
692 nvram_set("t_fix1", name);
693 nvram_set("lan_ifnames", "vlan0 eth1 eth2");
694 nvram_set("wl_ifname", "eth1");
695 nvram_set("wan_ifname", "none");
697 break;
698 case MODEL_TM2300:
699 mfr = "Dell";
700 name = "TrueMobile 2300";
701 break;
709 #ifndef WL_BSS_INFO_VERSION
710 #error WL_BSS_INFO_VERSION
711 #endif
712 #if WL_BSS_INFO_VERSION >= 108
714 case MODEL_WRH54G:
715 mfr = "Linksys";
716 name = "WRH54G";
718 nvram_set("opo", "12");
719 break;
721 case MODEL_WHRG125:
722 mfr = "Buffalo";
723 name = "WHR-G125";
724 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
726 nvram_set("opo", "0x0008");
727 nvram_set("ag0", "0x0C");
728 break;
729 #ifdef CONFIG_BCMWL5
730 case MODEL_RTN10:
731 mfr = "Asus";
732 name = "RT-N10";
733 features = SUP_SES | SUP_80211N;
734 if (!nvram_match("t_fix1", (char *)name)) {
735 nvram_set("lan_ifnames", "vlan0 eth1");
736 nvram_set("wan_ifnameX", "vlan1");
737 nvram_set("wl_ifname", "eth1");
738 nvram_set("t_fix1", name);
740 break;
741 case MODEL_RTN12:
742 mfr = "Asus";
743 name = "RT-N12";
744 features = SUP_SES | SUP_BRAU | SUP_80211N;
745 if (!nvram_match("t_fix1", (char *)name)) {
746 nvram_set("lan_ifnames", "vlan0 eth1");
747 nvram_set("wan_ifnameX", "vlan1");
748 nvram_set("wl_ifname", "eth1");
749 nvram_set("t_fix1", name);
751 break;
752 case MODEL_RTN16:
753 mfr = "Asus";
754 name = "RT-N16";
755 features = SUP_SES | SUP_80211N | SUP_1000ET;
756 if (!nvram_match("t_fix1", (char *)name)) {
757 nvram_set("lan_ifnames", "vlan1 eth1");
758 nvram_set("wan_ifnameX", "vlan2");
759 nvram_set("wl_ifname", "eth1");
760 nvram_set("vlan_enable", "1");
761 nvram_set("t_fix1", name);
763 break;
764 case MODEL_WNR3500L:
765 mfr = "Netgear";
766 name = "WNR3500L/U/v2";
767 features = SUP_SES | SUP_AOSS_LED | SUP_80211N | SUP_1000ET;
768 if (!nvram_match("t_fix1", (char *)name)) {
769 nvram_set("sromrev", "3");
770 nvram_set("lan_ifnames", "vlan1 eth1");
771 nvram_set("wan_ifnameX", "vlan2");
772 nvram_set("wl_ifname", "eth1");
773 nvram_set("portprio_support", "0");
774 nvram_set("t_fix1", name);
776 break;
777 case MODEL_WRT160Nv3:
778 mfr = "Linksys";
779 name = "WRT160N v3";
780 features = SUP_SES | SUP_80211N | SUP_WHAM_LED;
781 if (!nvram_match("t_fix1", (char *)name)) {
782 nvram_set("lan_ifnames", "vlan1 eth1");
783 nvram_set("wan_ifnameX", "vlan2");
784 nvram_set("wl_ifname", "eth1");
785 nvram_set("t_fix1", name);
787 break;
788 #endif // CONFIG_BCMWL5
789 case MODEL_WL500GPv2:
790 mfr = "Asus";
791 name = "WL-500gP v2";
792 features = SUP_SES;
793 if (!nvram_match("t_fix1", (char *)name)) {
794 nvram_set("t_fix1", name);
796 /* fix AIR LED */
797 if (nvram_match("wl0gpio1", "0x02"))
798 nvram_set("wl0gpio1", "0x88");
799 break;
800 case MODEL_WL520GU:
801 mfr = "Asus";
802 name = "WL-520GU";
803 features = SUP_SES;
804 if (!nvram_match("t_fix1", (char *)name)) {
805 nvram_set("t_fix1", name);
806 // !!TB - LED fix
807 nvram_set("wl0gpio0", "0");
808 nvram_set("wl0gpio1", "136");
809 nvram_set("wl0gpio2", "0");
810 nvram_set("wl0gpio3", "0");
812 break;
813 case MODEL_DIR320:
814 mfr = "D-Link";
815 name = "DIR-320";
816 features = SUP_SES;
817 if (nvram_match("wl0gpio0", "255"))
819 nvram_set("wl0gpio0", "8");
820 nvram_set("wl0gpio1", "0");
821 nvram_set("wl0gpio2", "0");
822 nvram_set("wl0gpio3", "0");
824 if (!nvram_match("t_fix1", (char *)name)) {
825 nvram_set("t_fix1", name);
826 nvram_unset( "vlan2ports" );
827 nvram_unset( "vlan2hwname" );
828 nvram_set("wandevs", "vlan1");
829 nvram_set("wan_ifname", "vlan1");
830 nvram_set("wan_ifnames", "vlan1");
831 nvram_set("wan0_ifname", "vlan1");
832 nvram_set("wan0_ifnames", "vlan1");
834 break;
835 #endif // WL_BSS_INFO_VERSION >= 108
836 #if TOMATO_N
837 case MODEL_WZRG300N:
838 mfr = "Buffalo";
839 name = "WZR-G300N";
840 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU | SUP_80211N;
841 break;
842 case MODEL_WRT300N:
843 mfr = "Linksys";
844 name = "WRT300N";
845 features = SUP_SES | SUP_80211N;
846 break;
847 #endif
850 if (name) {
851 sprintf(s, "%s %s", mfr, name);
853 else {
854 snprintf(s, sizeof(s), "%s %d/%s/%s/%s/%s", mfr, check_hw_type(),
855 nvram_safe_get("boardtype"), nvram_safe_get("boardnum"), nvram_safe_get("boardrev"), nvram_safe_get("boardflags"));
856 s[64] = 0;
858 nvram_set("t_model_name", s);
860 nvram_set("pa0maxpwr", "251"); // allow Tx power up tp 251 mW, needed for ND only
862 sprintf(s, "0x%lX", features);
863 nvram_set("t_features", s);
868 note: set wan_ifnameX if wan_ifname needs to be overriden
871 if (nvram_is_empty("wan_ifnameX")) {
872 #if 1
873 nvram_set("wan_ifnameX", ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
874 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1");
875 #else
876 p = nvram_safe_get("wan_ifname");
877 if ((*p == 0) || (nvram_match("wl_ifname", p))) {
878 p = ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
879 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1";
881 nvram_set("wan_ifnameX", p);
882 #endif
886 nvram_set("wl_hwaddr", ""); // when disabling wireless, we must get null wireless mac ??
887 //!!TB - do not force country code here to allow nvram override
888 //nvram_set("wl_country", "JP");
889 //nvram_set("wl_country_code", "JP");
890 nvram_set("wan_get_dns", "");
891 nvram_set("wan_get_domain", "");
892 nvram_set("pppoe_pid0", "");
893 nvram_set("action_service", "");
894 nvram_set("jffs2_format", "0");
895 nvram_set("rrules_radio", "-1");
896 nvram_unset("https_crt_gen");
897 if (nvram_get_int("http_id_gen") == 1) nvram_unset("http_id");
899 nvram_unset("sch_rboot_last");
900 nvram_unset("sch_rcon_last");
901 nvram_unset("sch_c1_last");
902 nvram_unset("sch_c2_last");
903 nvram_unset("sch_c3_last");
905 nvram_set("brau_state", "");
906 if ((features & SUP_BRAU) == 0) nvram_set("script_brau", "");
907 if ((features & SUP_SES) == 0) nvram_set("sesx_script", "");
909 if ((features & SUP_1000ET) == 0) nvram_set("jumbo_frame_enable", "0");
911 if (nvram_match("wl_net_mode", "disabled")) {
912 nvram_set("wl_radio", "0");
913 nvram_set("wl_net_mode", "mixed");
916 return 0;
919 /* Get the special files from nvram and copy them to disc.
920 * These were files saved with "nvram setfile2nvram <filename>".
921 * Better hope that they were saved with full pathname.
923 static void load_files_from_nvram(void)
925 char *name, *cp;
926 char buf[NVRAM_SPACE];
928 if (nvram_getall(buf, sizeof(buf)) != 0)
929 return;
931 for (name = buf; *name; name += strlen(name) + 1) {
932 if (strncmp(name, "FILE:", 5) == 0) { /* This special name marks a file to get. */
933 if ((cp = strchr(name, '=')) == NULL)
934 continue;
935 *cp = 0;
936 syslog(LOG_INFO, "Loading file '%s' from nvram", name + 5);
937 nvram_nvram2file(name, name + 5);
942 static void sysinit(void)
944 static const time_t tm = 0;
945 int hardware;
946 int i;
947 DIR *d;
948 struct dirent *de;
949 char s[256];
950 char t[256];
951 int model;
953 mount("proc", "/proc", "proc", 0, NULL);
954 mount("tmpfs", "/tmp", "tmpfs", 0, NULL);
956 #ifdef LINUX26
957 mount("devfs", "/dev", "tmpfs", MS_MGC_VAL | MS_NOATIME, NULL);
958 mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3));
959 mknod("/dev/console", S_IFCHR | 0600, makedev(5, 1));
960 mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL);
961 mkdir("/dev/shm", 0777);
962 mkdir("/dev/pts", 0777);
963 mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, NULL);
964 #endif
966 if (console_init()) noconsole = 1;
968 stime(&tm);
970 static const char *mkd[] = {
971 "/tmp/etc", "/tmp/var", "/tmp/home", "/tmp/mnt",
972 "/tmp/share", // !!TB
973 "/var/log", "/var/run", "/var/tmp", "/var/lib", "/var/lib/misc",
974 "/var/spool", "/var/spool/cron", "/var/spool/cron/crontabs",
975 "/tmp/var/wwwext", "/tmp/var/wwwext/cgi-bin", // !!TB - CGI support
976 NULL
978 umask(0);
979 for (i = 0; mkd[i]; ++i) {
980 mkdir(mkd[i], 0755);
982 mkdir("/var/lock", 0777);
983 mkdir("/var/tmp/dhcp", 0777);
984 mkdir("/home/root", 0700);
985 chmod("/tmp", 0777);
986 f_write("/etc/hosts", NULL, 0, 0, 0644); // blank
987 f_write("/etc/fstab", NULL, 0, 0, 0644); // !!TB - blank
988 simple_unlock("cron");
989 simple_unlock("firewall");
990 simple_unlock("restrictions");
991 umask(022);
993 if ((d = opendir("/rom/etc")) != NULL) {
994 while ((de = readdir(d)) != NULL) {
995 if (de->d_name[0] == '.') continue;
996 snprintf(s, sizeof(s), "%s/%s", "/rom/etc", de->d_name);
997 snprintf(t, sizeof(t), "%s/%s", "/etc", de->d_name);
998 symlink(s, t);
1000 closedir(d);
1002 symlink("/proc/mounts", "/etc/mtab");
1004 #ifdef TCONFIG_SAMBASRV
1005 if ((d = opendir("/usr/codepages")) != NULL) {
1006 while ((de = readdir(d)) != NULL) {
1007 if (de->d_name[0] == '.') continue;
1008 snprintf(s, sizeof(s), "/usr/codepages/%s", de->d_name);
1009 snprintf(t, sizeof(t), "/usr/share/%s", de->d_name);
1010 symlink(s, t);
1012 closedir(d);
1014 #endif
1016 #ifdef LINUX26
1017 eval("hotplug2", "--coldplug");
1018 start_hotplug2();
1019 #endif
1021 set_action(ACT_IDLE);
1023 for (i = 0; defenv[i]; ++i) {
1024 putenv(defenv[i]);
1027 if (!noconsole) {
1028 printf("\n\nHit ENTER for console...\n\n");
1029 run_shell(1, 0);
1032 check_bootnv();
1034 for (i = 0; i < sizeof(fatalsigs) / sizeof(fatalsigs[0]); i++) {
1035 signal(fatalsigs[i], handle_fatalsigs);
1037 for (i = 0; i < sizeof(initsigs) / sizeof(initsigs[0]); i++) {
1038 signal(initsigs[i], handle_initsigs);
1040 signal(SIGCHLD, handle_reap);
1042 switch (model = get_model()) {
1043 case MODEL_WR850GV1:
1044 case MODEL_WR850GV2:
1045 // need to cleanup some variables...
1046 if ((nvram_get("t_model") == NULL) && (nvram_get("MyFirmwareVersion") != NULL)) {
1047 nvram_unset("MyFirmwareVersion");
1048 nvram_set("restore_defaults", "1");
1050 break;
1053 hardware = check_hw_type();
1054 #if WL_BSS_INFO_VERSION >= 108
1055 modprobe("et");
1056 #else
1057 if ((hardware == HW_BCM4702) && (model != MODEL_WR850GV1)) {
1058 modprobe("4702et");
1059 modprobe("diag");
1061 else {
1062 modprobe("et");
1064 #endif
1066 #ifdef CONFIG_BCMWL5
1067 modprobe("emf");
1068 modprobe("igs");
1069 #endif
1070 modprobe("wl");
1071 modprobe("tomato_ct");
1073 config_loopback();
1075 system("nvram defaults --initcheck");
1076 init_nvram();
1078 // set the packet size
1079 if (nvram_get_int("jumbo_frame_enable")) {
1080 // only set the size here - 'enable' flag is set by the driver
1081 // eval("et", "robowr", "0x40", "0x01", "0x1F"); // (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)
1082 eval("et", "robowr", "0x40", "0x05", nvram_safe_get("jumbo_frame_size"));
1085 klogctl(8, NULL, nvram_get_int("console_loglevel"));
1087 setup_conntrack();
1088 set_host_domain_name();
1090 start_jffs2();
1092 set_tz();
1094 eval("buttons");
1096 i = nvram_get_int("sesx_led");
1097 led(LED_AMBER, (i & 1) != 0);
1098 led(LED_WHITE, (i & 2) != 0);
1099 led(LED_AOSS, (i & 4) != 0);
1100 led(LED_BRIDGE, (i & 8) != 0);
1101 led(LED_DIAG, 1);
1104 int init_main(int argc, char *argv[])
1106 pid_t shell_pid = 0;
1108 sysinit();
1110 state = START;
1111 signaled = -1;
1113 #if defined(DEBUG_NOISY)
1114 nvram_set("debug_logeval", "1");
1115 nvram_set("debug_cprintf", "1");
1116 nvram_set("debug_cprintf_file", "1");
1117 nvram_set("debug_ddns", "1");
1118 #endif
1120 for (;;) {
1121 // TRACE_PT("main loop state=%d\n", state);
1123 switch (state) {
1124 case USER1:
1125 exec_service();
1126 state = IDLE;
1127 break;
1128 case RESTART:
1129 case STOP:
1130 case HALT:
1131 case REBOOT:
1132 led(LED_DIAG, 1);
1133 unlink("/var/notice/sysup");
1135 run_nvscript("script_shut", NULL, 10);
1137 stop_services();
1138 stop_wan();
1139 stop_lan();
1140 stop_vlan();
1141 stop_syslog();
1143 // !!TB - USB Support
1144 remove_storage_main((state == REBOOT) || (state == HALT));
1145 stop_usb();
1147 if ((state == REBOOT) || (state == HALT)) {
1148 shutdn(state == REBOOT);
1149 exit(0);
1151 if (state == STOP) {
1152 state = IDLE;
1153 break;
1156 // RESTART falls through
1158 case START:
1159 SET_LED(RELEASE_WAN_CONTROL);
1160 start_syslog();
1162 load_files_from_nvram();
1164 int fd = -1;
1165 fd = file_lock("usb"); // hold off automount processing
1166 start_usb();
1168 run_nvscript("script_init", NULL, 2);
1170 file_unlock(fd); // allow to process usb hotplug events
1171 #ifdef TCONFIG_USB
1173 * On RESTART some partitions can stay mounted if they are busy at the moment.
1174 * In that case USB drivers won't unload, and hotplug won't kick off again to
1175 * remount those drives that actually got unmounted. Make sure to remount ALL
1176 * partitions here by simulating hotplug event.
1178 if (state == RESTART) add_remove_usbhost("-1", 1);
1179 #endif
1181 start_vlan();
1182 start_lan();
1183 start_wan(BOOT);
1184 start_services();
1185 start_wl();
1187 #ifdef CONFIG_BCMWL5
1188 if (nvram_match("wds_enable", "1")) {
1189 /* Restart NAS one more time - for some reason without
1190 * this the new driver doesn't always bring WDS up.
1192 stop_nas();
1193 start_nas();
1195 #endif
1197 syslog(LOG_INFO, "Tomato %s", tomato_version);
1198 syslog(LOG_INFO, "%s", nvram_safe_get("t_model_name"));
1200 led(LED_DIAG, 0);
1201 notice_set("sysup", "");
1203 state = IDLE;
1205 // fall through
1207 case IDLE:
1208 while (signaled == -1) {
1209 check_services();
1210 if ((!noconsole) && ((!shell_pid) || (kill(shell_pid, 0) != 0))) {
1211 shell_pid = run_shell(0, 1);
1213 else {
1214 pause();
1217 state = signaled;
1218 signaled = -1;
1219 break;
1224 int reboothalt_main(int argc, char *argv[])
1226 int reboot = (strstr(argv[0], "reboot") != NULL);
1227 puts(reboot ? "Rebooting..." : "Shutting down...");
1228 fflush(stdout);
1229 sleep(1);
1230 kill(1, reboot ? SIGTERM : SIGQUIT);
1232 /* In the case we're hung, we'll get stuck and never actually reboot.
1233 * The only way out is to pull power.
1234 * So after 10 seconds, forcibly crash & restart.
1236 if (fork() == 0) {
1237 f_write("/proc/sysrq-trigger", "s", 1, 0 , 0); /* sync disks */
1238 sleep(10);
1239 puts("Still running... Doing machine reset.");
1240 fflush(stdout);
1241 f_write("/proc/sysrq-trigger", "s", 1, 0 , 0); /* sync disks */
1242 sleep(1);
1243 f_write("/proc/sysrq-trigger", "b", 1, 0 , 0); /* machine reset */
1246 return 0;