1/*
2	Copyright 2005, Broadcom Corporation
3	All Rights Reserved.
4
5	THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
6	KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
7	SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
8	FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
9
10*/
11
12#include "rc.h"
13
14#include <termios.h>
15#include <dirent.h>
16#include <sys/ioctl.h>
17#include <sys/mount.h>
18#include <time.h>
19#include <errno.h>
20#include <paths.h>
21#include <sys/wait.h>
22#include <sys/reboot.h>
23#include <sys/klog.h>
24#include <fcntl.h>
25#include <unistd.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <sys/sysinfo.h>
29#include <wlutils.h>
30#include <bcmdevs.h>
31
32#include <shared.h>
33
34#ifdef RTCONFIG_QCA
35#include <qca.h>
36#include <flash_mtd.h>
37#endif
38
39#if defined(RTCONFIG_NEW_REGULATION_DOMAIN)
40#error !!!!!!!!!!!QCA driver must use country code!!!!!!!!!!!
41#endif
42static struct load_wifi_kmod_seq_s {
43	char *kmod_name;
44	unsigned int load_sleep;
45	unsigned int remove_sleep;
46} load_wifi_kmod_seq[] = {
47	{ "asf", 0, 0 },
48	{ "adf", 0, 0 },
49	{ "ath_hal", 0, 0 },
50	{ "ath_rate_atheros", 0, 0 },
51	{ "ath_dfs", 0, 0 },
52	{ "ath_spectral", 0, 0 },
53	{ "hst_tx99", 0, 0 },
54	{ "ath_dev", 0, 0 },
55	{ "umac", 0, 2 },
56	{ "ath_pktlog", 0, 0 },
57	{ "smart_antenna", 0, 0 },
58};
59
60static struct load_nat_accel_kmod_seq_s {
61	char *kmod_name;
62	unsigned int load_sleep;
63	unsigned int remove_sleep;
64} load_nat_accel_kmod_seq[] = {
65#if defined(RTCONFIG_SOC_IPQ8064)
66	{ "ecm", 0, 0 },
67#else
68	{ "shortcut_fe", 0, 0 },
69	{ "fast_classifier", 0, 0 },
70#endif
71};
72
73static void __mknod(char *name, mode_t mode, dev_t dev)
74{
75	if (mknod(name, mode, dev)) {
76		printf("## mknod %s mode 0%o fail! errno %d (%s)", name, mode, errno, strerror(errno));
77	}
78}
79
80void init_devs(void)
81{
82	int status;
83
84	__mknod("/dev/nvram", S_IFCHR | 0666, makedev(228, 0));
85	__mknod("/dev/dk0", S_IFCHR | 0666, makedev(63, 0));
86	__mknod("/dev/dk1", S_IFCHR | 0666, makedev(63, 1));
87	__mknod("/dev/armem", S_IFCHR | 0660, makedev(1, 13));
88	__mknod("/dev/sfe", S_IFCHR | 0660, makedev(252, 0)); // TBD
89#if (defined(PLN12) || defined(PLAC56) || defined(PLAC66U))
90	eval("ln", "-sf", "/dev/mtdblock2", "/dev/caldata");	/* mtdblock2 = SPI flash, Factory MTD partition */
91#else
92	eval("ln", "-sf", "/dev/mtdblock3", "/dev/caldata");	/* mtdblock3 = Factory MTD partition */
93#endif
94
95	if ((status = WEXITSTATUS(modprobe("nvram_linux"))))
96		printf("## modprove(nvram_linux) fail status(%d)\n", status);
97}
98
99void generate_switch_para(void)
100{
101#if defined(RTCONFIG_DUALWAN)
102	int model;
103	int wans_cap = get_wans_dualwan() & WANSCAP_WAN;
104	int wanslan_cap = get_wans_dualwan() & WANSCAP_LAN;
105
106	// generate nvram nvram according to system setting
107	model = get_model();
108
109	switch (model) {
110	case MODEL_RTAC55U:
111	case MODEL_RTAC55UHP:
112	case MODEL_RT4GAC55U:
113		nvram_unset("vlan3hwname");
114		if ((wans_cap && wanslan_cap)
115		    )
116			nvram_set("vlan3hwname", "et0");
117		break;
118	}
119#endif
120}
121
122static void init_switch_qca(void)
123{
124#if defined(RTCONFIG_SOC_IPQ8064)
125	char *qca_nss_list[] = {
126#if defined(RTCONFIG_SWITCH_QCA8337N)
127		"qca-ssdk",
128#endif
129		"qca-nss-gmac", "qca-nss-drv",
130		"qca-nss-qdisc",
131		NULL
132	}, **qmod;
133
134	for (qmod = &qca_nss_list[0]; *qmod != NULL; ++qmod) {
135		if (module_loaded(*qmod))
136			continue;
137
138		modprobe(*qmod);
139	}
140#endif
141	char *wan0_ifname = nvram_safe_get("wan0_ifname");
142
143#if (defined(PLN12) || defined(PLAC56) || defined(PLAC66U))
144	wan0_ifname = MII_IFNAME;
145#endif
146
147	generate_switch_para();
148
149	// TODO: replace to nvram controlled procedure later
150	if (strlen(wan0_ifname)) {
151		eval("ifconfig", wan0_ifname, "hw", "ether", nvram_safe_get("et1macaddr"));
152	}
153	config_switch();
154
155#ifdef RTCONFIG_SHP
156	if (nvram_get_int("qos_enable") || nvram_get_int("lfp_disable_force")) {
157		nvram_set("lfp_disable", "1");
158	} else {
159		nvram_set("lfp_disable", "0");
160	}
161
162	if (nvram_get_int("lfp_disable") == 0) {
163		restart_lfp();
164	}
165#endif
166}
167
168void enable_jumbo_frame(void)
169{
170	int mtu = 1518;	/* default value */
171	char mtu_str[] = "9000XXX";
172
173	if (!nvram_contains_word("rc_support", "switchctrl"))
174		return;
175
176	if (nvram_get_int("jumbo_frame_enable"))
177		mtu = 9000;
178
179	sprintf(mtu_str, "%d", mtu);
180	eval("swconfig", "dev", MII_IFNAME, "set", "max_frame_size", mtu_str);
181}
182
183void init_switch(void)
184{
185	init_switch_qca();
186}
187
188char *get_lan_hwaddr(void)
189{
190	/* TODO: handle exceptional model */
191        return nvram_safe_get("et1macaddr");
192}
193
194/**
195 * Setup a VLAN.
196 * @vid:	VLAN ID
197 * @prio:	VLAN PRIO
198 * @mask:	bit31~16:	untag mask
199 * 		bit15~0:	port member mask
200 * @return:
201 * 	0:	success
202 *  otherwise:	fail
203 *
204 * bit definition of untag mask/port member mask
205 * 0:	Port 0, LANx port which is closed to WAN port in visual.
206 * 1:	Port 1
207 * 2:	Port 2
208 * 3:	Port 3
209 * 4:	Port 4, WAN port
210 * 9:	Port 9, RGMII/MII port that is used to connect CPU and WAN port.
211 * 	a. If you only have one RGMII/MII port and it is shared by WAN/LAN ports,
212 * 	   you have to define two VLAN interface for WAN/LAN ports respectively.
213 * 	b. If your switch chip choose another port as same feature, convert bit9
214 * 	   to your own port in low-level driver.
215 */
216static int __setup_vlan(int vid, int prio, unsigned int mask)
217{
218	char vlan_str[] = "4096XXX";
219	char prio_str[] = "7XXX";
220	char mask_str[] = "0x00000000XXX";
221	char *set_vlan_argv[] = { "rtkswitch", "36", vlan_str, NULL };
222	char *set_prio_argv[] = { "rtkswitch", "37", prio_str, NULL };
223	char *set_mask_argv[] = { "rtkswitch", "39", mask_str, NULL };
224
225	if (vid > 4096) {
226		_dprintf("%s: invalid vid %d\n", __func__, vid);
227		return -1;
228	}
229
230	if (prio > 7)
231		prio = 0;
232
233	_dprintf("%s: vid %d prio %d mask 0x%08x\n", __func__, vid, prio, mask);
234
235	if (vid >= 0) {
236		sprintf(vlan_str, "%d", vid);
237		_eval(set_vlan_argv, NULL, 0, NULL);
238	}
239
240	if (prio >= 0) {
241		sprintf(prio_str, "%d", prio);
242		_eval(set_prio_argv, NULL, 0, NULL);
243	}
244
245	sprintf(mask_str, "0x%08x", mask);
246	_eval(set_mask_argv, NULL, 0, NULL);
247
248	return 0;
249}
250
251int config_switch_for_first_time = 1;
252void config_switch(void)
253{
254	int model = get_model();
255	int stbport;
256	int controlrate_unknown_unicast;
257	int controlrate_unknown_multicast;
258	int controlrate_multicast;
259	int controlrate_broadcast;
260	int merge_wan_port_into_lan_ports;
261#if defined(RTAC55U)
262	int i,j,bitmask,vid[4],pri[4];
263	char temp[30];
264#endif
265	dbG("link down all ports\n");
266	eval("rtkswitch", "17");	// link down all ports
267
268	switch (model) {
269	case MODEL_RTAC55U:	/* fall through */
270	case MODEL_RTAC55UHP:	/* fall through */
271	case MODEL_RT4GAC55U:	/* fall through */
272		merge_wan_port_into_lan_ports = 1;
273		break;
274	default:
275		merge_wan_port_into_lan_ports = 0;
276	}
277
278	if (config_switch_for_first_time)
279		config_switch_for_first_time = 0;
280	else {
281		dbG("software reset\n");
282		eval("rtkswitch", "27");	// software reset
283	}
284
285#ifdef RTCONFIG_DEFAULT_AP_MODE
286	if (nvram_get_int("sw_mode") != SW_MODE_ROUTER)
287		system("rtkswitch 8 7"); // LLLLL
288	else
289#endif
290	system("rtkswitch 8 0"); // init, rtkswitch 114,115,14,15 need it
291	if (is_routing_enabled()) {
292		char parm_buf[] = "XXX";
293		stbport = atoi(nvram_safe_get("switch_stb_x"));
294		if (stbport < 0 || stbport > 6) stbport = 0;
295		dbG("ISP Profile/STB: %s/%d\n", nvram_safe_get("switch_wantag"), stbport);
296		/* stbport:	Model-independent	unifi_malaysia=1	otherwise
297		 * 		IPTV STB port		(RT-N56U)		(RT-N56U)
298		 * -----------------------------------------------------------------------
299		 *	0:	N/A			LLLLW
300		 *	1:	LAN1			LLLTW			LLLWW
301		 *	2:	LAN2			LLTLW			LLWLW
302		 *	3:	LAN3			LTLLW			LWLLW
303		 *	4:	LAN4			TLLLW			WLLLW
304		 *	5:	LAN1 + LAN2		LLTTW			LLWWW
305		 *	6:	LAN3 + LAN4		TTLLW			WWLLW
306		 */
307
308		if (!nvram_match("switch_wantag", "none")&&!nvram_match("switch_wantag", "")) {
309			//2012.03 Yau modify
310			char tmp[128];
311			char *p;
312			int voip_port = 0;
313			int t, vlan_val = -1, prio_val = -1;
314			unsigned int mask = 0;
315
316//			voip_port = atoi(nvram_safe_get("voip_port"));
317			voip_port = 3;
318			if (voip_port < 0 || voip_port > 4)
319				voip_port = 0;
320
321			/* Fixed Ports Now*/
322			stbport = 4;
323			voip_port = 3;
324
325			sprintf(tmp, "rtkswitch 29 %d", voip_port);
326			system(tmp);
327
328			if (!strncmp(nvram_safe_get("switch_wantag"), "unifi", 5)) {
329				/* Added for Unifi. Cherry Cho modified in 2011/6/28.*/
330				if(strstr(nvram_safe_get("switch_wantag"), "home")) {
331					system("rtkswitch 38 1");		/* IPTV: P0 */
332					/* Internet:	untag: P9;   port: P4, P9 */
333					__setup_vlan(500, 0, 0x02000210);
334					/* IPTV:	untag: P0;   port: P0, P4 */
335					__setup_vlan(600, 0, 0x00010011);
336				}
337				else {
338					/* No IPTV. Business package */
339					/* Internet:	untag: P9;   port: P4, P9 */
340					system("rtkswitch 38 0");
341					__setup_vlan(500, 0, 0x02000210);
342				}
343			}
344			else if (!strncmp(nvram_safe_get("switch_wantag"), "singtel", 7)) {
345				/* Added for SingTel's exStream issues. Cherry Cho modified in 2011/7/19. */
346				if(strstr(nvram_safe_get("switch_wantag"), "mio")) {
347					/* Connect Singtel MIO box to P3 */
348					system("rtkswitch 40 1");		/* admin all frames on all ports */
349					system("rtkswitch 38 3");		/* IPTV: P0  VoIP: P1 */
350					/* Internet:	untag: P9;   port: P4, P9 */
351					__setup_vlan(10, 0, 0x02000210);
352					/* VoIP:	untag: N/A;  port: P1, P4 */
353					//VoIP Port: P1 tag
354					__setup_vlan(30, 4, 0x00000012);
355				}
356				else {
357					//Connect user's own ATA to lan port and use VoIP by Singtel WAN side VoIP gateway at voip.singtel.com
358					system("rtkswitch 38 1");		/* IPTV: P0 */
359					/* Internet:	untag: P9;   port: P4, P9 */
360					__setup_vlan(10, 0, 0x02000210);
361				}
362
363				/* IPTV */
364				__setup_vlan(20, 4, 0x00010011);		/* untag: P0;   port: P0, P4 */
365			}
366			else if (!strcmp(nvram_safe_get("switch_wantag"), "m1_fiber")) {
367				//VoIP: P1 tag. Cherry Cho added in 2012/1/13.
368				system("rtkswitch 40 1");			/* admin all frames on all ports */
369				system("rtkswitch 38 2");			/* VoIP: P1  2 = 0x10 */
370				/* Internet:	untag: P9;   port: P4, P9 */
371				__setup_vlan(1103, 1, 0x02000210);
372				/* VoIP:	untag: N/A;  port: P1, P4 */
373				//VoIP Port: P1 tag
374				__setup_vlan(1107, 1, 0x00000012);
375			}
376			else if (!strcmp(nvram_safe_get("switch_wantag"), "maxis_fiber")) {
377				//VoIP: P1 tag. Cherry Cho added in 2012/11/6.
378				system("rtkswitch 40 1");			/* admin all frames on all ports */
379				system("rtkswitch 38 2");			/* VoIP: P1  2 = 0x10 */
380				/* Internet:	untag: P9;   port: P4, P9 */
381				__setup_vlan(621, 0, 0x02000210);
382				/* VoIP:	untag: N/A;  port: P1, P4 */
383				__setup_vlan(821, 0, 0x00000012);
384
385				__setup_vlan(822, 0, 0x00000012);		/* untag: N/A;  port: P1, P4 */ //VoIP Port: P1 tag
386			}
387			else if (!strcmp(nvram_safe_get("switch_wantag"), "maxis_fiber_sp")) {
388				//VoIP: P1 tag. Cherry Cho added in 2012/11/6.
389				system("rtkswitch 40 1");			/* admin all frames on all ports */
390				system("rtkswitch 38 2");			/* VoIP: P1  2 = 0x10 */
391				/* Internet:	untag: P9;   port: P4, P9 */
392				__setup_vlan(11, 0, 0x02000210);
393				/* VoIP:	untag: N/A;  port: P1, P4 */
394				//VoIP Port: P1 tag
395				__setup_vlan(14, 0, 0x00000012);
396			}
397			else {
398
399#if defined(RTAC55U)
400				/*
401 				 * switch_wan1tagid: LAN4
402 				 * switch_wan2tagid: LAN3
403 				 * switch_wan3tagid: LAN2
404 				 * switch_wan4tagid: LAN1
405 				 *
406 				 */
407				if (!strcmp(nvram_safe_get("switch_wantag"), "manual"))
408				{
409					bitmask=0; //bit3:LAN1, bit2:LAN2, bit1:LAN3, bit0:LAN4
410					for(i=0;i<4;i++)
411					{
412						memset(temp,0,sizeof(temp));
413						sprintf(temp, "switch_wan%dtagid",i+1);
414						if(strcmp(nvram_safe_get(temp), ""))
415							bitmask+=(1<<i);
416					}
417
418					memset(temp,0,sizeof(temp));
419					sprintf(temp, "rtkswitch 38 %d",bitmask);
420					system(temp);
421				}
422				else
423#endif
424				{
425				/* Cherry Cho added in 2011/7/11. */
426				/* Initialize VLAN and set Port Isolation */
427				if(strcmp(nvram_safe_get("switch_wan1tagid"), "") && strcmp(nvram_safe_get("switch_wan2tagid"), ""))
428					system("rtkswitch 38 3");		// 3 = 0x11 IPTV: P0  VoIP: P1
429				else if(strcmp(nvram_safe_get("switch_wan1tagid"), ""))
430					system("rtkswitch 38 1");		// 1 = 0x01 IPTV: P0
431				else if(strcmp(nvram_safe_get("switch_wan2tagid"), ""))
432					system("rtkswitch 38 2");		// 2 = 0x10 VoIP: P1
433				else
434					system("rtkswitch 38 0");		//No IPTV and VoIP ports
435				}
436
437
438
439				/*++ Get and set Vlan Information */
440				if(strcmp(nvram_safe_get("switch_wan0tagid"), "") != 0) {
441					// Internet on WAN (port 4)
442					if ((p = nvram_get("switch_wan0tagid")) != NULL) {
443						t = atoi(p);
444						if((t >= 2) && (t <= 4094))
445							vlan_val = t;
446					}
447
448					if((p = nvram_get("switch_wan0prio")) != NULL && *p != '\0')
449						prio_val = atoi(p);
450
451					__setup_vlan(vlan_val, prio_val, 0x02000210);
452				}
453
454#if defined(RTAC55U)
455				if (!strcmp(nvram_safe_get("switch_wantag"), "manual"))
456				{
457					for(i=0;i<4;i++)
458					{
459						vid[i]=-1; pri[i]=-1;
460						memset(temp,0,sizeof(temp));
461						sprintf(temp, "switch_wan%dtagid",i+1);
462						if(strcmp(nvram_safe_get(temp), "")!=0)
463						{
464							if ((p = nvram_get(temp)) != NULL) {
465								t = atoi(p);
466								if((t >= 2) && (t <= 4094))
467									vid[i] = t;
468							}
469
470
471							memset(temp,0,sizeof(temp));
472							sprintf(temp, "switch_wan%dprio",i+1);
473							if((p = nvram_get(temp)) != NULL && *p != '\0')
474								pri[i] = atoi(p);
475
476						}
477					}
478
479					/* LAN4: 0x00010011
480 					*  LAN3: 0x00020012
481 					*  LAN2: 0x00040014
482 					*  LAN1: 0x00080018
483 					*/
484					for(i=0;i<4;i++)
485					{
486						if(vid[i]!=-1)
487						{
488							mask=0x10;
489							for(j=0;j<4;j++)
490								if(vid[i]==vid[j])
491								{
492									mask|=(0x1<<i | 0x1<<j);
493									mask|=(0x1<<(i+16) | 0x1<<(j+16));
494								}
495							__setup_vlan(vid[i], pri[i], mask);
496						}
497
498					}
499
500				}
501				else
502#endif
503				{
504				if(strcmp(nvram_safe_get("switch_wan1tagid"), "") != 0) {
505					// IPTV on LAN4 (port 0)
506					if ((p = nvram_get("switch_wan1tagid")) != NULL) {
507						t = atoi(p);
508						if((t >= 2) && (t <= 4094))
509							vlan_val = t;
510					}
511
512					if((p = nvram_get("switch_wan1prio")) != NULL && *p != '\0')
513						prio_val = atoi(p);
514
515					if(!strcmp(nvram_safe_get("switch_wan1tagid"), nvram_safe_get("switch_wan2tagid")))
516						mask = 0x00030013;	//IPTV=VOIP
517					else
518						mask = 0x00010011;	//IPTV Port: P0 untag 65553 = 0x10 011
519
520					__setup_vlan(vlan_val, prio_val, mask);
521				}
522
523				if(strcmp(nvram_safe_get("switch_wan2tagid"), "") != 0) {
524					// VoIP on LAN3 (port 1)
525					if ((p = nvram_get("switch_wan2tagid")) != NULL) {
526						t = atoi(p);
527						if((t >= 2) && (t <= 4094))
528							vlan_val = t;
529					}
530
531					if((p = nvram_get("switch_wan2prio")) != NULL && *p != '\0')
532						prio_val = atoi(p);
533
534					if(!strcmp(nvram_safe_get("switch_wan1tagid"), nvram_safe_get("switch_wan2tagid")))
535						mask = 0x00030013;	//IPTV=VOIP
536					else
537						mask = 0x00020012;	//VoIP Port: P1 untag
538
539					__setup_vlan(vlan_val, prio_val, mask);
540				}
541
542				}
543
544
545			}
546		}
547		else
548		{
549			sprintf(parm_buf, "%d", stbport);
550			if (stbport)
551				eval("rtkswitch", "8", parm_buf);
552		}
553
554		/* unknown unicast storm control */
555		if (!nvram_get("switch_ctrlrate_unknown_unicast"))
556			controlrate_unknown_unicast = 0;
557		else
558			controlrate_unknown_unicast = atoi(nvram_get("switch_ctrlrate_unknown_unicast"));
559		if (controlrate_unknown_unicast < 0 || controlrate_unknown_unicast > 1024)
560			controlrate_unknown_unicast = 0;
561		if (controlrate_unknown_unicast)
562		{
563			sprintf(parm_buf, "%d", controlrate_unknown_unicast);
564			eval("rtkswitch", "22", parm_buf);
565		}
566
567		/* unknown multicast storm control */
568		if (!nvram_get("switch_ctrlrate_unknown_multicast"))
569			controlrate_unknown_multicast = 0;
570		else
571			controlrate_unknown_multicast = atoi(nvram_get("switch_ctrlrate_unknown_multicast"));
572		if (controlrate_unknown_multicast < 0 || controlrate_unknown_multicast > 1024)
573			controlrate_unknown_multicast = 0;
574		if (controlrate_unknown_multicast) {
575			sprintf(parm_buf, "%d", controlrate_unknown_multicast);
576			eval("rtkswitch", "23", parm_buf);
577		}
578
579		/* multicast storm control */
580		if (!nvram_get("switch_ctrlrate_multicast"))
581			controlrate_multicast = 0;
582		else
583			controlrate_multicast = atoi(nvram_get("switch_ctrlrate_multicast"));
584		if (controlrate_multicast < 0 || controlrate_multicast > 1024)
585			controlrate_multicast = 0;
586		if (controlrate_multicast)
587		{
588			sprintf(parm_buf, "%d", controlrate_multicast);
589			eval("rtkswitch", "24", parm_buf);
590		}
591
592		/* broadcast storm control */
593		if (!nvram_get("switch_ctrlrate_broadcast"))
594			controlrate_broadcast = 0;
595		else
596			controlrate_broadcast = atoi(nvram_get("switch_ctrlrate_broadcast"));
597		if (controlrate_broadcast < 0 || controlrate_broadcast > 1024)
598			controlrate_broadcast = 0;
599		if (controlrate_broadcast) {
600			sprintf(parm_buf, "%d", controlrate_broadcast);
601			eval("rtkswitch", "25", parm_buf);
602		}
603	}
604	else if (is_apmode_enabled())
605	{
606		if (merge_wan_port_into_lan_ports)
607			eval("rtkswitch", "8", "100");
608	}
609#if defined(RTCONFIG_WIRELESSREPEATER) && defined(RTCONFIG_PROXYSTA)
610	else if (mediabridge_mode())
611	{
612	}
613#endif
614
615	if (is_routing_enabled() || is_apmode_enabled()) {
616		dbG("link up wan port(s)\n");
617		eval("rtkswitch", "114");	// link up wan port(s)
618	}
619
620	enable_jumbo_frame();
621
622#if defined(RTCONFIG_BLINK_LED)
623	if (is_swports_bled("led_lan_gpio")) {
624		update_swports_bled("led_lan_gpio", nvram_get_int("lanports_mask"));
625	}
626	if (is_swports_bled("led_wan_gpio")) {
627		update_swports_bled("led_wan_gpio", nvram_get_int("wanports_mask"));
628	}
629#endif
630}
631
632int switch_exist(void)
633{
634	FILE *fp;
635	char cmd[64], buf[512];
636	int rlen;
637
638	sprintf(cmd, "swconfig dev %s port 0 get link", MII_IFNAME);
639	if ((fp = popen(cmd, "r")) == NULL) {
640		return 0;
641	}
642	rlen = fread(buf, 1, sizeof(buf), fp);
643	pclose(fp);
644	if (rlen <= 1)
645		return 0;
646
647	buf[rlen-1] = '\0';
648	if (strstr(buf, "link:up speed:1000"))
649		return 1;
650	return 0;
651}
652
653/**
654 * Low level function to load QCA WiFi driver.
655 * @testmode:	if true, load WiFi driver as test mode which is required in ATE mode.
656 */
657static void __load_wifi_driver(int testmode)
658{
659	char country[FACTORY_COUNTRY_CODE_LEN + 1], code_str[6];
660	const char *umac_params[] = {
661		"vow_config", "OL_ACBKMinfree", "OL_ACBEMinfree", "OL_ACVIMinfree",
662		"OL_ACVOMinfree", "ar900b_emu", "frac", "intval", "atf_mode",
663		"fw_dump_options", "enableuartprint", "ar900b_20_targ_clk",
664		"max_descs", "qwrap_enable", "otp_mod_param", "max_active_peers",
665		"enable_smart_antenna",
666#if defined(RTCONFIG_WIFI_QCA9990_QCA9990) || defined(RTCONFIG_WIFI_QCA9994_QCA9994)
667		"nss_wifi_olcfg",
668#endif
669		NULL
670	}, **up;
671	int i, code;
672	char param[512], *s = &param[0], umac_nv[64], *val;
673	char *argv[30] = {
674		"modprobe", "-s", NULL
675	}, **v;
676	struct load_wifi_kmod_seq_s *p = &load_wifi_kmod_seq[0];
677
678	for (i = 0, p = &load_wifi_kmod_seq[i]; i < ARRAY_SIZE(load_wifi_kmod_seq); ++i, ++p) {
679		if (module_loaded(p->kmod_name))
680			continue;
681
682		v = &argv[2];
683		*v++ = p->kmod_name;
684		*param = '\0';
685		s = &param[0];
686#if defined(RTCONFIG_WIFI_QCA9557_QCA9882) || defined(RTCONFIG_QCA953X) || defined(RTCONFIG_QCA956X)
687		if (!strcmp(p->kmod_name, "ath_hal")) {
688			int ce_level = nvram_get_int("ce_level");
689			if (ce_level <= 0)
690				ce_level = 0xce;
691
692			*v++ = s;
693			s += sprintf(s, "ce_level=%d", ce_level);
694			s++;
695		}
696#endif
697		if (!strcmp(p->kmod_name, "umac")) {
698			if (!testmode) {
699				*v++ = "msienable=0";	/* FIXME: Enable MSI interrupt in future. */
700				for (up = &umac_params[0]; *up != NULL; up++) {
701					snprintf(umac_nv, sizeof(umac_nv), "qca_%s", *up);
702					if (!(val = nvram_get(umac_nv)))
703						continue;
704					*v++ = s;
705					s += sprintf(s, "%s=%s", *up, val);
706					s++;
707				}
708			}
709#if defined(RTCONFIG_WIFI_QCA9990_QCA9990) || defined(RTCONFIG_WIFI_QCA9994_QCA9994)
710			else {
711				*v++ = "testmode=1";
712				*v++ = "ahbskip=1";
713			}
714#endif
715		}
716
717#if defined(RTCONFIG_WIFI_QCA9990_QCA9990) || defined(RTCONFIG_WIFI_QCA9994_QCA9994)
718		if (!strcmp(p->kmod_name, "adf")) {
719			if (nvram_get("qca_prealloc_disabled") != NULL) {
720				*v++ = s;
721				s += sprintf(s, "prealloc_disabled=%d", nvram_get_int("qca_prealloc_disabled"));
722				s++;
723			}
724		}
725#endif
726
727		*v++ = NULL;
728		_eval(argv, NULL, 0, NULL);
729
730		if (p->load_sleep)
731			sleep(p->load_sleep);
732	}
733
734	if (!testmode) {
735		//sleep(2);
736#if defined(RTCONFIG_WIFI_QCA9557_QCA9882) || defined(RTCONFIG_QCA953X) || defined(RTCONFIG_QCA956X)
737		eval("iwpriv", "wifi0", "disablestats", "0");
738		eval("iwpriv", "wifi1", "enable_ol_stats", "0");
739#elif defined(RTCONFIG_WIFI_QCA9990_QCA9990) || defined(RTCONFIG_WIFI_QCA9994_QCA9994)
740		eval("iwpriv", "wifi0", "enable_ol_stats", "0");
741		eval("iwpriv", "wifi1", "enable_ol_stats", "0");
742#endif
743
744		strncpy(country, nvram_safe_get("wl0_country_code"), FACTORY_COUNTRY_CODE_LEN);
745		country[FACTORY_COUNTRY_CODE_LEN] = '\0';
746		code = country_to_code(country, 2);
747		if (code < 0)
748			code = country_to_code("DB", 2);
749		sprintf(code_str, "%d", code);
750		eval("iwpriv", "wifi0", "setCountryID", code_str);
751
752		strncpy(country, nvram_safe_get("wl1_country_code"), FACTORY_COUNTRY_CODE_LEN);
753		country[FACTORY_COUNTRY_CODE_LEN] = '\0';
754		code = country_to_code(country, 5);
755		if (code < 0)
756			code = country_to_code("DB", 5);
757		sprintf(code_str, "%d", code);
758		eval("iwpriv", "wifi1", "setCountryID", code_str);
759
760#if defined(RTAC88Q)
761		set_irq_smp_affinity(68, 1);	/* wifi0 = 2G ==> CPU0 */
762		set_irq_smp_affinity(90, 2);	/* wifi1 = 5G ==> CPU1 */
763#endif
764#if defined(RTCONFIG_SOC_IPQ8064)
765		tweak_wifi_ps(VPHY_2G);
766		tweak_wifi_ps(VPHY_5G);
767#endif
768	}
769}
770
771void load_wifi_driver(void)
772{
773	__load_wifi_driver(0);
774}
775
776void load_testmode_wifi_driver(void)
777{
778	__load_wifi_driver(1);
779}
780
781void set_uuid(void)
782{
783	int len;
784	char *p, uuid[60];
785	FILE *fp;
786
787	fp = popen("cat /proc/sys/kernel/random/uuid", "r");
788	 if (fp) {
789	    memset(uuid, 0, sizeof(uuid));
790	    fread(uuid, 1, sizeof(uuid), fp);
791	    for (len = strlen(uuid), p = uuid; len > 0; len--, p++) {
792		    if (isxdigit(*p) || *p == '-')
793			    continue;
794		    *p = '\0';
795		    break;
796	    }
797	    nvram_set("uuid",uuid);
798	    pclose(fp);
799	 }
800}
801
802static int create_node=0;
803void init_wl(void)
804{
805   	int unit;
806	char *p, *ifname;
807	char *wl_ifnames;
808	int wlc_band;
809	if(!create_node)
810	{
811		load_wifi_driver();
812		sleep(2);
813
814		dbG("init_wl:create wi node\n");
815		if ((wl_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL)
816		{
817			p = wl_ifnames;
818			while ((ifname = strsep(&p, " ")) != NULL) {
819				while (*ifname == ' ') ++ifname;
820				if (*ifname == 0) break;
821
822				//create ath00x & ath10x
823				 if(strncmp(ifname,WIF_2G,strlen(WIF_2G))==0)
824					unit=0;
825				 else if(strncmp(ifname,WIF_5G,strlen(WIF_5G))==0)
826					unit=1;
827			 	 else
828			   		unit=-99;
829			         if(unit>=0)
830			   	 {
831					dbG("\ncreate a wifi node %s from %s\n", ifname, get_vphyifname(unit));
832					doSystem("wlanconfig %s create wlandev %s wlanmode ap", ifname, get_vphyifname(unit));
833   					sleep(1);
834				 }
835			}
836			free(wl_ifnames);
837		}
838		create_node=1;
839#ifdef RTCONFIG_WIRELESSREPEATER
840		if(nvram_get_int("sw_mode")==SW_MODE_REPEATER)
841		{
842		  	wlc_band=nvram_get_int("wlc_band");
843			doSystem("wlanconfig %s create wlandev %s wlanmode sta nosbeacon",
844				get_staifname(wlc_band), get_vphyifname(wlc_band));
845		}
846#endif
847	}
848}
849
850void fini_wl(void)
851{
852	int wlc_band;
853	char wif[256];
854	int unit = -1, sunit = 0;
855	unsigned int m;	/* bit0~3: 2G, bit4~7: 5G */
856	char pid_path[] = "/var/run/hostapd_athXXX.pidYYYYYY";
857	char path[] = "/sys/class/net/ath001XXXXXX";
858	int i;
859	struct load_wifi_kmod_seq_s *wp;
860
861	dbG("fini_wl:destroy wi node\n");
862	for (i = 0, unit = 0, sunit = 0, m = 0xFF; m > 0; ++i, ++sunit, m >>= 1) {
863		if (i == 4) {
864			unit = 1;
865			sunit -= 4;
866		}
867		__get_wlifname(unit, sunit, wif);
868		sprintf(pid_path, "/var/run/hostapd_%s.pid", wif);
869		if (f_exists(pid_path))
870			kill_pidfile_tk(pid_path);
871		sprintf(path, "/sys/class/net/%s", wif);
872		if (d_exists(path)) {
873			eval("ifconfig", wif, "down");
874			eval("wlanconfig", wif, "destroy");
875		}
876	}
877
878#ifdef RTCONFIG_WIRELESSREPEATER
879		if(nvram_get_int("sw_mode")==SW_MODE_REPEATER)
880		{
881		  	wlc_band=nvram_get_int("wlc_band");
882			doSystem("wlanconfig sta%d destroy",wlc_band);
883		}
884#endif
885	create_node=0;
886
887	eval("ifconfig", (char*) VPHY_2G, "down");
888	eval("ifconfig", (char*) VPHY_5G, "down");
889	for (i = ARRAY_SIZE(load_wifi_kmod_seq)-1, wp = &load_wifi_kmod_seq[i]; i >= 0; --i, --wp) {
890		if (!module_loaded(wp->kmod_name))
891			continue;
892
893		modprobe_r(wp->kmod_name);
894		if (wp->remove_sleep)
895			sleep(wp->remove_sleep);
896	}
897}
898
899static void chk_valid_country_code(char *country_code)
900{
901	if ((unsigned char)country_code[0]!=0xff)
902	{
903		//
904	}
905	else
906	{
907		strcpy(country_code, "DB");
908	}
909}
910
911void init_syspara(void)
912{
913	unsigned char buffer[16];
914	unsigned char *dst;
915	unsigned int bytes;
916	char macaddr[] = "00:11:22:33:44:55";
917	char macaddr2[] = "00:11:22:33:44:58";
918	char country_code[FACTORY_COUNTRY_CODE_LEN+1];
919	char pin[9];
920	char productid[13];
921	char fwver[8];
922	char blver[20];
923#ifdef RTCONFIG_ODMPID
924	char modelname[16];
925#endif
926
927	nvram_set("buildno", rt_serialno);
928	nvram_set("extendno", rt_extendno);
929	nvram_set("buildinfo", rt_buildinfo);
930	nvram_set("swpjverno", rt_swpjverno);
931
932	/* /dev/mtd/2, RF parameters, starts from 0x40000 */
933	dst = buffer;
934	bytes = 6;
935	memset(buffer, 0, sizeof(buffer));
936	memset(country_code, 0, sizeof(country_code));
937	memset(pin, 0, sizeof(pin));
938	memset(productid, 0, sizeof(productid));
939	memset(fwver, 0, sizeof(fwver));
940
941	if (FRead(dst, OFFSET_MAC_ADDR_2G, bytes) < 0) {  // ET0/WAN is same as 2.4G
942		_dprintf("READ MAC address 2G: Out of scope\n");
943	} else {
944		if (buffer[0] != 0xff)
945			ether_etoa(buffer, macaddr);
946	}
947
948	if (FRead(dst, OFFSET_MAC_ADDR, bytes) < 0) { // ET1/LAN is same as 5G
949		_dprintf("READ MAC address : Out of scope\n");
950	} else {
951		if (buffer[0] != 0xff)
952			ether_etoa(buffer, macaddr2);
953	}
954
955	if (!mssid_mac_validate(macaddr) || !mssid_mac_validate(macaddr2))
956		nvram_set("wl_mssid", "0");
957	else
958		nvram_set("wl_mssid", "1");
959
960#if 0	// single band
961	nvram_set("et0macaddr", macaddr);
962	nvram_set("et1macaddr", macaddr);
963#else
964	//TODO: separate for different chipset solution
965	nvram_set("et0macaddr", macaddr);
966#if (defined(PLN12) || defined(PLAC56))
967	nvram_set("et1macaddr", macaddr);
968#else
969	nvram_set("et1macaddr", macaddr2);
970#endif
971#endif
972
973	dst = (unsigned char*) country_code;
974	bytes = FACTORY_COUNTRY_CODE_LEN;
975	if (FRead(dst, OFFSET_COUNTRY_CODE, bytes)<0)
976	{
977		_dprintf("READ ASUS country code: Out of scope\n");
978		nvram_set("wl_country_code", "DB");
979	}
980	else
981	{
982		dst[FACTORY_COUNTRY_CODE_LEN]='\0';
983		chk_valid_country_code(country_code);
984		nvram_set("wl_country_code", country_code);
985		nvram_set("wl0_country_code", country_code);
986		nvram_set("wl1_country_code", country_code);
987	}
988
989	/* reserved for Ralink. used as ASUS pin code. */
990	dst = (char *)pin;
991	bytes = 8;
992	if (FRead(dst, OFFSET_PIN_CODE, bytes) < 0) {
993		_dprintf("READ ASUS pin code: Out of scope\n");
994		nvram_set("wl_pin_code", "");
995	} else {
996		if ((unsigned char)pin[0] != 0xff)
997			nvram_set("secret_code", pin);
998		else
999			nvram_set("secret_code", "12345670");
1000	}
1001
1002	dst = buffer;
1003	bytes = 16;
1004	if (linuxRead(dst, 0x20, bytes) < 0) {	/* The "linux" MTD partition, offset 0x20. */
1005		fprintf(stderr, "READ firmware header: Out of scope\n");
1006		nvram_set("productid", "unknown");
1007		nvram_set("firmver", "unknown");
1008	} else {
1009		strncpy(productid, buffer + 4, 12);
1010		productid[12] = 0;
1011		sprintf(fwver, "%d.%d.%d.%d", buffer[0], buffer[1], buffer[2],
1012			buffer[3]);
1013		nvram_set("productid", trim_r(productid));
1014		nvram_set("firmver", trim_r(fwver));
1015	}
1016
1017#if defined(RTCONFIG_TCODE)
1018	/* Territory code */
1019	memset(buffer, 0, sizeof(buffer));
1020	if (FRead(buffer, OFFSET_TERRITORY_CODE, 5) < 0) {
1021		_dprintf("READ ASUS territory code: Out of scope\n");
1022		nvram_unset("territory_code");
1023	} else {
1024		/* [A-Z][A-Z]/[0-9][0-9] */
1025		if (buffer[2] != '/' ||
1026		    !isupper(buffer[0]) || !isupper(buffer[1]) ||
1027		    !isdigit(buffer[3]) || !isdigit(buffer[4]))
1028		{
1029			nvram_unset("territory_code");
1030		} else {
1031			nvram_set("territory_code", buffer);
1032		}
1033	}
1034
1035	/* PSK */
1036	memset(buffer, 0, sizeof(buffer));
1037	if (FRead(buffer, OFFSET_PSK, 14) < 0) {
1038		_dprintf("READ ASUS PSK: Out of scope\n");
1039		nvram_set("wifi_psk", "");
1040	} else {
1041		if (buffer[0] == 0xff)
1042			nvram_set("wifi_psk", "");
1043		else
1044			nvram_set("wifi_psk", buffer);
1045	}
1046#endif
1047
1048	memset(buffer, 0, sizeof(buffer));
1049	FRead(buffer, OFFSET_BOOT_VER, 4);
1050	sprintf(blver, "%s-0%c-0%c-0%c-0%c", trim_r(productid), buffer[0],
1051		buffer[1], buffer[2], buffer[3]);
1052	nvram_set("blver", trim_r(blver));
1053
1054	_dprintf("bootloader version: %s\n", nvram_safe_get("blver"));
1055	_dprintf("firmware version: %s\n", nvram_safe_get("firmver"));
1056
1057	nvram_set("wl1_txbf_en", "0");
1058
1059#ifdef RTCONFIG_ODMPID
1060	FRead(modelname, OFFSET_ODMPID, sizeof(modelname));
1061	modelname[sizeof(modelname) - 1] = '\0';
1062	if (modelname[0] != 0 && (unsigned char)(modelname[0]) != 0xff
1063	    && is_valid_hostname(modelname)
1064	    && strcmp(modelname, "ASUS")) {
1065		nvram_set("odmpid", modelname);
1066	} else
1067#endif
1068		nvram_unset("odmpid");
1069
1070	nvram_set("firmver", rt_version);
1071	nvram_set("productid", rt_buildname);
1072
1073#if !defined(RTCONFIG_TCODE) // move the verification later bcz TCODE/LOC
1074	verify_ctl_table();
1075#endif
1076
1077#ifdef RTCONFIG_QCA_PLC_UTILS
1078	getPLC_MAC(macaddr);
1079	nvram_set("plc_macaddr", macaddr);
1080#endif
1081
1082#ifdef RTCONFIG_DEFAULT_AP_MODE
1083	char dhcp = '0';
1084
1085	if (FRead(&dhcp, OFFSET_FORCE_DISABLE_DHCP, 1) < 0) {
1086		_dprintf("READ Disable DHCP: Out of scope\n");
1087	} else {
1088		if (dhcp == '1')
1089			nvram_set("ate_flag", "1");
1090		else
1091			nvram_set("ate_flag", "0");
1092	}
1093#endif
1094}
1095
1096#ifdef RTCONFIG_ATEUSB3_FORCE
1097void post_syspara(void)
1098{
1099	unsigned char buffer[16];
1100	buffer[0]='0';
1101	if (FRead(&buffer[0], OFFSET_FORCE_USB3, 1) < 0) {
1102		fprintf(stderr, "READ FORCE_USB3 address: Out of scope\n");
1103	}
1104	if (buffer[0]=='1')
1105		nvram_set("usb_usb3", "1");
1106}
1107#endif
1108
1109void generate_wl_para(int unit, int subunit)
1110{
1111}
1112
1113char *get_staifname(int band)
1114{
1115	return (char*) ((!band)? STA_2G:STA_5G);
1116}
1117
1118char *get_vphyifname(int band)
1119{
1120	return (char*) ((!band)? VPHY_2G:VPHY_5G);
1121}
1122
1123char *__get_wlifname(int band, int subunit, char *buf)
1124{
1125	if (!buf)
1126		return buf;
1127
1128	if (!subunit)
1129		strcpy(buf, (!band)? WIF_2G:WIF_5G);
1130	else
1131		sprintf(buf, "%s0%d", (!band)? WIF_2G:WIF_5G, subunit);
1132
1133	return buf;
1134}
1135
1136int get_wlsubnet(int band, const char *ifname)
1137{
1138	int subnet, sidx;
1139	char buf[32];
1140
1141	for (subnet = 0, sidx = 0; subnet < MAX_NO_MSSID; subnet++)
1142	{
1143		if(!nvram_match(wl_nvname("bss_enabled", band, subnet), "1"))
1144			continue;
1145
1146		if(strcmp(ifname, __get_wlifname(band, sidx, buf)) == 0)
1147			return subnet;
1148
1149		sidx++;
1150	}
1151	return -1;
1152}
1153
1154#if defined(RTCONFIG_SOC_QCA9557) || defined(RTCONFIG_QCA953X) || defined(RTCONFIG_QCA956X)
1155// only qca solution can reload it dynamically
1156// only happened when qca_sfe=1
1157// only loaded when unloaded, and unloaded when loaded
1158// in restart_firewall for fw_pt_l2tp/fw_pt_ipsec
1159// in restart_qos for qos_enable
1160// in restart_wireless for wlx_mrate_x, etc
1161void reinit_sfe(int unit)
1162{
1163	int prim_unit = wan_primary_ifunit();
1164	int act = 1,i;	/* -1/0/otherwise: ignore/remove sfe/load sfe */
1165	struct load_nat_accel_kmod_seq_s *p = &load_nat_accel_kmod_seq[0];
1166#if defined(RTCONFIG_DUALWAN)
1167	int nat_x = -1, l, t, link_wan = 1, link_wans_lan = 1;
1168	int wans_cap = get_wans_dualwan() & WANSCAP_WAN;
1169	int wanslan_cap = get_wans_dualwan() & WANSCAP_LAN;
1170	char nat_x_str[] = "wanX_nat_xXXXXXX";
1171#endif
1172	if (!nvram_get_int("qca_sfe"))
1173		return;
1174
1175	/* If QoS is enabled, disable sfe. */
1176	if (nvram_get_int("qos_enable") == 1 && nvram_get_int("qos_type") != 1)
1177		act = 0;
1178
1179	if (act > 0 && !nvram_match("switch_wantag", "none") && !nvram_match("switch_wantag", ""))
1180		act = 0;
1181
1182	if (act > 0) {
1183#if defined(RTCONFIG_DUALWAN)
1184		if (unit < 0 || unit > WAN_UNIT_SECOND) {
1185			if ((wans_cap && wanslan_cap) ||
1186			    (wanslan_cap && (!nvram_match("switch_wantag", "none") && !nvram_match("switch_wantag", "")))
1187			   )
1188				act = 0;
1189		} else {
1190			sprintf(nat_x_str, "wan%d_nat_x", unit);
1191			nat_x = nvram_get_int(nat_x_str);
1192			if (unit == prim_unit && !nat_x)
1193				act = 0;
1194			else if ((wans_cap && wanslan_cap) ||
1195				 (wanslan_cap && (!nvram_match("switch_wantag", "none") && !nvram_match("switch_wantag", "")))
1196				)
1197				act = 0;
1198			else if (unit != prim_unit)
1199				act = -1;
1200		}
1201#else
1202		if (!is_nat_enabled())
1203			act = 0;
1204#endif
1205	}
1206
1207	if (act > 0) {
1208#if defined(RTCONFIG_DUALWAN)
1209		if (unit < 0 || unit > WAN_UNIT_SECOND || nvram_match("wans_mode", "lb")) {
1210			if (get_wans_dualwan() & WANSCAP_USB)
1211				act = 0;
1212		} else {
1213			if (unit == prim_unit && get_dualwan_by_unit(unit) == WANS_DUALWAN_IF_USB)
1214				act = 0;
1215		}
1216#else
1217		if (dualwan_unit__usbif(prim_unit))
1218			act = 0;
1219#endif
1220	}
1221
1222#if defined(RTCONFIG_DUALWAN)
1223	if (act != 0 &&
1224	    ((wans_cap && wanslan_cap) || (wanslan_cap && (!nvram_match("switch_wantag", "none") && !nvram_match("switch_wantag", ""))))
1225	   )
1226	{
1227		/* If WANS_LAN and WAN is enabled, WANS_LAN is link-up and WAN is not link-up, hw_nat MUST be removed.
1228		 * If hw_nat exists in such scenario, LAN PC can't connect to Internet through WANS_LAN correctly.
1229		 *
1230		 * FIXME:
1231		 * If generic IPTV feature is enabled, STB port and VoIP port are recognized as WAN port(s).
1232		 * In such case, we don't know whether real WAN port is link-up/down.
1233		 * Thus, if WAN is link-up and primary unit is not WAN, assume WAN is link-down.
1234		 */
1235		for (i = WAN_UNIT_FIRST; i < WAN_UNIT_MAX; ++i) {
1236			if ((t = get_dualwan_by_unit(i)) == WANS_DUALWAN_IF_USB)
1237				continue;
1238
1239			l = wanport_status(i);
1240			switch (t) {
1241			case WANS_DUALWAN_IF_WAN:
1242				link_wan = l && (i == prim_unit);
1243				break;
1244			case WANS_DUALWAN_IF_DSL:
1245				link_wan = l;
1246				break;
1247			case WANS_DUALWAN_IF_LAN:
1248				link_wans_lan = l;
1249				break;
1250			default:
1251				_dprintf("%s: Unknown WAN type %d\n", __func__, t);
1252			}
1253		}
1254
1255		if (!link_wan && link_wans_lan)
1256			act = 0;
1257	}
1258
1259	_dprintf("%s:DUALWAN: unit %d,%d type %d iptv [%s] nat_x %d qos %d wans_mode %s link %d,%d: action %d.\n",
1260		__func__, unit, prim_unit, get_dualwan_by_unit(unit), nvram_safe_get("switch_wantag"), nat_x,
1261		nvram_get_int("qos_enable"), nvram_safe_get("wans_mode"),
1262		link_wan, link_wans_lan, act);
1263#else
1264	_dprintf("%s:WAN: unit %d,%d type %d nat_x %d qos %d: action %d.\n",
1265		__func__, unit, prim_unit, get_dualwan_by_unit(unit),
1266		nvram_get_int("wan0_nat_x"), nvram_get_int("qos_enable"), act);
1267#endif
1268
1269	if (act < 0)
1270		return;
1271
1272	for (i = 0, p = &load_nat_accel_kmod_seq[i]; i < ARRAY_SIZE(load_nat_accel_kmod_seq); ++i, ++p) {
1273		if (!act) {
1274			/* remove sfe */
1275			if (!module_loaded(p->kmod_name))
1276				continue;
1277
1278			modprobe_r(p->kmod_name);
1279			if (p->remove_sleep)
1280				sleep(p->load_sleep);
1281
1282		} else {
1283			/* load sfe */
1284			if (module_loaded(p->kmod_name))
1285				continue;
1286
1287			modprobe(p->kmod_name);
1288			if (p->load_sleep)
1289				sleep(p->load_sleep);
1290		}
1291	}
1292}
1293#endif	/* RTCONFIG_SOC_QCA9557 || defined(RTCONFIG_QCA953X) || defined(RTCONFIG_QCA956X) */
1294
1295char *get_wlifname(int unit, int subunit, int subunit_x, char *buf)
1296{
1297#if 1 //eric++
1298	char wifbuf[32];
1299	char prefix[] = "wlXXXXXX_", tmp[100];
1300#if defined(RTCONFIG_WIRELESSREPEATER)
1301	if (nvram_get_int("sw_mode") == SW_MODE_REPEATER
1302	    && nvram_get_int("wlc_band") == unit && subunit == 1) {
1303		strcpy(buf, get_staifname(unit));
1304	} else
1305#endif /* RTCONFIG_WIRELESSREPEATER */
1306	{
1307		__get_wlifname(unit, 0, wifbuf);
1308		snprintf(prefix, sizeof(prefix), "wl%d.%d_", unit, subunit);
1309		if (nvram_match(strcat_r(prefix, "bss_enabled", tmp), "1"))
1310			sprintf(buf, "%s0%d", wifbuf, subunit_x);
1311		else
1312			sprintf(buf, "%s", "");
1313	}
1314	return buf;
1315#else
1316	return __get_wlifname(unit, subunit, buf);
1317#endif //eric++
1318}
1319
1320int wl_exist(char *ifname, int band)
1321{
1322	int ret = 0;
1323	ret = eval("iwpriv", ifname, "get_driver_caps");
1324	_dprintf("eval(iwpriv, %s, get_driver_caps) ret(%d)\n", ifname, ret);
1325	return (ret==0);
1326}
1327
1328void
1329set_wan_tag(char *interface) {
1330	int model, wan_vid; //, iptv_vid, voip_vid, wan_prio, iptv_prio, voip_prio;
1331	char wan_dev[10], port_id[7];
1332
1333	model = get_model();
1334	wan_vid = nvram_get_int("switch_wan0tagid");
1335//	iptv_vid = nvram_get_int("switch_wan1tagid");
1336//	voip_vid = nvram_get_int("switch_wan2tagid");
1337//	wan_prio = nvram_get_int("switch_wan0prio");
1338//	iptv_prio = nvram_get_int("switch_wan1prio");
1339//	voip_prio = nvram_get_int("switch_wan2prio");
1340
1341	sprintf(wan_dev, "vlan%d", wan_vid);
1342
1343	switch(model) {
1344	case MODEL_RTAC55U:
1345	case MODEL_RTAC55UHP:
1346	case MODEL_RT4GAC55U:
1347		ifconfig(interface, IFUP, 0, 0);
1348		if(wan_vid) { /* config wan port */
1349			eval("vconfig", "rem", "vlan2");
1350			sprintf(port_id, "%d", wan_vid);
1351			eval("vconfig", "add", interface, port_id);
1352		}
1353		/* Set Wan port PRIO */
1354		if(nvram_invmatch("switch_wan0prio", "0"))
1355			eval("vconfig", "set_egress_map", wan_dev, "0", nvram_get("switch_wan0prio"));
1356		break;
1357	}
1358}
1359