1/* 2 * IEEE 802.1Q Virtual LAN services 3 * 4 * Copyright 2004, Broadcom Corporation 5 * All Rights Reserved. 6 * 7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 11 * 12 * $Id: vlan.c,v 1.1.1.1 2008/10/15 03:28:48 james26_jang Exp $ 13 */ 14#ifdef WL500GX 15#include <stdio.h> 16#include <stdlib.h> 17#include <errno.h> 18#include <syslog.h> 19#include <ctype.h> 20#include <string.h> 21#include <unistd.h> 22#include <sys/stat.h> 23#include <sys/ioctl.h> 24#include <sys/types.h> 25#include <sys/socket.h> 26#include <net/if.h> 27#include <netinet/in.h> 28#include <arpa/inet.h> 29#include <net/if_arp.h> 30#include <bcmnvram.h> 31#include <netconf.h> 32#include <shutils.h> 33#include <rc.h> 34#include <errno.h> 35#include <stdio.h> 36#include <stdlib.h> 37#include <unistd.h> 38#include <fcntl.h> 39#include <strings.h> 40#include <sys/ioctl.h> 41#include <../../linux/linux/include/linux/if_vlan.h> 42#include <linux/sockios.h> 43#include <string.h> 44#include <sys/socket.h> 45#include <sys/types.h> 46#define uint32 unsigned long 47#define uint unsigned int 48#define uint8 unsigned char 49#define uint64 unsigned long long 50#include <swmod.h> 51#include <swapi.h> 52#include <nvports.h> 53#include <bcmdevs.h> 54#include <nvparse.h> 55extern int wan_valid(char *ifname); 56 57 58/* VLAN Descriptors, per-board or platform setting */ 59struct vlan_board_s{ 60 char* bd_name; 61 char* bd_desc; 62 int numports; 63 int wan_port; 64 int lan_port_start; 65 int lan_port_end; 66 int vlan_devno; 67 int wan_vlan; 68 int lan_vlan; 69} vlan_boards[] = { 70 {"reference board", 71 "Broadcom Sentry5", 72 BCM_NUM_PORTS, 73 BCM_WAN_PORT, 74 BCM_LAN_MIN_PORT, 75 BCM_LAN_MAX_PORT, 76 0, 77 BCM_DEF_WAN_VLAN, 78 BCM_DEF_LAN_VLAN}, 79}; 80int vlan_configured = 0; 81int brcm_tag_driver_enabled = 0; 82#define IFUP (IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST) 83 84 85static void 86enable_wan_port(void) 87{ 88 char val8 = 0; 89 90 if ((bcm_api_init()) < 0) 91 return; 92 93 /* enable physical WAN port */ 94 bcm_write_reg(0, ROBO_CTRL_PAGE, ROBO_PORT0_CTRL, &val8, 1); 95 96 bcm_api_deinit(); 97} 98 99static int 100vlan_configure(void) 101 102{ 103 104 char *vlan_enable = nvram_safe_get("vlan_enable"); 105 char *lan_ifname = nvram_safe_get("lan_ifname"); 106 char *lan_ifnames = nvram_safe_get("lan_ifnames"); 107 char *wan_hwaddr = nvram_safe_get("wan0_hwaddr"); //Thanks for Oleg 108 char *wan_ifname = NULL; 109 char *wan_proto; 110 char tmp[100], prefix[] = "wanXXXXXXXXXX_"; 111 char *restore_lan_ifname = nvram_safe_get("restore_lan_ifname"); 112 char *restore_lan_ifnames = nvram_safe_get("restore_lan_ifnames"); 113 char *restore_wan_ifname = nvram_safe_get("restore_wan_ifname"); 114 char *restore_wan_hwaddr = nvram_safe_get("restore_wan_hwaddr"); 115 char *mibac_enable = nvram_safe_get("mibac_enable"); 116 char *mibac_interval = nvram_safe_get("mibac_interval"); 117 char *brcmtag_enable = nvram_safe_get("brcmtag_enable"); 118 char *wan_vlan = nvram_safe_get("wan_vlan"); 119 char *lan_vlan = nvram_safe_get("lan_vlan"); 120 char *lan_br_name; 121 char buf[80]; 122 char lan_ifbase_realdev[80], wan_ifbase[80]; 123 char name[80], lan_ifbase[80], br_group[80], *next, vlan[4], vlan_wan[4], port[4]; 124 uint bVlan, board_index = 0, i, buf_index = 0, hasBridge = 0; 125 uint bBrcmTag, bMIBAC; 126 uint wan_vid = 0, lan_vid = 0, lan_vids[BCM_NUM_PORTS-1], vid; 127 int unit; 128 129 bcm_l2_addr_t l2addr; 130 bcm_mac_t eth_addr, mcast_addr = BRIDGE_GROUP_MAC_ADDR; 131 int retval; 132 unsigned short MIBport; 133 bcm_mac_t MIBda; 134 uint mibac_int = ROBO_AC_RATE_DEFAULT; 135 136 if (!bcm_is_robo()) 137 return -1; 138 bVlan = (atoi(vlan_enable) > 0) ||(strlen(vlan_enable) && 139 !strncmp(vlan_enable,"true", strlen(vlan_enable))); 140 printf("\n\nBroadcom Enterprise RG/AP\n"); 141 printf("\r\nBroadcom ROBO 802.1Q VLAN %s\n", 142 bVlan > 0 ? "enabled" :"disabled"); 143 144 bMIBAC = (atoi(mibac_enable) > 0) || 145 (strlen(mibac_enable) && 146 !strncmp(mibac_enable,"true", strlen(mibac_enable))); 147 148 bBrcmTag = ((atoi(brcmtag_enable) > 0) || 149 (strlen(brcmtag_enable) && 150 !strncmp(brcmtag_enable,"true", strlen(brcmtag_enable)))); 151 152 if (strlen(mibac_interval)) 153 { 154 mibac_int = ROBO_GET_AC_RATE(atoi(mibac_interval)); 155 if (mibac_int > ROBO_AC_RATE_MAX) 156 mibac_int = ROBO_AC_RATE_MAX; 157 } 158 159 /* find configured and enabled WAN connection */ 160 for (unit = 0; unit < MAX_NVPARSE; unit ++) { 161 snprintf(prefix, sizeof(prefix), "wan%d_", unit); 162 wan_ifname = nvram_get(strcat_r(prefix, "ifname", tmp)); 163 if (!wan_ifname) 164 continue; 165 wan_proto = nvram_get(strcat_r(prefix, "proto", tmp)); 166 if (!wan_proto || !strcmp(wan_proto, "disabled")) 167 continue; 168 /* disable the connection if the i/f is not in wan_ifnames */ 169 if (!wan_valid(wan_ifname)) { 170 nvram_set(strcat_r(prefix, "proto", tmp), "disabled"); 171 continue; 172 } 173 break; 174 } 175 176 if (!wan_ifname) 177 { 178 if (bcm_is_robo()) 179 { 180 dprintf("No active, configured WAN interface found\n"); 181 enable_wan_port(); 182 } 183 return -1; 184 } 185 186 /* check to make sure vlan numbers are valid */ 187 /* (if no nvram variables, use defaults) */ 188 if (strlen(wan_vlan)) 189 wan_vid = atoi(wan_vlan); 190 else 191 wan_vid = vlan_boards[board_index].wan_vlan; 192 if (strlen(lan_vlan)) 193 lan_vid = atoi(lan_vlan); 194 else 195 lan_vid = vlan_boards[board_index].lan_vlan; 196 for (i=0;i<BCM_NUM_PORTS;i++) 197 lan_vids[i] = 0; 198 if (wan_vid == 0 || wan_vid > VLAN_ID_MAX) 199 { 200 printf("'wan_vlan' does not have valid vlan id\n"); 201 bVlan = 0; 202 } 203 if (lan_vid == 0 || lan_vid > VLAN_ID_MAX || lan_vid == wan_vid) 204 { 205 printf("'lan_vlan' does not have valid vlan id\n"); 206 bVlan = 0; 207 } 208 209 /* first restore ifnames, if necessary. note that if the user */ 210 /* wants to change lan_ifname or wan_ifname, it will be necessary */ 211 /* to delete the corresponding 'restore' value to avoid subsequent */ 212 /* overwriting of the new value when the router starts */ 213 if (strlen(restore_wan_ifname)) { 214 if (nvram_set(strcat_r(prefix, "ifname", tmp), restore_wan_ifname)) 215 return -1; 216 if (nvram_unset("restore_wan_ifname")) 217 return -1; 218 } 219 if (strlen(restore_lan_ifname)) { 220 if (nvram_set("lan_ifname", restore_lan_ifname)) 221 return -1; 222 if (nvram_unset("restore_lan_ifname")) 223 return -1; 224 } 225 if (strlen(restore_lan_ifnames)) { 226 if (nvram_set("lan_ifnames", restore_lan_ifnames)) 227 return -1; 228 if (nvram_unset("restore_lan_ifnames")) 229 return -1; 230 } 231 if (strlen(restore_wan_hwaddr)) { 232 if (nvram_set(strcat_r(prefix, "hwaddr", tmp), restore_wan_hwaddr)) 233 return -1; 234 if (nvram_unset("restore_wan_hwaddr")) 235 return -1; 236 } 237 238 /* now check to see if vlan disabled */ 239 /* disabled, just exit */ 240 if (!bVlan) 241 { 242 enable_wan_port(); 243 return 0; 244 } 245 246 /* activate interface to Robo switch */ 247 if ((bcm_api_init())<0) { 248 if (bcm_is_robo()) 249 { 250 dprintf("No ROBO device found\n"); 251 } 252 return -1; 253 } 254 /* create interface names */ 255 /* get base name that interface will be based on */ 256 sprintf(lan_ifbase,"eth%d",vlan_boards[board_index].vlan_devno); 257 258 /* check to see if bridge has been set up */ 259 if (strncmp(lan_ifname, "br", 2) == 0) { 260 /* iterate though members of bridge group and extract lan name for */ 261 /* use in creating vlans and create list w/o lan member, which will */ 262 /* have vlan group members added below */ 263 buf_index = 0; 264 foreach(name, nvram_safe_get("lan_ifnames"), next) { 265 if (strncmp(name, lan_ifbase, 4) == 0) { 266 hasBridge = 1; 267 } 268 else { 269 strcpy(&br_group[buf_index],name); 270 strcat(br_group," "); 271 buf_index = strlen(br_group); 272 } 273 } 274 } 275 276 /* note that if brcm tags are enabled, the WAN is configured with a vlan and */ 277 /* the LAN ports are configured with the brcm tag driver. if brcm tags are disabled */ 278 /* the LAN is configured with a vlan and the WAN directly uses eth0. This */ 279 /* only applies to vlan interfaces created with vconfig. In both cases, the underlying */ 280 /* switch is programmed with a separate vlan for WAN and LAN, but in the case w/o */ 281 /* brcm tags, the WAN vlan tag is removed when it exits the switch to the CPU */ 282 283 /* modify lan_ifbase & wan_ifbase for brcm tag driver, but save to bring up interface */ 284 strcpy(lan_ifbase_realdev,lan_ifbase); 285 strcpy(wan_ifbase,lan_ifbase); 286 if (bBrcmTag) 287 { 288 /* if brcm tag driver will be used, add 't' to root name */ 289 strcat(lan_ifbase,"t"); 290 strcat(wan_ifbase,"t"); 291 sprintf(buf,".%d",vlan_boards[board_index].wan_port); 292 strcat(wan_ifbase,buf); 293 /* need to create wan vlan name here. the form of the name will be ethx.port.vlan */ 294 sprintf(buf,"%s.%d",wan_ifbase,wan_vid); 295 nvram_set("restore_wan_ifname",wan_ifname); 296 nvram_set(strcat_r(prefix, "ifname", tmp),buf); 297 nvram_set(strcat_r(prefix, "ifnames", tmp),buf); 298 } 299 300 /* we need to handle the case of if bridge exists or not. if 301 * it does exist, and brcm tags are enabled brcm tag (for default) interface names will be 302 * substituted for 'ethx' name. if it doesn't exist, bridge 'br0' will be created 303 * with only vlan or brcm tag interface names 304 */ 305 if (hasBridge) { 306 lan_br_name = lan_ifname; 307 strcpy(&buf[0],&br_group[0]); 308 } else { 309 lan_br_name = "br0"; 310 buf_index = 0; 311 hasBridge = 1; 312 } 313 for (i = vlan_boards[board_index].lan_port_start; 314 i <= vlan_boards[board_index].lan_port_end;i++) { 315 if (bBrcmTag) 316 /* use port ids for interface suffixes */ 317 sprintf(&buf[buf_index],"%s.%d ",lan_ifbase,i); 318 else 319 /* use single lan vlan id interface suffixes */ 320 sprintf(&buf[buf_index],"%s.%d ",lan_ifbase,lan_vid); 321 buf_index = strlen(buf); 322 if (!bBrcmTag) 323 /* if no brcm tag driver, just use one interface for all ports on LAN side */ 324 break; 325 } 326 /* get rid of last space */ 327 buf[strlen(buf) - 1] = '\0'; 328 printf("lan_ifnames %s\n",buf); 329 nvram_set("restore_lan_ifnames",lan_ifnames); 330 nvram_set("restore_lan_ifname",lan_ifname); 331 nvram_set("lan_ifnames",buf); 332 nvram_set("lan_ifname",lan_br_name); 333 334 /* change wan_hwaddr to be lan_hwaddr. this is because underlying 335 * lan device has lan_hwaddr and if wan vlan device had different 336 * hwaddr, the vlan processing would set the underlying device to 337 * promiscuous mode 338 */ 339 nvram_set("restore_wan_hwaddr",wan_hwaddr); 340 nvram_set(strcat_r(prefix, "hwaddr", tmp),nvram_safe_get("lan_hwaddr")); 341 342 /* now create vlan i/f's */ 343 /* need to bring up the underlying switch i/f to create vlans */ 344 ifconfig(lan_ifbase_realdev, IFUP, 0, 0); 345 346 if (bBrcmTag) 347 { 348 /* create brcm tag device for wan */ 349 bcm_reg_brcmtag_dev(lan_ifbase_realdev, "t", vlan_boards[board_index].wan_port); 350 ifconfig(wan_ifbase, IFUP, 0, 0); 351 } 352 353 /* first, wan vlan. note, must also configure wan here, in case */ 354 /* it's the same wan being used for nfs, in order to allow nfs to */ 355 /* keep working during configuration of vlans */ 356 sprintf(vlan_wan,"%d",wan_vid); 357 eval("vconfig","set_name_type","DEV_PLUS_VID_NO_PAD"); 358 if (bBrcmTag) 359 eval("vconfig","add",wan_ifbase,vlan_wan); 360 else 361 /* don't configure WAN as vlan interface, just program switch with vlan id */ 362 bcm_vlan_create(0,wan_vid); /* this is for default case, which doesn't call vconfig */ 363 /* Bring up WAN interface */ 364 ifconfig(nvram_safe_get(strcat_r(prefix, "ifname", tmp)), IFUP, 365 nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)), 366 nvram_safe_get(strcat_r(prefix, "netmask", tmp))); 367 /* now configure wan vlan and enable vlans */ 368 sprintf(port,"%d",vlan_boards[board_index].wan_port); 369 eval("vconfig","add_port",vlan_wan,port); 370 /* MII port is set up to tag with wan vlan here, but that will be overridden below */ 371 /* to tag with lan vlan (only matters for default case where CPU doesn't have vlan */ 372 /* configured, but switch does; ie, mii port does tag/untag) */ 373 sprintf(port,"%d",BCM_MII_PORT); /* mii port, note that vlan tags retained on egress */ 374 if (bBrcmTag) 375 eval("vconfig","add_port_nountag",vlan_wan,port); 376 else 377 /* if no BRCM tags, untag MII for WAN VLAN */ 378 eval("vconfig","add_port",vlan_wan,port); 379 if (bBrcmTag) 380 /* set flag to let vlan dev build headers in vlan_dev_hard_header */ 381 eval("vconfig","set_flag",nvram_safe_get(strcat_r(prefix, "wan_ifname", tmp)),"1","0"); 382 383 /* now enable switch ports for vlan */ 384 sprintf(buf,"%d",1); 385 eval("vconfig","ports_enable",buf); 386 387 /* set multicast related registers */ 388 buf[0] = 0x0a; /* Rsvd MC tag/untag */ 389 if (bBrcmTag) 390 /* if default mode, allow tagging of frames into MII. this is to allow */ 391 /* lan to have vlan handling in switch, but remove vlan tag when received */ 392 /* by CPU */ 393 buf[0] |= 0x80; 394 bcm_write_reg(0,ROBO_VLAN_PAGE,ROBO_VLAN_CTRL1,buf,1); 395 buf[0] = 0x01; /* enable MC ARL entries to use port map */ 396 bcm_write_reg(0,ROBO_CTRL_PAGE,ROBO_IP_MULTICAST_CTRL,buf,1); 397 buf[0] = 0x1c; /* MII receive unicast, multicast, broadcast */ 398 bcm_write_reg(0,ROBO_CTRL_PAGE,ROBO_IM_PORT_CTRL,buf,1); 399 buf[0] = 0x40; /* drop frame if frame has VID violation */ 400 bcm_write_reg(0,ROBO_VLAN_PAGE,ROBO_VLAN_CTRL4,buf,1); 401 buf[0] = 0x08; /* drop frame if vtable miss */ 402 bcm_write_reg(0,ROBO_VLAN_PAGE,ROBO_VLAN_CTRL5,buf,1); 403 if (bBrcmTag) 404 { 405 /* now set up managed mode registers for brcm tag */ 406 buf[0] = 0x00; /* Rsvd MC tag/untag */ 407 bcm_write_reg(0,ROBO_VLAN_PAGE,ROBO_VLAN_CTRL1,buf,1); 408 buf[0] = 0x8e; /* MII port as management port, IGMP snoop, rx BPDUs */ 409 bcm_write_reg(0,ROBO_MGMT_PAGE,ROBO_GLOBAL_CONFIG,buf,1); 410 buf[0] = 0x08; /* mgmt port ID */ 411 bcm_write_reg(0,ROBO_MGMT_PAGE,ROBO_MGMT_PORT_ID,buf,1); 412 buf[0] = 0x0a; /* ignore crc check on mgmt port */ 413 bcm_write_reg(0,ROBO_VLAN_PAGE,ROBO_VLAN_CTRL5,buf,1); 414 buf[0] = 0x03; /* turn on managed mode */ 415 bcm_write_reg(0,ROBO_CTRL_PAGE,ROBO_SWITCH_MODE,buf,1); 416 brcm_tag_driver_enabled = 1; 417 } 418 /* now assign 0.0.0.0 ip address to i/f underlying vlans */ 419 if (bBrcmTag) 420 ifconfig(lan_ifbase_realdev, IFUP, "0.0.0.0", "0.0.0.0"); 421 422 /* now lan vlan */ 423 for (i = vlan_boards[board_index].lan_port_start; 424 i <= vlan_boards[board_index].lan_port_end;i++) { 425 /* if default, no vconfig, because */ 426 /* vlan untagged at MII port */ 427 if (bBrcmTag) { 428 /* default mode (w/brcm tags), create brcm tag device per port and set up */ 429 /* single vlan for all ports */ 430 if (i == vlan_boards[board_index].lan_port_start) 431 { 432 bcm_vlan_create(0,lan_vid); /* this is for default case, which doesn't call vconfig */ 433 sprintf(vlan,"%d",lan_vid); 434 sprintf(port,"%d",BCM_MII_PORT); /* mii port */ 435 eval("vconfig","add_port",vlan,port); 436 } 437 sprintf(port,"%d",i); 438 eval("vconfig","add_port",vlan,port); 439 bcm_reg_brcmtag_dev(lan_ifbase_realdev, "t", i); 440 } else { 441 /* brcm tags disabled. create one vlan interface for LAN */ 442 if (i == vlan_boards[board_index].lan_port_start) 443 { 444 /* only create one vlan for default mode w/no brcm tags */ 445 sprintf(vlan,"%d",lan_vid); 446 eval("vconfig","add",lan_ifbase,vlan); 447 /* also add mii port */ 448 sprintf(port,"%d",BCM_MII_PORT); /* mii port */ 449 eval("vconfig","add_port_nountag_nodeftag",vlan,port); 450 } 451 sprintf(port,"%d",i); 452 eval("vconfig","add_port",vlan,port); 453 /* add interface to port/interface map */ 454 bcm_add_port_interface(i, lan_vid); 455 } 456 } 457 458 if (hasBridge && bBrcmTag) 459 { 460 /* init spanning tree state */ 461 /* set WAN port & MII to forwarding, all others to disabled */ 462 bcm_port_stp_set(BCM_WAN_PORT,BCM_PORT_STP_FORWARD); 463 bcm_port_stp_set(9,BCM_PORT_STP_FORWARD); 464 for (i = vlan_boards[board_index].lan_port_start; 465 i <= vlan_boards[board_index].lan_port_end;i++) 466 bcm_port_stp_set(i,BCM_PORT_STP_DISABLE); 467 } else { 468 /* init spanning tree state to none for all ports */ 469 for (i=1;i<=BCM_MAX_PORT;i++) 470 bcm_port_stp_set(i,BCM_PORT_STP_NONE); 471 } 472 /* add static entries to arl for wan hwaddr & lan hwaddr */ 473 ether_atoe(nvram_safe_get(strcat_r(prefix, "hwaddr", tmp)), eth_addr); 474 bcm_l2_addr_init(&l2addr,eth_addr,wan_vid); 475 l2addr.port = BCM_MII_ARL_UC_PORT-1; 476 if (BCM_RET_SUCCESS != (retval = bcm_l2_addr_add(0, &l2addr))) 477 dprintf("failure writing wan l2 addr: %d\n",retval); 478 ether_atoe(nvram_safe_get("lan_hwaddr"), eth_addr); 479 /* set up MIB autocast, if enabled */ 480 if (bMIBAC) 481 { 482 /* set up MIB AC (dst, src, port & rate) */ 483 memcpy(MIBda,eth_addr,sizeof(bcm_mac_t)); 484 bcm_byteswap(&MIBda); 485 bcm_write_reg(0,ROBO_MIB_AC_PAGE,ROBO_MIB_AC_DA,MIBda,sizeof(bcm_mac_t)); 486 memset(buf,0,sizeof(bcm_mac_t)); 487 bcm_write_reg(0,ROBO_MIB_AC_PAGE,ROBO_MIB_AC_SA,buf,sizeof(bcm_mac_t)); 488 MIBport = PBMP_PORT(BCM_MII_ARL_UC_PORT-1); 489 bcm_write_reg(0,ROBO_MIB_AC_PAGE,ROBO_MIB_AC_PORT,(uint8 *)&MIBport,sizeof(MIBport)); 490 bcm_write_reg(0,ROBO_MIB_AC_PAGE,ROBO_MIB_AC_RATE,(uint8 *)&mibac_int,sizeof(char)); 491 bcm_read_reg(0,ROBO_MGMT_PAGE,ROBO_GLOBAL_CONFIG,buf,1); 492 buf[0] |= 0x20; /* enable MIB AC */ 493 bcm_write_reg(0,ROBO_MGMT_PAGE,ROBO_GLOBAL_CONFIG,buf,1); 494 } 495 /* now multicast entry for BPDUs */ 496 bcm_l2_addr_init(&l2addr,mcast_addr,wan_vid); 497 l2addr.pbmp = PBMP_PORT(i-1) | PBMP_PORT(BCM_MII_PORT-1); 498 if (BCM_RET_SUCCESS != (retval = bcm_l2_addr_add(0, &l2addr))) 499 dprintf("failure writing lan l2 addr: %d\n",retval); 500 for (i = vlan_boards[board_index].lan_port_start; 501 i <= vlan_boards[board_index].lan_port_end;i++) { 502 vid = lan_vid; 503 if (i == vlan_boards[board_index].lan_port_start) { 504 bcm_l2_addr_init(&l2addr,eth_addr,vid); 505 l2addr.port = BCM_MII_ARL_UC_PORT-1; 506 if (BCM_RET_SUCCESS != (retval = bcm_l2_addr_add(0, &l2addr))) 507 dprintf("failure writing lan l2 addr: %d\n",retval); 508 /* now multicast entry for BPDUs */ 509 bcm_l2_addr_init(&l2addr,mcast_addr,vid); 510 l2addr.pbmp = PBMP_PORT(i-1) | PBMP_PORT(BCM_MII_PORT-1); 511 if (BCM_RET_SUCCESS != (retval = bcm_l2_addr_add(0, &l2addr))) 512 dprintf("failure writing lan l2 addr: %d\n",retval); 513 } 514 } 515 if (!bBrcmTag) 516 { 517 /* if in mgmt mode (if brcm tag driver used), don't need to do this */ 518 /* set bogus mc addr to bypass specian h/w handling of BPDUs and let ARL handle them */ 519 memset(&mcast_addr,0,sizeof(mcast_addr)); 520 bcm_write_reg(0,ROBO_ARLCTRL_PAGE,ROBO_BPDU_MC_ADDR_REG,mcast_addr,sizeof(mcast_addr)); 521 } 522 vlan_configured = 1; 523 /* deinit Robo switch interface */ 524 bcm_api_deinit(); 525 526 /* We had changed wan_hwaddr to be the same as lan_hwaddr (temporarily) 527 due the issue of promiscuous. 528 Now it's time to roll it back. */ 529 restore_wan_hwaddr = nvram_safe_get("restore_wan_hwaddr"); 530 if (strlen(restore_wan_hwaddr)) 531 { 532 if (nvram_set(strcat_r(prefix, "hwaddr", tmp), restore_wan_hwaddr)) 533 return -1; 534 if (nvram_unset("restore_wan_hwaddr")) 535 return -1; 536 } 537 538 nvram_commit(); 539 540 return 0; 541} 542 543static int 544vlan_deconfigure(void) 545{ 546 char *restore_lan_ifname = nvram_safe_get("restore_lan_ifname"); 547 char *restore_lan_ifnames = nvram_safe_get("restore_lan_ifnames"); 548 char *restore_wan_ifname = nvram_safe_get("restore_wan_ifname"); 549 char *restore_wan_hwaddr = nvram_safe_get("restore_wan_hwaddr"); 550 char *wan_ifname = NULL; 551 char *wan_proto; 552 char tmp[100], prefix[] = "wanXXXXXXXXXX_"; 553 char buf[80]; 554 char name[80], *next; 555 uint board_index = 0; 556 int unit; 557 558 /* first, bring down vlans, if enabled */ 559 dprintf("deconfigure vlan\n"); 560 if (vlan_configured) { 561 562 /* activate interface to Robo switch */ 563 if ((bcm_api_init())<0) { 564 dprintf("No ROBO device found\n"); 565 return -1; 566 } 567 568 /* find configured and enabled WAN connection */ 569 for (unit = 0; unit < MAX_NVPARSE; unit ++) { 570 snprintf(prefix, sizeof(prefix), "wan%d_", unit); 571 wan_ifname = nvram_get(strcat_r(prefix, "ifname", tmp)); 572 if (!wan_ifname) 573 continue; 574 wan_proto = nvram_get(strcat_r(prefix, "proto", tmp)); 575 if (!wan_proto || !strcmp(wan_proto, "disabled")) 576 continue; 577 /* disable the connection if the i/f is not in wan_ifnames */ 578 if (!wan_valid(wan_ifname)) { 579 nvram_set(strcat_r(prefix, "proto", tmp), "disabled"); 580 continue; 581 } 582 } 583 584 if (!wan_ifname) 585 { 586 if (bcm_is_robo()) 587 { 588 dprintf("No active, configured WAN interface found\n"); 589 } 590 return -1; 591 } 592 593 /* vlan is non-zero, that means that eth0 is wan port */ 594 if (vlan_boards[board_index].vlan_devno) 595 ifconfig("eth0", IFUP, nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)), 596 nvram_safe_get(strcat_r(prefix, "netmask", tmp))); 597 598 /* now bring down brcm tag device for wan device */ 599 if (brcm_tag_driver_enabled) 600 { 601 /* Strip off vlan suffix */ 602 strcpy(name,wan_ifname); 603 next = strrchr(name,'.'); 604 if (next != NULL) 605 { 606 *next = '\0'; 607 bcm_unreg_brcmtag_dev(name); 608 } 609 buf[0] = 0x02; /* turn off managed mode */ 610 bcm_write_reg(0,ROBO_CTRL_PAGE,ROBO_SWITCH_MODE,buf,1); 611 buf[0] = 0x00; /* turn off vlan mode */ 612 bcm_write_reg(0,ROBO_VLAN_PAGE,ROBO_VLAN_CTRL0,buf,1); 613 /* now, deconfigure wan vlan */ 614 eval("vconfig","rem",wan_ifname); 615 } 616 617 /* now lan vlan */ 618 if (brcm_tag_driver_enabled) { 619 /* default mode, just bring down brcm tag devices per port */ 620 foreach(name, nvram_safe_get("lan_ifnames"), next) { 621 /* check to see if has suffix '.port' before removing */ 622 if (strrchr(name,'.') != NULL) 623 bcm_unreg_brcmtag_dev(name); 624 } 625 brcm_tag_driver_enabled = 0; 626 } else 627 /* no brcm tags, bring down lan vlan */ 628 foreach(name, nvram_safe_get("lan_ifnames"), next) { 629 /* check to see if has suffix '.port' before removing */ 630 if (strrchr(name,'.') != NULL) 631 eval("vconfig","rem",name); 632 } 633 } 634 /* now disable switch ports for vlan */ 635 sprintf(buf,"%d\n",0); 636 eval("vconfig","ports_enable",buf); 637 vlan_configured = 0; 638 bcm_api_deinit(); 639 640 /* now restore environment */ 641 if (strlen(restore_wan_ifname)) { 642 if (nvram_set(strcat_r(prefix, "ifname", tmp), restore_wan_ifname)) 643 return -1; 644 if (nvram_unset("restore_wan_ifname")) 645 return -1; 646 } 647 if (strlen(restore_lan_ifname)) { 648 if (nvram_set("lan_ifname", restore_lan_ifname)) 649 return -1; 650 if (nvram_unset("restore_lan_ifname")) 651 return -1; 652 } 653 if (strlen(restore_lan_ifnames)) { 654 if (nvram_set("lan_ifnames", restore_lan_ifnames)) 655 return -1; 656 if (nvram_unset("restore_lan_ifnames")) 657 return -1; 658 } 659 if (strlen(restore_wan_hwaddr)) { 660 if (nvram_set(strcat_r(prefix, "wan_hwaddr", tmp), restore_wan_hwaddr)) 661 return -1; 662 if (nvram_unset("restore_wan_hwaddr")) 663 return -1; 664 } 665 666 return 0; 667} 668 669 670/* 671 * Setup VLAN interfaces, if enabled 672 */ 673int 674start_vlan(void) 675{ 676 /* Bringup vlan interfaces */ 677 vlan_configure(); 678 return 0; 679} 680 681/* 682 * Stop VLANs, if they have been created. 683 */ 684int 685stop_vlan(void) 686{ 687 688 /* Shut down vifs */ 689 vlan_deconfigure(); 690 return 0; 691} 692 693 694int start_portmon() 695{ 696 697 /* Start Linkscan */ 698 return 0; 699 700} 701 702 703int stop_portmon() 704{ 705 706 /* Stop linkscan */ 707 return 0; 708} 709#endif 710