3 Copyright 2005, Broadcom Corporation
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.
17 #include <sys/ioctl.h>
18 #include <sys/mount.h>
23 #include <sys/reboot.h>
26 #include <sys/types.h>
28 #include <sys/sysinfo.h>
33 #define SHELL "/bin/sh"
35 static int fatalsigs
[] = {
46 static int initsigs
[] = {
56 static char *defenv
[] = {
59 "PATH=/usr/bin:/bin:/usr/sbin:/sbin",
65 /* Set terminal settings to reasonable defaults */
66 static void set_term(int fd
)
72 /* set control chars */
73 tty
.c_cc
[VINTR
] = 3; /* C-c */
74 tty
.c_cc
[VQUIT
] = 28; /* C-\ */
75 tty
.c_cc
[VERASE
] = 127; /* C-? */
76 tty
.c_cc
[VKILL
] = 21; /* C-u */
77 tty
.c_cc
[VEOF
] = 4; /* C-d */
78 tty
.c_cc
[VSTART
] = 17; /* C-q */
79 tty
.c_cc
[VSTOP
] = 19; /* C-s */
80 tty
.c_cc
[VSUSP
] = 26; /* C-z */
82 /* use line dicipline 0 */
86 tty
.c_cflag
&= CBAUD
|CBAUDEX
|CSIZE
|CSTOPB
|PARENB
|PARODD
;
87 tty
.c_cflag
|= CREAD
|HUPCL
|CLOCAL
;
91 tty
.c_iflag
= ICRNL
| IXON
| IXOFF
;
94 tty
.c_oflag
= OPOST
| ONLCR
;
98 ISIG
| ICANON
| ECHO
| ECHOE
| ECHOK
| ECHOCTL
| ECHOKE
| IEXTEN
;
100 tcsetattr(fd
, TCSANOW
, &tty
);
103 static int console_init(void)
108 ioctl(0, TIOCNOTTY
, 0);
115 if ((fd
= open(_PATH_CONSOLE
, O_RDWR
)) < 0) {
116 /* Avoid debug messages is redirected to socket packet if no exist a UART chip, added by honor, 2003-12-04 */
117 open("/dev/null", O_RDONLY
);
118 open("/dev/null", O_WRONLY
);
119 open("/dev/null", O_WRONLY
);
120 perror(_PATH_CONSOLE
);
127 ioctl(0, TIOCSCTTY
, 1);
128 tcsetpgrp(0, getpgrp());
135 * Waits for a file descriptor to change status or unblocked signal
136 * @param fd file descriptor
137 * @param timeout seconds to wait before timing out or 0 for no timeout
138 * @return 1 if descriptor changed status or 0 if timed out or -1 on error
140 static int waitfor(int fd
, int timeout
)
143 struct timeval tv
= { timeout
, 0 };
147 return select(fd
+ 1, &rfds
, NULL
, NULL
, (timeout
> 0) ? &tv
: NULL
);
150 static pid_t
run_shell(int timeout
, int nowait
)
155 /* Wait for user input */
156 if (waitfor(STDIN_FILENO
, timeout
) <= 0) return 0;
158 switch (pid
= fork()) {
163 /* Reset signal handlers set for parent process */
164 for (sig
= 0; sig
< (_NSIG
-1); sig
++)
165 signal(sig
, SIG_DFL
);
169 printf("\n\nTomato %s\n\n", tomato_version
);
171 /* Now run it. The new program will take over this PID,
172 * so nothing further in init.c should be run. */
173 execve(SHELL
, (char *[]) { SHELL
, NULL
}, defenv
);
175 /* We're still here? Some error happened. */
183 waitpid(pid
, NULL
, 0);
189 int console_main(int argc
, char *argv
[])
191 for (;;) run_shell(0, 0);
196 static void shutdn(int rb
)
202 _dprintf("shutdn rb=%d\n", rb
);
205 for (i
= 0; i
< sizeof(fatalsigs
) / sizeof(fatalsigs
[0]); i
++)
206 sigaddset(&ss
, fatalsigs
[i
]);
207 for (i
= 0; i
< sizeof(initsigs
) / sizeof(initsigs
[0]); i
++)
208 sigaddset(&ss
, initsigs
[i
]);
209 sigprocmask(SIG_BLOCK
, &ss
, NULL
);
211 for (i
= 30; i
> 0; --i
) {
212 if (((act
= check_action()) == ACT_IDLE
) || (act
== ACT_REBOOT
)) break;
213 _dprintf("Busy with %d. Waiting before shutdown... %d\n", act
, i
);
216 set_action(ACT_REBOOT
);
218 // Disconnect pppd - need this for PPTP/L2TP to finish gracefully
232 umount("/jffs"); // may hang if not
238 for (i
= 4; i
> 0; --i
) {
249 reboot(rb
? RB_AUTOBOOT
: RB_HALT_SYSTEM
);
256 static void handle_fatalsigs(int sig
)
258 _dprintf("fatal sig=%d\n", sig
);
262 /* Fixed the race condition & incorrect code by using sigwait()
263 * instead of pause(). But SIGCHLD is a problem, since other
264 * code: 1) messes with it and 2) depends on CHLD being caught so
265 * that the pid gets immediately reaped instead of left a zombie.
266 * Pidof still shows the pid, even though it's in zombie state.
267 * So this SIGCHLD handler reaps and then signals the mainline by
270 static void handle_reap(int sig
)
276 static int check_nv(const char *name
, const char *value
)
279 if (!nvram_match("manual_boot_nv", "1")) {
280 if (((p
= nvram_get(name
)) == NULL
) || (strcmp(p
, value
) != 0)) {
281 _dprintf("Error: Critical variable %s is invalid. Resetting.\n", name
);
282 nvram_set(name
, value
);
289 static int find_sercom_mac_addr(void)
292 unsigned char m
[6], s
[18];
294 sprintf(s
, MTD_DEV(%dro
), 0);
295 if ((fp
= fopen(s
, "rb"))) {
296 fseek(fp
, 0x1ffa0, SEEK_SET
);
297 fread(m
, sizeof(m
), 1, fp
);
299 sprintf(s
, "%02X:%02X:%02X:%02X:%02X:%02X",
300 m
[0], m
[1], m
[2], m
[3], m
[4], m
[5]);
301 nvram_set("et0macaddr", s
);
302 return (strncasecmp(s
, "00:90:4c", 8) != 0);
307 static int find_dir320_mac_addr(void)
311 int i
, part
, size
, found
= 0;
313 if (!mtd_getinfo("board_data", &part
, &size
))
315 sprintf(s
, MTD_DEV(%dro
), part
);
317 if ((fp
= fopen(s
, "rb"))) {
318 buffer
= malloc(size
);
319 memset(buffer
, 0, size
);
320 fread(buffer
, size
, 1, fp
);
321 if (!memcmp(buffer
, "RGCFG1", 6)) {
322 for (i
= 6; i
< size
- 24; i
++) {
323 if (!memcmp(buffer
+ i
, "lanmac=", 7)) {
324 memcpy(s
, buffer
+ i
+ 7, 17);
326 nvram_set("et0macaddr", s
);
329 else if (!memcmp(buffer
+ i
, "wanmac=", 7)) {
330 memcpy(s
, buffer
+ i
+ 7, 17);
332 nvram_set("il0macaddr", s
);
335 nvram_set("et0macaddr", s
);
346 strcpy(s
, nvram_safe_get("wl0_hwaddr"));
348 nvram_set("et0macaddr", s
);
353 static int init_vlan_ports(void)
356 int model
= get_model();
360 switch (check_hw_type()) {
361 case HW_BCM5352E
: // G v4, GS v3, v4
362 dirty
|= check_nv("vlan0ports", "3 2 1 0 5*");
367 dirty
|= check_nv("vlan0ports", "0 5*");
368 dirty
|= check_nv("vlan1ports", "1 5");
369 dirty
|= check_nv("vlan_enable", "1");
373 case MODEL_WL500GPv2
:
375 if (nvram_match("vlan1ports", "0 5u")) // 520GU or WL500GE?
376 dirty
|= check_nv("vlan1ports", "0 5");
377 else if (nvram_match("vlan1ports", "4 5u"))
378 dirty
|= check_nv("vlan1ports", "4 5");
381 dirty
|= check_nv("vlan0ports", "1 2 3 4 5*");
382 dirty
|= check_nv("vlan1ports", "0 5");
386 dirty
|= (nvram_get("vlan2ports") != NULL
);
387 nvram_unset("vlan2ports");
388 dirty
|= check_nv("vlan1ports", "0 5");
390 case MODEL_WRT310Nv1
:
391 dirty
|= check_nv("vlan1ports", "1 2 3 4 8*");
392 dirty
|= check_nv("vlan2ports", "0 8");
395 dirty
|= check_nv("vlan0ports", "0 1 2 3 5*");
396 dirty
|= check_nv("vlan1ports", "4 5");
402 dirty
|= check_nv("vlan1ports", "4 3 2 1 8*");
403 dirty
|= check_nv("vlan2ports", "0 8");
405 case MODEL_WNR2000v2
:
406 dirty
|= check_nv("vlan0ports", "4 3 2 1 5*");
407 dirty
|= check_nv("vlan1ports", "0 5");
410 dirty
|= check_nv("vlan1ports", "4 5");
413 dirty
|= check_nv("vlan0ports", "3 2 1 0 5*");
414 dirty
|= check_nv("vlan1ports", "4 5");
416 case MODEL_WRT610Nv2
:
417 case MODEL_F5D8235v3
:
418 dirty
|= check_nv("vlan1ports", "1 2 3 4 8*");
419 dirty
|= check_nv("vlan2ports", "0 8");
423 dirty
|= check_nv("vlan1ports", "3 2 1 0 8*");
424 dirty
|= check_nv("vlan2ports", "4 8");
428 dirty
|= check_nv("vlan1ports", "0 1 2 3 5*");
429 dirty
|= check_nv("vlan2ports", "4 5");
432 dirty
|= check_nv("vlan1ports", "0 1 2 3 8*");
433 dirty
|= check_nv("vlan2ports", "4 8");
435 case MODEL_WRT160Nv3
:
436 if (nvram_match("vlan1ports", "1 2 3 4 5*")) {
437 // fix lan port numbering on CSE41, CSE51
438 dirty
|= check_nv("vlan1ports", "4 3 2 1 5*");
440 else if (nvram_match("vlan1ports", "1 2 3 4 8*")) {
442 dirty
|= check_nv("vlan1ports", "4 3 2 1 8*");
451 static void check_bootnv(void)
463 dirty
|= check_nv("vlan0hwname", "et0");
464 dirty
|= check_nv("vlan1hwname", "et0");
467 dirty
|= check_nv("wl0gpio0", "130");
470 /* fix WL500W mac adresses for WAN port */
471 if (strncasecmp(nvram_safe_get("et1macaddr"), "00:90:4c", 8) == 0) {
472 strcpy(mac
, nvram_safe_get("et0macaddr"));
474 dirty
|= check_nv("et1macaddr", mac
);
476 dirty
|= check_nv("wl0gpio0", "0x88");
479 dirty
|= check_nv("sdram_init", "0x0009"); // 32MB; defaults: 0x000b, 0x0009
480 dirty
|= check_nv("wl0gpio0", "136");
482 case MODEL_WL500GPv2
:
484 dirty
|= check_nv("wl0gpio1", "136");
487 dirty
|= check_nv("vlan0hwname", "et0");
488 dirty
|= check_nv("vlan1hwname", "et0");
489 dirty
|= check_nv("boardflags", "0x00000100"); // set BFL_ENETVLAN
490 nvram_unset("wl0gpio0");
493 if (strlen(nvram_safe_get("et0macaddr")) == 12 ||
494 strlen(nvram_safe_get("il0macaddr")) == 12) {
495 dirty
|= find_dir320_mac_addr();
497 if (nvram_get("vlan2hwname") != NULL
) {
498 nvram_unset("vlan2hwname");
501 dirty
|= check_nv("wandevs", "vlan1");
502 dirty
|= check_nv("vlan1hwname", "et0");
503 dirty
|= check_nv("wl0gpio0", "8");
504 dirty
|= check_nv("wl0gpio1", "0");
505 dirty
|= check_nv("wl0gpio2", "0");
506 dirty
|= check_nv("wl0gpio3", "0");
508 if (strncasecmp(nvram_safe_get("et0macaddr"), "00:90:4c", 8) == 0) {
509 dirty
|= find_sercom_mac_addr();
512 case MODEL_WRT160Nv1
:
513 case MODEL_WRT310Nv1
:
515 dirty
|= check_nv("wl0gpio0", "8");
519 dirty
|= check_nv("boardflags", "0x00000710"); // needed to enable USB
520 dirty
|= check_nv("vlan2hwname", "et0");
521 dirty
|= check_nv("ledbh0", "7");
523 case MODEL_WNR2000v2
:
524 dirty
|= check_nv("ledbh5", "8");
527 dirty
|= check_nv("reset_gpio", "5");
528 dirty
|= check_nv("ledbh0", "136");
529 dirty
|= check_nv("ledbh1", "11");
530 /* fall through, same as RT-N16 */
532 dirty
|= check_nv("vlan2hwname", "et0");
534 case MODEL_WRT610Nv2
:
535 dirty
|= check_nv("vlan2hwname", "et0");
536 dirty
|= check_nv("wl1_leddc", "0x640000");
537 dirty
|= check_nv("pci/1/1/ledbh2", "8");
538 dirty
|= check_nv("sb/1/ledbh1", "8");
539 if (strncasecmp(nvram_safe_get("pci/1/1/macaddr"), "00:90:4c", 8) == 0) {
540 strcpy(mac
, nvram_safe_get("et0macaddr"));
542 dirty
|= check_nv("pci/1/1/macaddr", mac
);
546 dirty
|= check_nv("vlan2hwname", "et0");
547 dirty
|= check_nv("wl1_leddc", "0x640000");
548 if (strncasecmp(nvram_safe_get("pci/1/1/macaddr"), "00:90:4c", 8) == 0) {
549 strcpy(mac
, nvram_safe_get("et0macaddr"));
551 dirty
|= check_nv("pci/1/1/macaddr", mac
);
554 case MODEL_WRT160Nv3
:
555 dirty
|= check_nv("vlan2hwname", "et0");
560 if (strncmp(nvram_safe_get("pmon_ver"), "CFE", 3) != 0) return;
562 hardware
= check_hw_type();
563 if (!nvram_get("boardtype") ||
564 !nvram_get("boardnum") ||
565 !nvram_get("boardflags") ||
566 !nvram_get("clkfreq") ||
567 !nvram_get("os_flash_addr") ||
568 !nvram_get("dl_ram_addr") ||
569 !nvram_get("os_ram_addr") ||
570 !nvram_get("scratch") ||
571 !nvram_get("et0macaddr") ||
572 ((hardware
!= HW_BCM4704_BCM5325F
) && (!nvram_get("vlan0ports") || !nvram_get("vlan0hwname")))) {
573 _dprintf("Unable to find critical settings, erasing NVRAM\n");
578 dirty
|= check_nv("aa0", "3");
579 dirty
|= check_nv("wl0gpio0", "136");
580 dirty
|= check_nv("wl0gpio2", "0");
581 dirty
|= check_nv("wl0gpio3", "0");
582 dirty
|= check_nv("cctl", "0");
583 dirty
|= check_nv("ccode", "0");
587 /* Lower the DDR ram drive strength , the value will be stable for all boards
588 Latency 3 is more stable for all ddr 20050420 by honor */
589 dirty
|= check_nv("sdram_init", "0x010b");
590 dirty
|= check_nv("sdram_config", "0x0062");
591 if (!nvram_match("debug_clkfix", "0")) {
592 dirty
|= check_nv("clkfreq", "216");
595 nvram_set("sdram_ncdl", "0x0");
597 dirty
|= check_nv("pa0itssit", "62");
598 dirty
|= check_nv("pa0b0", "0x15eb");
599 dirty
|= check_nv("pa0b1", "0xfa82");
600 dirty
|= check_nv("pa0b2", "0xfe66");
601 //dirty |= check_nv("pa0maxpwr", "0x4e");
603 case HW_BCM5352E
: // G v4, GS v3, v4
604 dirty
|= check_nv("sdram_init", "0x010b");
605 dirty
|= check_nv("sdram_config", "0x0062");
607 nvram_set("sdram_ncdl", "0x0");
609 dirty
|= check_nv("pa0itssit", "62");
610 dirty
|= check_nv("pa0b0", "0x168b");
611 dirty
|= check_nv("pa0b1", "0xfabf");
612 dirty
|= check_nv("pa0b2", "0xfeaf");
613 //dirty |= check_nv("pa0maxpwr", "0x4e");
616 dirty
|= check_nv("pa0itssit", "62");
617 dirty
|= check_nv("pa0b0", "0x1326");
618 dirty
|= check_nv("pa0b1", "0xFB51");
619 dirty
|= check_nv("pa0b2", "0xFE87");
620 //dirty |= check_nv("pa0maxpwr", "0x4e");
622 case HW_BCM4704_BCM5325F
:
626 dirty
|= check_nv("pa0itssit", "62");
627 dirty
|= check_nv("pa0b0", "0x170c");
628 dirty
|= check_nv("pa0b1", "0xfa24");
629 dirty
|= check_nv("pa0b2", "0xfe70");
630 //dirty |= check_nv("pa0maxpwr", "0x48");
637 dirty
|= check_nv("wl0_leddc", "0x640000");
638 dirty
|= init_vlan_ports();
642 REBOOT
: // do a simple reboot
649 static int init_nvram(void)
651 unsigned long features
;
660 sprintf(s
, "%d", model
);
661 nvram_set("t_model", s
);
669 name
= "WRT54G/GS/GL";
670 switch (check_hw_type()) {
672 nvram_set("gpio2", "adm_eecs");
673 nvram_set("gpio3", "adm_eesk");
674 nvram_unset("gpio4");
675 nvram_set("gpio5", "adm_eedi");
676 nvram_set("gpio6", "adm_rc");
679 nvram_unset("gpio2");
680 nvram_unset("gpio3");
681 nvram_unset("gpio4");
682 nvram_unset("gpio5");
683 nvram_unset("gpio6");
686 nvram_set("opo", "0x0008");
687 nvram_set("ag0", "0x02");
690 nvram_set("gpio2", "ses_led");
691 nvram_set("gpio3", "ses_led2");
692 nvram_set("gpio4", "ses_button");
693 features
= SUP_SES
| SUP_WHAM_LED
;
700 if (!nvram_match("t_fix1", (char *)name
)) {
701 nvram_set("lan_ifnames", "vlan0 eth1");
702 nvram_set("gpio2", "ses_button");
703 nvram_set("reset_gpio", "7");
705 nvram_set("pa0itssit", "62");
706 nvram_set("pa0b0", "0x1542");
707 nvram_set("pa0b1", "0xfacb");
708 nvram_set("pa0b2", "0xfec7");
709 //nvram_set("pa0maxpwr", "0x4c");
712 case MODEL_WRTSL54GS
:
715 features
= SUP_SES
| SUP_WHAM_LED
;
720 features
= SUP_SES
| SUP_AOSS_LED
| SUP_BRAU
;
723 case MODEL_WZRRSG54HP
:
726 features
= SUP_SES
| SUP_AOSS_LED
| SUP_HPAMP
;
728 case MODEL_WZRRSG54HP
:
729 name
= "WZR-RS-G54HP";
736 features
= SUP_SES
| SUP_AOSS_LED
| SUP_BRAU
| SUP_HPAMP
;
740 bf
= strtoul(nvram_safe_get("boardflags"), NULL
, 0);
746 if (nvram_match("wlx_hpamp", "")) {
747 if (nvram_get_int("wl_txpwr") > 10) nvram_set("wl_txpwr", "10");
748 nvram_set("wlx_hpamp", "1");
749 nvram_set("wlx_hperx", "0");
753 if (nvram_match("wlx_hpamp", "0")) {
759 if (nvram_match("wlx_hperx", "0")) {
766 sprintf(s
, "0x%lX", n
);
767 nvram_set("boardflags", s
);
771 syslog(LOG_WARNING
, "Unexpected: boardflag=%lX", bf
);
782 features
= SUP_SES
| SUP_AOSS_LED
;
784 case MODEL_WHR2A54G54
:
786 name
= "WHR2-A54G54";
787 features
= SUP_SES
| SUP_AOSS_LED
| SUP_BRAU
;
792 features
= SUP_SES
| SUP_AOSS_LED
;
797 features
= SUP_SES
| SUP_AOSS_LED
;
802 features
= SUP_SES
| SUP_AOSS_LED
;
812 features
= SUP_SES
| SUP_AOSS_LED
;
821 features
= SUP_NONVE
;
825 name
= "WR850G v2/v3";
826 features
= SUP_NONVE
;
833 nvram_set("usb_ohci", "-1");
835 if (!nvram_match("t_fix1", (char *)name
)) {
836 nvram_set("lan_ifnames", "vlan0 eth1 eth2 eth3"); // set to "vlan0 eth2" by DD-WRT; default: vlan0 eth1
842 features
= SUP_SES
| SUP_80211N
;
844 nvram_set("usb_ohci", "-1");
852 nvram_set("usb_uhci", "-1");
871 if (!nvram_match("t_fix1", (char *)name
)) {
872 nvram_set("lan_ifnames", "vlan0 eth1 eth2");
873 nvram_set("wl_ifname", "eth1");
874 nvram_set("wan_ifname", "none");
879 name
= "TrueMobile 2300";
888 #ifndef WL_BSS_INFO_VERSION
889 #error WL_BSS_INFO_VERSION
891 #if WL_BSS_INFO_VERSION >= 108
897 nvram_set("opo", "12");
903 features
= SUP_SES
| SUP_AOSS_LED
| SUP_BRAU
;
905 nvram_set("opo", "0x0008");
906 nvram_set("ag0", "0x0C");
912 features
= SUP_SES
| SUP_80211N
;
913 if (!nvram_match("t_fix1", (char *)name
)) {
914 nvram_set("lan_ifnames", "vlan0 eth1");
915 nvram_set("wan_ifnameX", "vlan1");
916 nvram_set("wl_ifname", "eth1");
922 features
= SUP_SES
| SUP_BRAU
| SUP_80211N
;
923 if (!nvram_match("t_fix1", (char *)name
)) {
924 nvram_set("lan_ifnames", "vlan0 eth1");
925 nvram_set("wan_ifnameX", "vlan1");
926 nvram_set("wl_ifname", "eth1");
932 features
= SUP_SES
| SUP_80211N
| SUP_1000ET
;
934 nvram_set("usb_uhci", "-1");
936 if (!nvram_match("t_fix1", (char *)name
)) {
937 nvram_set("lan_ifnames", "vlan1 eth1");
938 nvram_set("wan_ifnameX", "vlan2");
939 nvram_set("wl_ifname", "eth1");
940 nvram_set("vlan_enable", "1");
945 name
= "WNR3500L/U/v2";
946 features
= SUP_SES
| SUP_AOSS_LED
| SUP_80211N
| SUP_1000ET
;
947 if (!nvram_match("t_fix1", (char *)name
)) {
948 nvram_set("sromrev", "3");
949 nvram_set("lan_ifnames", "vlan1 eth1");
950 nvram_set("wan_ifnameX", "vlan2");
951 nvram_set("wl_ifname", "eth1");
954 case MODEL_WNR2000v2
:
957 features
= SUP_SES
| SUP_AOSS_LED
| SUP_80211N
;
958 if (!nvram_match("t_fix1", (char *)name
)) {
959 nvram_set("lan_ifnames", "vlan0 eth1");
960 nvram_set("wan_ifnameX", "vlan1");
961 nvram_set("wl_ifname", "eth1");
968 case MODEL_F5D8235v3
:
970 features
= SUP_SES
| SUP_80211N
;
973 name
= "Share Max F7D3301 v1";
976 name
= "Share F7D3302 v1";
979 name
= "Play Max F7D4301 v1";
982 name
= "Play F7D4302 v1";
984 case MODEL_F5D8235v3
:
985 name
= "F5D8235-4 v3";
988 if (!nvram_match("t_fix1", (char *)name
)) {
989 nvram_set("lan_ifnames", "vlan1 eth1 eth2");
990 nvram_set("wan_ifnameX", "vlan2");
993 case MODEL_WRT160Nv3
:
994 // same as M10, M20, WRT310Nv2, E1000v1
996 name
= nvram_safe_get("boot_hw_model");
997 if (strcmp(name
, "E100") == 0)
999 features
= SUP_SES
| SUP_80211N
| SUP_WHAM_LED
;
1000 if (!nvram_match("t_fix1", (char *)name
)) {
1001 nvram_set("lan_ifnames", "vlan1 eth1");
1002 nvram_set("wan_ifnameX", "vlan2");
1003 nvram_set("wl_ifname", "eth1");
1008 name
= nvram_match("boardrev", "0x1307") ? "E2000" : "WRT320N";
1009 features
= SUP_SES
| SUP_80211N
| SUP_WHAM_LED
| SUP_1000ET
;
1010 if (!nvram_match("t_fix1", (char *)name
)) {
1011 nvram_set("lan_ifnames", "vlan1 eth1");
1012 nvram_set("wan_ifnameX", "vlan2");
1013 nvram_set("wl_ifname", "eth1");
1016 case MODEL_WRT610Nv2
:
1018 name
= nvram_match("boot_hw_model", "E300") ? "E3000" : "WRT610N v2";
1019 features
= SUP_SES
| SUP_80211N
| SUP_WHAM_LED
| SUP_1000ET
;
1021 nvram_set("usb_uhci", "-1");
1023 if (!nvram_match("t_fix1", (char *)name
)) {
1024 nvram_set("lan_ifnames", "vlan1 eth1 eth2");
1025 nvram_set("wan_ifnameX", "vlan2");
1026 nvram_set("wl_ifname", "eth1");
1031 name
= nvram_safe_get("boot_hw_model");
1032 features
= SUP_SES
| SUP_80211N
| SUP_1000ET
;
1034 nvram_set("usb_uhci", "-1");
1036 if (!nvram_match("t_fix1", (char *)name
)) {
1037 nvram_set("lan_ifnames", "vlan1 eth1");
1038 nvram_set("wan_ifnameX", "vlan2");
1039 nvram_set("wl_ifname", "eth1");
1042 #endif // CONFIG_BCMWL5
1043 case MODEL_WL500GPv2
:
1045 name
= "WL-500gP v2";
1048 nvram_set("usb_uhci", "-1");
1056 nvram_set("usb_uhci", "-1");
1061 name
= "WL-500g Deluxe";
1062 // features = SUP_SES;
1064 nvram_set("usb_ohci", "-1");
1066 if (!nvram_match("t_fix1", (char *)name
)) {
1067 nvram_set("wl_ifname", "eth1");
1068 nvram_set("lan_ifnames", "vlan0 eth1");
1069 nvram_set("wan_ifnameX", "vlan1");
1070 nvram_unset("wl0gpio0");
1077 if (!nvram_match("t_fix1", (char *)name
)) {
1078 nvram_set("wan_ifnameX", "vlan1");
1079 nvram_set("wl_ifname", "eth1");
1084 name
= "ZXV10 H618B";
1085 features
= SUP_SES
| SUP_AOSS_LED
;
1087 case MODEL_WL1600GL
:
1092 #endif // WL_BSS_INFO_VERSION >= 108
1093 case MODEL_WZRG300N
:
1096 features
= SUP_SES
| SUP_AOSS_LED
| SUP_BRAU
| SUP_80211N
;
1098 case MODEL_WRT160Nv1
:
1101 name
= (model
== MODEL_WRT300N
) ? "WRT300N v1" : "WRT160N v1";
1102 features
= SUP_SES
| SUP_80211N
;
1103 if (!nvram_match("t_fix1", (char *)name
)) {
1104 nvram_set("wan_ifnameX", "eth1");
1105 nvram_set("lan_ifnames", "eth0 eth2");
1108 case MODEL_WRT310Nv1
:
1110 name
= "WRT310N v1";
1111 features
= SUP_SES
| SUP_80211N
| SUP_WHAM_LED
| SUP_1000ET
;
1112 if (!nvram_match("t_fix1", (char *)name
)) {
1113 nvram_set("lan_ifnames", "vlan1 eth1");
1114 nvram_set("wan_ifnameX", "vlan2");
1115 nvram_set("wl_ifname", "eth1");
1121 nvram_set("t_fix1", name
);
1122 sprintf(s
, "%s %s", mfr
, name
);
1125 snprintf(s
, sizeof(s
), "%s %d/%s/%s/%s/%s", mfr
, check_hw_type(),
1126 nvram_safe_get("boardtype"), nvram_safe_get("boardnum"), nvram_safe_get("boardrev"), nvram_safe_get("boardflags"));
1129 nvram_set("t_model_name", s
);
1131 nvram_set("pa0maxpwr", "400"); // allow Tx power up tp 400 mW, needed for ND only
1133 sprintf(s
, "0x%lX", features
);
1134 nvram_set("t_features", s
);
1137 note: set wan_ifnameX if wan_ifname needs to be overriden
1140 if (nvram_is_empty("wan_ifnameX")) {
1142 nvram_set("wan_ifnameX", ((strtoul(nvram_safe_get("boardflags"), NULL
, 0) & BFL_ENETVLAN
) ||
1143 (check_hw_type() == HW_BCM4712
)) ? "vlan1" : "eth1");
1145 p
= nvram_safe_get("wan_ifname");
1146 if ((*p
== 0) || (nvram_match("wl_ifname", p
))) {
1147 p
= ((strtoul(nvram_safe_get("boardflags"), NULL
, 0) & BFL_ENETVLAN
) ||
1148 (check_hw_type() == HW_BCM4712
)) ? "vlan1" : "eth1";
1150 nvram_set("wan_ifnameX", p
);
1154 nvram_set("wl_hwaddr", ""); // zzz- when disabling wireless, we must get null wireless mac ??
1156 //!!TB - do not force country code here to allow nvram override
1157 //nvram_set("wl_country", "JP");
1158 //nvram_set("wl_country_code", "JP");
1159 nvram_set("wan_get_dns", "");
1160 nvram_set("wan_get_domain", "");
1161 nvram_set("ppp_get_ip", "");
1162 nvram_set("action_service", "");
1163 nvram_set("jffs2_format", "0");
1164 nvram_set("rrules_radio", "-1");
1165 nvram_unset("https_crt_gen");
1166 nvram_unset("log_wmclear");
1168 nvram_set("ipv6_get_dns", "");
1170 #ifdef TCONFIG_MEDIA_SERVER
1171 nvram_unset("ms_rescan");
1173 if (nvram_get_int("http_id_gen") == 1) nvram_unset("http_id");
1175 nvram_unset("sch_rboot_last");
1176 nvram_unset("sch_rcon_last");
1177 nvram_unset("sch_c1_last");
1178 nvram_unset("sch_c2_last");
1179 nvram_unset("sch_c3_last");
1181 nvram_set("brau_state", "");
1182 if ((features
& SUP_BRAU
) == 0) nvram_set("script_brau", "");
1183 if ((features
& SUP_SES
) == 0) nvram_set("sesx_script", "");
1185 if ((features
& SUP_1000ET
) == 0) nvram_set("jumbo_frame_enable", "0");
1187 // compatibility with old versions
1188 if (nvram_match("wl_net_mode", "disabled")) {
1189 nvram_set("wl_radio", "0");
1190 nvram_set("wl_net_mode", "mixed");
1196 /* Get the special files from nvram and copy them to disc.
1197 * These were files saved with "nvram setfile2nvram <filename>".
1198 * Better hope that they were saved with full pathname.
1200 static void load_files_from_nvram(void)
1204 char buf
[NVRAM_SPACE
];
1206 if (nvram_getall(buf
, sizeof(buf
)) != 0)
1209 for (name
= buf
; *name
; name
+= strlen(name
) + 1) {
1210 if (strncmp(name
, "FILE:", 5) == 0) { /* This special name marks a file to get. */
1211 if ((cp
= strchr(name
, '=')) == NULL
)
1214 syslog(LOG_INFO
, "Loading file '%s' from nvram", name
+ 5);
1215 nvram_nvram2file(name
, name
+ 5);
1216 if (memcmp(".autorun", cp
- 8, 9) == 0)
1220 /* Start any autorun files that may have been loaded into one of the standard places. */
1222 run_nvscript(".autorun", NULL
, 3);
1225 #if defined(LINUX26) && defined(TCONFIG_USB)
1226 static inline void tune_min_free_kbytes(void)
1228 struct sysinfo info
;
1230 memset(&info
, 0, sizeof(struct sysinfo
));
1232 if (info
.totalram
>= 55 * 1024 * 1024) {
1233 // If we have 64MB+ RAM, tune min_free_kbytes
1234 // to reduce page allocation failure errors.
1235 f_write_string("/proc/sys/vm/min_free_kbytes", "8192", 0, 0);
1240 static void sysinit(void)
1242 static int noconsole
= 0;
1243 static const time_t tm
= 0;
1252 mount("proc", "/proc", "proc", 0, NULL
);
1253 mount("tmpfs", "/tmp", "tmpfs", 0, NULL
);
1256 mount("devfs", "/dev", "tmpfs", MS_MGC_VAL
| MS_NOATIME
, NULL
);
1257 mknod("/dev/null", S_IFCHR
| 0666, makedev(1, 3));
1258 mknod("/dev/console", S_IFCHR
| 0600, makedev(5, 1));
1259 mount("sysfs", "/sys", "sysfs", MS_MGC_VAL
, NULL
);
1260 mkdir("/dev/shm", 0777);
1261 mkdir("/dev/pts", 0777);
1262 mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL
, NULL
);
1265 if (console_init()) noconsole
= 1;
1269 static const char *mkd
[] = {
1270 "/tmp/etc", "/tmp/var", "/tmp/home", "/tmp/mnt",
1271 "/tmp/share", "/var/webmon", // !!TB
1272 "/var/log", "/var/run", "/var/tmp", "/var/lib", "/var/lib/misc",
1273 "/var/spool", "/var/spool/cron", "/var/spool/cron/crontabs",
1274 "/tmp/var/wwwext", "/tmp/var/wwwext/cgi-bin", // !!TB - CGI support
1278 for (i
= 0; mkd
[i
]; ++i
) {
1279 mkdir(mkd
[i
], 0755);
1281 mkdir("/var/lock", 0777);
1282 mkdir("/var/tmp/dhcp", 0777);
1283 mkdir("/home/root", 0700);
1284 chmod("/tmp", 0777);
1285 f_write("/etc/hosts", NULL
, 0, 0, 0644); // blank
1286 f_write("/etc/fstab", NULL
, 0, 0, 0644); // !!TB - blank
1287 simple_unlock("cron");
1288 simple_unlock("firewall");
1289 simple_unlock("restrictions");
1292 if ((d
= opendir("/rom/etc")) != NULL
) {
1293 while ((de
= readdir(d
)) != NULL
) {
1294 if (de
->d_name
[0] == '.') continue;
1295 snprintf(s
, sizeof(s
), "%s/%s", "/rom/etc", de
->d_name
);
1296 snprintf(t
, sizeof(t
), "%s/%s", "/etc", de
->d_name
);
1301 symlink("/proc/mounts", "/etc/mtab");
1303 #ifdef TCONFIG_SAMBASRV
1304 if ((d
= opendir("/usr/codepages")) != NULL
) {
1305 while ((de
= readdir(d
)) != NULL
) {
1306 if (de
->d_name
[0] == '.') continue;
1307 snprintf(s
, sizeof(s
), "/usr/codepages/%s", de
->d_name
);
1308 snprintf(t
, sizeof(t
), "/usr/share/%s", de
->d_name
);
1316 eval("hotplug2", "--coldplug");
1319 static const char *dn
[] = {
1320 "null", "zero", "random", "urandom", "full", "ptmx", "nvram",
1323 for (i
= 0; dn
[i
]; ++i
) {
1324 snprintf(s
, sizeof(s
), "/dev/%s", dn
[i
]);
1327 chmod("/dev/gpio", 0660);
1330 set_action(ACT_IDLE
);
1332 for (i
= 0; defenv
[i
]; ++i
) {
1337 printf("\n\nHit ENTER for console...\n\n");
1344 // disable IPv6 by default on all interfaces
1345 f_write_string("/proc/sys/net/ipv6/conf/default/disable_ipv6", "1", 0, 0);
1348 for (i
= 0; i
< sizeof(fatalsigs
) / sizeof(fatalsigs
[0]); i
++) {
1349 signal(fatalsigs
[i
], handle_fatalsigs
);
1351 signal(SIGCHLD
, handle_reap
);
1353 switch (model
= get_model()) {
1354 case MODEL_WR850GV1
:
1355 case MODEL_WR850GV2
:
1356 // need to cleanup some variables...
1357 if ((nvram_get("t_model") == NULL
) && (nvram_get("MyFirmwareVersion") != NULL
)) {
1358 nvram_unset("MyFirmwareVersion");
1359 nvram_set("restore_defaults", "1");
1364 #ifdef CONFIG_BCMWL5
1365 // ctf must be loaded prior to any other modules
1366 if (nvram_invmatch("ctf_disable", "1"))
1370 switch (hardware
= check_hw_type()) {
1372 modprobe("bcm57xx");
1387 system("nvram defaults --initcheck");
1390 // set the packet size
1391 if (nvram_get_int("jumbo_frame_enable")) {
1392 // only set the size here - 'enable' flag is set by the driver
1393 // eval("et", "robowr", "0x40", "0x01", "0x1F"); // (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)
1394 eval("et", "robowr", "0x40", "0x05", nvram_safe_get("jumbo_frame_size"));
1397 klogctl(8, NULL
, nvram_get_int("console_loglevel"));
1399 #if defined(LINUX26) && defined(TCONFIG_USB)
1400 tune_min_free_kbytes();
1403 set_host_domain_name();
1409 if (!noconsole
) xstart("console");
1411 i
= nvram_get_int("sesx_led");
1412 led(LED_AMBER
, (i
& 1) != 0);
1413 led(LED_WHITE
, (i
& 2) != 0);
1414 led(LED_AOSS
, (i
& 4) != 0);
1415 led(LED_BRIDGE
, (i
& 8) != 0);
1419 int init_main(int argc
, char *argv
[])
1426 sigemptyset(&sigset
);
1427 for (i
= 0; i
< sizeof(initsigs
) / sizeof(initsigs
[0]); i
++) {
1428 sigaddset(&sigset
, initsigs
[i
]);
1430 sigprocmask(SIG_BLOCK
, &sigset
, NULL
);
1432 #if defined(DEBUG_NOISY)
1433 nvram_set("debug_logeval", "1");
1434 nvram_set("debug_cprintf", "1");
1435 nvram_set("debug_cprintf_file", "1");
1436 nvram_set("debug_ddns", "1");
1441 state
= SIGUSR2
; /* START */
1444 TRACE_PT("main loop signal/state=%d\n", state
);
1447 case SIGUSR1
: /* USER1: service handler */
1451 case SIGHUP
: /* RESTART */
1452 case SIGINT
: /* STOP */
1453 case SIGQUIT
: /* HALT */
1454 case SIGTERM
: /* REBOOT */
1456 unlink("/var/notice/sysup");
1458 run_nvscript("script_shut", NULL
, 10);
1466 if ((state
== SIGTERM
/* REBOOT */) ||
1467 (state
== SIGQUIT
/* HALT */)) {
1468 remove_storage_main(1);
1471 shutdn(state
== SIGTERM
/* REBOOT */);
1474 if (state
== SIGINT
/* STOP */) {
1478 // SIGHUP (RESTART) falls through
1480 case SIGUSR2
: /* START */
1481 SET_LED(RELEASE_WAN_CONTROL
);
1484 load_files_from_nvram();
1487 fd
= file_lock("usb"); // hold off automount processing
1490 run_nvscript("script_init", NULL
, 2);
1492 file_unlock(fd
); // allow to process usb hotplug events
1495 * On RESTART some partitions can stay mounted if they are busy at the moment.
1496 * In that case USB drivers won't unload, and hotplug won't kick off again to
1497 * remount those drives that actually got unmounted. Make sure to remount ALL
1498 * partitions here by simulating hotplug event.
1500 if (state
== SIGHUP
/* RESTART */)
1501 add_remove_usbhost("-1", 1);
1511 #ifdef CONFIG_BCMWL5
1513 /* Restart NAS one more time - for some reason without
1514 * this the new driver doesn't always bring WDS up.
1521 syslog(LOG_INFO
, "%s: Tomato %s", nvram_safe_get("t_model_name"), tomato_version
);
1524 notice_set("sysup", "");
1528 chld_reap(0); /* Periodically reap zombies. */
1530 sigwait(&sigset
, &state
);
1536 int reboothalt_main(int argc
, char *argv
[])
1538 int reboot
= (strstr(argv
[0], "reboot") != NULL
);
1539 puts(reboot
? "Rebooting..." : "Shutting down...");
1542 kill(1, reboot
? SIGTERM
: SIGQUIT
);
1544 /* In the case we're hung, we'll get stuck and never actually reboot.
1545 * The only way out is to pull power.
1546 * So after 'reset_wait' seconds (default: 20), forcibly crash & restart.
1549 int wait
= nvram_get_int("reset_wait") ? : 20;
1550 if ((wait
< 10) || (wait
> 120)) wait
= 10;
1552 f_write("/proc/sysrq-trigger", "s", 1, 0 , 0); /* sync disks */
1554 puts("Still running... Doing machine reset.");
1556 f_write("/proc/sysrq-trigger", "s", 1, 0 , 0); /* sync disks */
1558 f_write("/proc/sysrq-trigger", "b", 1, 0 , 0); /* machine reset */