DIR-320 ID (buttons and leds)
[tomato.git] / release / src / router / rc / init.c
blobab8965688938c32ba256de2c1e3210ad41473156
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 #include <wlutils.h>
26 #include <bcmdevs.h>
28 #define SHELL "/bin/sh"
31 enum {
32 RESTART,
33 STOP,
34 START,
35 USER1,
36 IDLE,
37 REBOOT,
38 HALT,
39 INIT
42 static int fatalsigs[] = {
43 SIGILL,
44 SIGABRT,
45 SIGFPE,
46 SIGPIPE,
47 SIGBUS,
48 SIGSYS,
49 SIGTRAP,
50 SIGPWR
53 static int initsigs[] = {
54 SIGHUP,
55 SIGUSR1,
56 SIGUSR2,
57 SIGINT,
58 SIGQUIT,
59 SIGTERM
62 static char *defenv[] = {
63 "TERM=vt100",
64 "HOME=/",
65 "PATH=/usr/bin:/bin:/usr/sbin:/sbin",
66 "SHELL=" SHELL,
67 "USER=root",
68 NULL
71 static int noconsole = 0;
72 static volatile int state = INIT;
73 static volatile int signaled = -1;
76 /* Set terminal settings to reasonable defaults */
77 static void set_term(int fd)
79 struct termios tty;
81 tcgetattr(fd, &tty);
83 /* set control chars */
84 tty.c_cc[VINTR] = 3; /* C-c */
85 tty.c_cc[VQUIT] = 28; /* C-\ */
86 tty.c_cc[VERASE] = 127; /* C-? */
87 tty.c_cc[VKILL] = 21; /* C-u */
88 tty.c_cc[VEOF] = 4; /* C-d */
89 tty.c_cc[VSTART] = 17; /* C-q */
90 tty.c_cc[VSTOP] = 19; /* C-s */
91 tty.c_cc[VSUSP] = 26; /* C-z */
93 /* use line dicipline 0 */
94 tty.c_line = 0;
96 /* Make it be sane */
97 tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
98 tty.c_cflag |= CREAD|HUPCL|CLOCAL;
101 /* input modes */
102 tty.c_iflag = ICRNL | IXON | IXOFF;
104 /* output modes */
105 tty.c_oflag = OPOST | ONLCR;
107 /* local modes */
108 tty.c_lflag =
109 ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
111 tcsetattr(fd, TCSANOW, &tty);
114 static int console_init(void)
116 int fd;
118 /* Clean up */
119 ioctl(0, TIOCNOTTY, 0);
120 close(0);
121 close(1);
122 close(2);
123 setsid();
125 /* Reopen console */
126 if ((fd = open(_PATH_CONSOLE, O_RDWR)) < 0) {
127 /* Avoid debug messages is redirected to socket packet if no exist a UART chip, added by honor, 2003-12-04 */
128 open("/dev/null", O_RDONLY);
129 open("/dev/null", O_WRONLY);
130 open("/dev/null", O_WRONLY);
131 perror(_PATH_CONSOLE);
132 return errno;
134 dup2(fd, 0);
135 dup2(fd, 1);
136 dup2(fd, 2);
138 ioctl(0, TIOCSCTTY, 1);
139 tcsetpgrp(0, getpgrp());
140 set_term(0);
142 return 0;
146 * Waits for a file descriptor to change status or unblocked signal
147 * @param fd file descriptor
148 * @param timeout seconds to wait before timing out or 0 for no timeout
149 * @return 1 if descriptor changed status or 0 if timed out or -1 on error
151 static int waitfor(int fd, int timeout)
153 fd_set rfds;
154 struct timeval tv = { timeout, 0 };
156 FD_ZERO(&rfds);
157 FD_SET(fd, &rfds);
158 return select(fd + 1, &rfds, NULL, NULL, (timeout > 0) ? &tv : NULL);
161 static pid_t run_shell(int timeout, int nowait)
163 pid_t pid;
164 int sig;
166 /* Wait for user input */
167 if (waitfor(STDIN_FILENO, timeout) <= 0) return 0;
169 switch (pid = fork()) {
170 case -1:
171 perror("fork");
172 return 0;
173 case 0:
174 /* Reset signal handlers set for parent process */
175 for (sig = 0; sig < (_NSIG-1); sig++)
176 signal(sig, SIG_DFL);
178 /* Reopen console */
179 console_init();
180 printf("\n\nTomato %s\n\n", tomato_version);
182 /* Now run it. The new program will take over this PID,
183 * so nothing further in init.c should be run. */
184 execve(SHELL, (char *[]) { SHELL, NULL }, defenv);
186 /* We're still here? Some error happened. */
187 perror(SHELL);
188 exit(errno);
189 default:
190 if (nowait) {
191 return pid;
193 else {
194 waitpid(pid, NULL, 0);
195 return 0;
200 static void shutdn(int rb)
202 int i;
203 int act;
204 sigset_t ss;
206 _dprintf("shutdn rb=%d\n", rb);
208 sigemptyset(&ss);
209 for (i = 0; i < sizeof(fatalsigs) / sizeof(fatalsigs[0]); i++)
210 sigaddset(&ss, fatalsigs[i]);
211 for (i = 0; i < sizeof(initsigs) / sizeof(initsigs[0]); i++)
212 sigaddset(&ss, initsigs[i]);
213 sigaddset(&ss, SIGCHLD);
214 sigprocmask(SIG_BLOCK, &ss, NULL);
216 for (i = 30; i > 0; --i) {
217 if (((act = check_action()) == ACT_IDLE) || (act == ACT_REBOOT)) break;
218 cprintf("Busy with %d. Waiting before shutdown... %d\n", act, i);
219 sleep(1);
221 set_action(ACT_REBOOT);
223 cprintf("TERM\n");
224 kill(-1, SIGTERM);
225 sleep(2);
226 sync();
228 cprintf("KILL\n");
229 kill(-1, SIGKILL);
230 sleep(1);
231 sync();
233 umount("/jffs"); // may hang if not
234 sleep(1);
236 if (rb != -1) {
237 led(LED_WLAN, 0);
238 if (rb == 0) {
239 for (i = 4; i > 0; --i) {
240 led(LED_DMZ, 1);
241 led(LED_WHITE, 1);
242 usleep(250000);
243 led(LED_DMZ, 0);
244 led(LED_WHITE, 0);
245 usleep(250000);
250 reboot(rb ? RB_AUTOBOOT : RB_HALT_SYSTEM);
252 do {
253 sleep(1);
254 } while (1);
257 static void handle_fatalsigs(int sig)
259 _dprintf("fatal sig=%d\n", sig);
260 shutdn(-1);
263 void handle_reap(int sig)
265 while (waitpid(-1, NULL, WNOHANG) > 0) {
270 static void handle_initsigs(int sig)
272 // TRACE_PT("sig=%d state=%d, signaled=%d\n", sig, state, signaled);
274 switch (sig) {
275 case SIGHUP:
276 signaled = RESTART;
277 break;
278 case SIGUSR1:
279 signaled = USER1;
280 break;
281 case SIGUSR2:
282 signaled = START;
283 break;
284 case SIGINT:
285 signaled = STOP;
286 break;
287 case SIGTERM:
288 signaled = REBOOT;
289 break;
290 case SIGQUIT:
291 signaled = HALT;
292 break;
296 static int check_nv(const char *name, const char *value)
298 const char *p;
299 if (!nvram_match("manual_boot_nv", "1")) {
300 if (((p = nvram_get(name)) == NULL) || (strcmp(p, value) != 0)) {
301 // cprintf("Error: Critical variable %s is invalid. Resetting.\n", name);
302 nvram_set(name, value);
303 return 1;
306 return 0;
309 static void check_bootnv(void)
311 int dirty;
312 int hardware;
314 if (get_model() != MODEL_WRT54G) return;
315 if (strncmp(nvram_safe_get("pmon_ver"), "CFE", 3) != 0) return;
317 hardware = check_hw_type();
318 if (!nvram_get("boardtype") ||
319 !nvram_get("boardnum") ||
320 !nvram_get("boardflags") ||
321 !nvram_get("clkfreq") ||
322 !nvram_get("os_flash_addr") ||
323 !nvram_get("dl_ram_addr") ||
324 !nvram_get("os_ram_addr") ||
325 !nvram_get("scratch") ||
326 !nvram_get("et0macaddr") ||
327 ((hardware != HW_BCM4704_BCM5325F) && (!nvram_get("vlan0ports") || !nvram_get("vlan0hwname")))) {
328 cprintf("Unable to find critical settings, erasing NVRAM\n");
329 mtd_erase("nvram");
330 goto REBOOT;
333 dirty = 0;
335 switch (hardware) {
336 case HW_BCM5325E:
337 /* Lower the DDR ram drive strength , the value will be stable for all boards
338 Latency 3 is more stable for all ddr 20050420 by honor */
339 dirty |= check_nv("sdram_init", "0x010b");
340 dirty |= check_nv("sdram_config", "0x0062");
341 if (!nvram_match("debug_clkfix", "0")) {
342 dirty |= check_nv("clkfreq", "216");
344 if (dirty) {
345 nvram_set("sdram_ncdl", "0x0");
347 dirty |= check_nv("pa0itssit", "62");
348 dirty |= check_nv("pa0b0", "0x15eb");
349 dirty |= check_nv("pa0b1", "0xfa82");
350 dirty |= check_nv("pa0b2", "0xfe66");
351 //dirty |= check_nv("pa0maxpwr", "0x4e");
352 break;
353 case HW_BCM5352E: // G v4, GS v3, v4
354 dirty |= check_nv("sdram_init", "0x010b");
355 dirty |= check_nv("sdram_config", "0x0062");
356 if (dirty) {
357 nvram_set("sdram_ncdl", "0x0");
359 dirty |= check_nv("pa0itssit", "62");
360 dirty |= check_nv("pa0b0", "0x168b");
361 dirty |= check_nv("pa0b1", "0xfabf");
362 dirty |= check_nv("pa0b2", "0xfeaf");
363 //dirty |= check_nv("pa0maxpwr", "0x4e");
364 dirty |= check_nv("vlan0ports", "3 2 1 0 5*");
365 break;
366 case HW_BCM5354G:
367 dirty |= check_nv("pa0itssit", "62");
368 dirty |= check_nv("pa0b0", "0x1326");
369 dirty |= check_nv("pa0b1", "0xFB51");
370 dirty |= check_nv("pa0b2", "0xFE87");
371 //dirty |= check_nv("pa0maxpwr", "0x4e");
372 break;
373 case HW_BCM4704_BCM5325F:
374 // nothing to do
375 break;
376 default:
377 dirty |= check_nv("pa0itssit", "62");
378 dirty |= check_nv("pa0b0", "0x170c");
379 dirty |= check_nv("pa0b1", "0xfa24");
380 dirty |= check_nv("pa0b2", "0xfe70");
381 //dirty |= check_nv("pa0maxpwr", "0x48");
382 break;
385 if (dirty) {
386 nvram_commit();
387 REBOOT: // do a simple reboot
388 sync();
389 reboot(RB_AUTOBOOT);
390 exit(0);
394 static int init_nvram(void)
396 unsigned long features;
397 int model;
398 const char *mfr;
399 const char *name;
400 char s[256];
401 unsigned long bf;
402 unsigned long n;
404 model = get_model();
405 sprintf(s, "%d", model);
406 nvram_set("t_model", s);
408 mfr = "Broadcom";
409 name = NULL;
410 features = 0;
411 switch (model) {
412 case MODEL_WRT54G:
413 mfr = "Linksys";
414 name = "WRT54G/GS/GL";
415 switch (check_hw_type()) {
416 case HW_BCM4712:
417 nvram_set("gpio2", "adm_eecs");
418 nvram_set("gpio3", "adm_eesk");
419 nvram_unset("gpio4");
420 nvram_set("gpio5", "adm_eedi");
421 nvram_set("gpio6", "adm_rc");
422 break;
423 case HW_BCM4702:
424 nvram_unset("gpio2");
425 nvram_unset("gpio3");
426 nvram_unset("gpio4");
427 nvram_unset("gpio5");
428 nvram_unset("gpio6");
429 break;
430 case HW_BCM5352E:
431 nvram_set("opo", "0x0008");
432 nvram_set("ag0", "0x02");
433 // drop
434 default:
435 nvram_set("gpio2", "ses_led");
436 nvram_set("gpio3", "ses_led2");
437 nvram_set("gpio4", "ses_button");
438 features = SUP_SES | SUP_WHAM_LED;
439 break;
441 break;
442 case MODEL_WTR54GS:
443 mfr = "Linksys";
444 name = "WTR54GS";
445 if (!nvram_match("t_fix1", (char *)name)) {
446 nvram_set ("vlan0hwname", "et0");
447 nvram_set ("vlan1hwname", "et0");
448 nvram_set("vlan0ports", "0 5*");
449 nvram_set("vlan1ports", "1 5");
450 nvram_set("vlan_enable", "1");
451 nvram_set("lan_ifnames", "vlan0 eth1");
452 nvram_set("gpio2", "ses_button");
453 nvram_set("reset_gpio", "7");
456 nvram_set("pa0itssit", "62");
457 nvram_set("pa0b0", "0x1542");
458 nvram_set("pa0b1", "0xfacb");
459 nvram_set("pa0b2", "0xfec7");
460 //nvram_set("pa0maxpwr", "0x4c");
461 features = SUP_SES;
462 break;
463 case MODEL_WRTSL54GS:
464 mfr = "Linksys";
465 name = "WRTSL54GS";
466 features = SUP_SES | SUP_WHAM_LED;
467 break;
468 case MODEL_WHRG54S:
469 mfr = "Buffalo";
470 name = "WHR-G54S";
471 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
472 break;
473 case MODEL_WHRHPG54:
474 case MODEL_WZRRSG54HP:
475 case MODEL_WZRHPG54:
476 mfr = "Buffalo";
477 features = SUP_SES | SUP_AOSS_LED | SUP_HPAMP;
478 switch (model) {
479 case MODEL_WZRRSG54HP:
480 name = "WZR-RS-G54HP";
481 break;
482 case MODEL_WZRHPG54:
483 name = "WZR-HP-G54";
484 break;
485 default:
486 name = "WHR-HP-G54";
487 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU | SUP_HPAMP;
488 break;
491 bf = strtoul(nvram_safe_get("boardflags"), NULL, 0);
492 switch (bf) {
493 case 0x0758:
494 case 0x1758:
495 case 0x2758:
496 case 0x3758:
497 if (nvram_match("wlx_hpamp", "")) {
498 if (nvram_get_int("wl_txpwr") > 10) nvram_set("wl_txpwr", "10");
499 nvram_set("wlx_hpamp", "1");
500 nvram_set("wlx_hperx", "0");
503 n = bf;
504 if (nvram_match("wlx_hpamp", "0")) {
505 n &= ~0x2000UL;
507 else {
508 n |= 0x2000UL;
510 if (nvram_match("wlx_hperx", "0")) {
511 n |= 0x1000UL;
513 else {
514 n &= ~0x1000UL;
516 if (bf != n) {
517 sprintf(s, "0x%lX", n);
518 nvram_set("boardflags", s);
520 break;
521 default:
522 syslog(LOG_WARNING, "Unexpected: boardflag=%lX", bf);
523 break;
525 break;
526 case MODEL_WBRG54:
527 mfr = "Buffalo";
528 name = "WBR-G54";
529 nvram_set("wl0gpio0", "130");
530 break;
531 case MODEL_WBR2G54:
532 mfr = "Buffalo";
533 name = "WBR2-G54";
534 features = SUP_SES | SUP_AOSS_LED;
535 break;
536 case MODEL_WHR2A54G54:
537 mfr = "Buffalo";
538 name = "WHR2-A54G54";
539 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
540 break;
541 case MODEL_WHR3AG54:
542 mfr = "Buffalo";
543 name = "WHR3-AG54";
544 features = SUP_SES | SUP_AOSS_LED;
545 break;
546 case MODEL_WZRG54:
547 mfr = "Buffalo";
548 name = "WZR-G54";
549 features = SUP_SES | SUP_AOSS_LED;
550 break;
551 case MODEL_WZRRSG54:
552 mfr = "Buffalo";
553 name = "WZR-RS-G54";
554 features = SUP_SES | SUP_AOSS_LED;
555 break;
556 case MODEL_WVRG54NF:
557 mfr = "Buffalo";
558 name = "WVR-G54-NF";
559 features = SUP_SES;
560 break;
561 case MODEL_WZRG108:
562 mfr = "Buffalo";
563 name = "WZR-G108";
564 features = SUP_SES | SUP_AOSS_LED;
565 break;
566 case MODEL_RT390W:
567 mfr = "Fuji";
568 name = "RT390W";
569 break;
570 case MODEL_WR850GV1:
571 mfr = "Motorola";
572 name = "WR850G v1";
573 features = SUP_NONVE;
574 break;
575 case MODEL_WR850GV2:
576 mfr = "Motorola";
577 name = "WR850G v2/v3";
578 features = SUP_NONVE;
579 break;
580 case MODEL_WL500GP:
581 mfr = "Asus";
582 name = "WL-500gP";
583 features = SUP_SES;
584 if (!nvram_match("t_fix1", (char *)name)) {
585 nvram_set("t_fix1", name);
586 nvram_set("sdram_init", "0x0009"); // 32MB; defaults: 0x000b, 0x0009
587 nvram_set("vlan1ports", "0 5"); // default: 0 5u
588 nvram_set("lan_ifnames", "vlan0 eth1 eth2 eth3"); // set to "vlan0 eth2" by DD-WRT; default: vlan0 eth1
589 // !!TB - WLAN LED fix
590 nvram_set("wl0gpio0", "136");
592 break;
593 case MODEL_WL500W:
594 mfr = "Asus";
595 name = "WL-500W";
596 features = SUP_SES | SUP_80211N;
597 /* fix WL500W mac adresses for WAN port */
598 if (nvram_match("et1macaddr", "00:90:4c:a1:00:2d"))
599 nvram_set("et1macaddr", nvram_get("et0macaddr"));
600 /* fix AIR LED */
601 if (!nvram_get("wl0gpio0") || nvram_match("wl0gpio0", "2"))
602 nvram_set("wl0gpio0", "0x88");
603 break;
604 case MODEL_WL500GE:
605 mfr = "Asus";
606 name = "WL-500gE";
607 // features = ?
608 if (!nvram_match("t_fix1", (char *)name)) {
609 nvram_set("t_fix1", name);
610 nvram_set("vlan1ports", "0 5"); // default: 0 5u
612 break;
613 case MODEL_WX6615GT:
614 mfr = "SparkLAN";
615 name = "WX-6615GT";
616 // features = ?
617 break;
618 case MODEL_MN700:
619 mfr = "Microsoft";
620 name = "MN-700";
621 break;
622 case MODEL_WR100:
623 mfr = "Viewsonic";
624 name = "WR100";
625 break;
626 case MODEL_WLA2G54L:
627 mfr = "Buffalo";
628 name = "WLA2-G54L";
629 if (!nvram_match("t_fix1", (char *)name)) {
630 nvram_set("t_fix1", name);
631 nvram_set("lan_ifnames", "vlan0 eth1 eth2");
632 nvram_set("wl_ifname", "eth1");
633 nvram_set("wan_ifname", "none");
635 break;
636 case MODEL_TM2300:
637 mfr = "Dell";
638 name = "TrueMobile 2300";
639 break;
647 #ifndef WL_BSS_INFO_VERSION
648 #error WL_BSS_INFO_VERSION
649 #endif
650 #if WL_BSS_INFO_VERSION >= 108
652 case MODEL_WRH54G:
653 mfr = "Linksys";
654 name = "WRH54G";
656 nvram_set("opo", "12");
657 break;
659 case MODEL_WHRG125:
660 mfr = "Buffalo";
661 name = "WHR-G125";
662 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU;
664 nvram_set("opo", "0x0008");
665 nvram_set("ag0", "0x0C");
666 break;
667 case MODEL_RTN10:
668 mfr = "Asus";
669 name = "RT-N10";
670 features = SUP_SES | SUP_80211N;
671 if (!nvram_match("t_fix1", (char *)name)) {
672 nvram_set("lan_ifnames", "vlan0 eth1");
673 nvram_set("wan_ifnameX", "vlan1");
674 nvram_set("wl_ifname", "eth1");
675 nvram_set("vlan1ports", "4 5");
676 nvram_set("t_fix1", name);
678 break;
679 case MODEL_RTN12:
680 mfr = "Asus";
681 name = "RT-N12";
682 features = SUP_SES | SUP_80211N;
683 if (!nvram_match("t_fix1", (char *)name)) {
684 nvram_set("lan_ifnames", "vlan0 eth1");
685 nvram_set("wan_ifnameX", "vlan1");
686 nvram_set("wl_ifname", "eth1");
687 nvram_set("vlan0ports", "3 2 1 0 5*");
688 nvram_set("vlan1ports", "4 5");
689 nvram_set("t_fix1", name);
691 break;
692 case MODEL_RTN16:
693 mfr = "Asus";
694 name = "RT-N16";
695 features = SUP_SES | SUP_80211N;
696 if (!nvram_match("t_fix1", (char *)name)) {
697 nvram_set("lan_ifnames", "vlan1 eth1");
698 nvram_set("wan_ifnameX", "vlan2");
699 nvram_set("wl_ifname", "eth1");
700 nvram_set("vlan2hwname", "et0");
701 nvram_set("vlan_enable", "1");
702 nvram_set("vlan1ports", "4 3 2 1 8*");
703 nvram_set("vlan2ports", "0 8");
704 nvram_set("t_fix1", name);
706 break;
707 case MODEL_WL500GPv2:
708 mfr = "Asus";
709 name = "WL-500gP v2";
710 // features = ?;
711 if (!nvram_match("t_fix1", (char *)name)) {
712 if (nvram_match("vlan1ports", "4 5u")) {
713 nvram_set("vlan1ports", "4 5");
715 else if (nvram_match("vlan1ports", "0 5u")) { // 520GU?
716 nvram_set("vlan1ports", "0 5");
719 break;
720 case MODEL_WL520GU:
721 mfr = "Asus";
722 name = "WL-520GU";
723 features = SUP_SES;
724 if (!nvram_match("t_fix1", (char *)name)) {
725 nvram_set("t_fix1", name);
726 nvram_set("vlan1ports", "0 5");
727 // !!TB - LED fix
728 nvram_set("wl0gpio0", "0");
729 nvram_set("wl0gpio1", "136");
730 nvram_set("wl0gpio2", "0");
731 nvram_set("wl0gpio3", "0");
733 break;
734 case MODEL_DIR320:
735 mfr = "D-Link";
736 name = "DIR-320";
737 features = SUP_SES;
738 if (nvram_match("wl0gpio0", "255"))
740 nvram_set("wl0gpio0", "8");
741 nvram_set("wl0gpio1", "0");
742 nvram_set("wl0gpio2", "0");
743 nvram_set("wl0gpio3", "0");
745 if (!nvram_match("t_fix1", (char *)name)) {
746 nvram_set("t_fix1", name);
747 nvram_unset( "vlan2ports" );
748 nvram_unset( "vlan2hwname" );
749 nvram_set("vlan1hwname", "et0");
750 nvram_set("vlan1ports", "0 5");
751 nvram_set("wandevs", "vlan1");
752 nvram_set("wan_ifname", "vlan1");
753 nvram_set("wan_ifnames", "vlan1");
754 nvram_set("wan0_ifname", "vlan1");
755 nvram_set("wan0_ifnames", "vlan1");
757 break;
758 #endif
759 #if TOMATO_N
760 case MODEL_WZRG300N:
761 mfr = "Buffalo";
762 name = "WZR-G300N";
763 features = SUP_SES | SUP_AOSS_LED | SUP_BRAU | SUP_80211N;
764 break;
765 case MODEL_WRT300N:
766 mfr = "Linksys";
767 name = "WRT300N";
768 features = SUP_SES | SUP_80211N;
769 break;
770 #endif
773 if (name) {
774 sprintf(s, "%s %s", mfr, name);
776 else {
777 snprintf(s, sizeof(s), "%s %d/%s/%s/%s/%s", mfr, check_hw_type(),
778 nvram_safe_get("boardtype"), nvram_safe_get("boardnum"), nvram_safe_get("boardrev"), nvram_safe_get("boardflags"));
779 s[64] = 0;
781 nvram_set("t_model_name", s);
783 nvram_set("pa0maxpwr", "251"); // allow Tx power up tp 251 mW, needed for ND only
785 sprintf(s, "0x%lX", features);
786 nvram_set("t_features", s);
791 note: set wan_ifnameX if wan_ifname needs to be overriden
794 if (nvram_is_empty("wan_ifnameX")) {
795 #if 1
796 nvram_set("wan_ifnameX", ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
797 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1");
798 #else
799 p = nvram_safe_get("wan_ifname");
800 if ((*p == 0) || (nvram_match("wl_ifname", p))) {
801 p = ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
802 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1";
804 nvram_set("wan_ifnameX", p);
805 #endif
809 nvram_set("wl_hwaddr", ""); // when disabling wireless, we must get null wireless mac ??
810 nvram_set("wl_country", "JP");
811 nvram_set("wl_country_code", "JP");
812 nvram_set("wan_get_dns", "");
813 nvram_set("wan_get_domain", "");
814 nvram_set("pppoe_pid0", "");
815 nvram_set("action_service", "");
816 nvram_set("jffs2_format", "0");
817 nvram_set("rrules_radio", "-1");
818 nvram_unset("https_crt_gen");
819 if (nvram_get_int("http_id_gen") == 1) nvram_unset("http_id");
821 nvram_unset("sch_rboot_last");
822 nvram_unset("sch_rcon_last");
823 nvram_unset("sch_c1_last");
824 nvram_unset("sch_c2_last");
825 nvram_unset("sch_c3_last");
827 nvram_set("brau_state", "");
828 if ((features & SUP_BRAU) == 0) nvram_set("script_brau", "");
829 if ((features & SUP_SES) == 0) nvram_set("sesx_script", "");
831 if (nvram_match("wl_net_mode", "disabled")) {
832 nvram_set("wl_radio", "0");
833 nvram_set("wl_net_mode", "mixed");
836 return 0;
839 static void sysinit(void)
841 static const time_t tm = 0;
842 int hardware;
843 int i;
844 DIR *d;
845 struct dirent *de;
846 char s[256];
847 char t[256];
848 int model;
850 mount("", "/proc", "proc", 0, NULL);
851 mount("", "/tmp", "ramfs", 0, NULL);
853 if (console_init()) noconsole = 1;
855 stime(&tm);
857 static const char *mkd[] = {
858 "/tmp/etc", "/tmp/var", "/tmp/home", "/tmp/mnt",
859 "/var/log", "/var/run", "/var/tmp", "/var/lib", "/var/lib/misc",
860 "/var/spool", "/var/spool/cron", "/var/spool/cron/crontabs", NULL
862 umask(0);
863 for (i = 0; mkd[i]; ++i) {
864 mkdir(mkd[i], 0755);
866 mkdir("/var/lock", 0777);
867 mkdir("/var/tmp/dhcp", 0777);
868 mkdir("/home/root", 0700);
869 chmod("/tmp", 0777);
870 f_write("/etc/hosts", NULL, 0, 0, 0644); // blank
871 simple_unlock("cron");
872 simple_unlock("firewall");
873 simple_unlock("restrictions");
874 umask(022);
876 if ((d = opendir("/rom/etc")) != NULL) {
877 while ((de = readdir(d)) != NULL) {
878 if (de->d_name[0] == '.') continue;
879 snprintf(s, sizeof(s), "%s/%s", "/rom/etc", de->d_name);
880 snprintf(t, sizeof(t), "%s/%s", "/etc", de->d_name);
881 symlink(s, t);
883 closedir(d);
885 symlink("/proc/mounts", "/etc/mtab");
887 set_action(ACT_IDLE);
889 for (i = 0; defenv[i]; ++i) {
890 putenv(defenv[i]);
893 if (!noconsole) {
894 printf("\n\nHit ENTER for console...\n\n");
895 run_shell(1, 0);
898 check_bootnv();
900 for (i = 0; i < sizeof(fatalsigs) / sizeof(fatalsigs[0]); i++) {
901 signal(fatalsigs[i], handle_fatalsigs);
903 for (i = 0; i < sizeof(initsigs) / sizeof(initsigs[0]); i++) {
904 signal(initsigs[i], handle_initsigs);
906 signal(SIGCHLD, handle_reap);
908 switch (model = get_model()) {
909 case MODEL_WR850GV1:
910 case MODEL_WR850GV2:
911 // need to cleanup some variables...
912 if ((nvram_get("t_model") == NULL) && (nvram_get("MyFirmwareVersion") != NULL)) {
913 nvram_unset("MyFirmwareVersion");
914 nvram_set("restore_defaults", "1");
916 break;
919 system("nvram defaults --initcheck");
920 init_nvram();
922 klogctl(8, NULL, nvram_get_int("console_loglevel"));
924 setup_conntrack();
926 hardware = check_hw_type();
927 #if WL_BSS_INFO_VERSION >= 108
928 modprobe("et");
929 #else
930 if ((hardware == HW_BCM4702) && (model != MODEL_WR850GV1)) {
931 modprobe("4702et");
932 modprobe("diag");
934 else {
935 modprobe("et");
937 #endif
938 modprobe("wl");
939 modprobe("tomato_ct");
941 set_host_domain_name();
942 config_loopback();
944 eval("buttons");
946 start_jffs2();
948 set_tz();
950 i = nvram_get_int("sesx_led");
951 led(LED_AMBER, (i & 1) != 0);
952 led(LED_WHITE, (i & 2) != 0);
953 led(LED_AOSS, (i & 4) != 0);
954 led(LED_BRIDGE, (i & 8) != 0);
955 led(LED_DIAG, 1);
958 int init_main(int argc, char *argv[])
960 pid_t shell_pid = 0;
962 sysinit();
964 state = START;
965 signaled = -1;
967 #if defined(DEBUG_NOISY)
968 nvram_set("debug_logeval", "1");
969 nvram_set("debug_cprintf", "1");
970 nvram_set("debug_cprintf_file", "1");
971 nvram_set("debug_ddns", "1");
972 #endif
974 for (;;) {
975 // TRACE_PT("main loop state=%d\n", state);
977 switch (state) {
978 case USER1:
979 exec_service();
980 state = IDLE;
981 break;
982 case RESTART:
983 case STOP:
984 case HALT:
985 case REBOOT:
986 led(LED_DIAG, 1);
988 run_nvscript("script_shut", NULL, 10);
990 stop_services();
991 stop_wan();
992 stop_lan();
993 stop_vlan();
995 if ((state == REBOOT) || (state == HALT)) {
996 shutdn(state == REBOOT);
997 exit(0);
999 if (state == STOP) {
1000 state = IDLE;
1001 break;
1004 // RESTART falls through
1006 case START:
1007 SET_LED(RELEASE_WAN_CONTROL);
1009 run_nvscript("script_init", NULL, 2);
1011 start_vlan();
1012 start_lan();
1013 start_wan(BOOT);
1014 start_services();
1016 syslog(LOG_INFO, "Tomato %s", tomato_version);
1017 syslog(LOG_INFO, "%s", nvram_safe_get("t_model_name"));
1019 led(LED_DIAG, 0);
1021 state = IDLE;
1023 // fall through
1025 case IDLE:
1026 while (signaled == -1) {
1027 check_services();
1028 if ((!noconsole) && ((!shell_pid) || (kill(shell_pid, 0) != 0))) {
1029 shell_pid = run_shell(0, 1);
1031 else {
1032 pause();
1035 state = signaled;
1036 signaled = -1;
1037 break;
1042 int reboothalt_main(int argc, char *argv[])
1044 int reboot = (strstr(argv[0], "reboot") != NULL);
1045 puts(reboot ? "Rebooting..." : "Shutting down...");
1046 fflush(stdout);
1047 sleep(1);
1048 kill(1, reboot ? SIGTERM : SIGQUIT);
1049 return 0;