Changeset 35584


Ignore:
Timestamp:
2013-02-13T17:04:50+01:00 (5 years ago)
Author:
hauke
Message:

switch: read and write vlan config from and to gigabit switches

This patch makes it possible to read and write the vlan config from and to recent switchs.

This is based on a patch by jcharest and the Broadcom SDK.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/package/switch/src/switch-robo.c

    r35583 r35584  
    7575        bool is_5365; 
    7676        bool gmii;                      /* gigabit mii */ 
     77        u8 corerev; 
    7778        int gpio_robo_reset; 
    7879        int gpio_lanports_enable; 
     
    420421} 
    421422 
    422  
    423 static int handle_vlan_port_read(void *driver, char *buf, int nr) 
     423static int handle_vlan_port_read_old(switch_driver *d, char *buf, int nr) 
    424424{ 
    425425        __u16 val16; 
     
    434434                val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_READ); 
    435435                if ((val16 & (1 << 14)) /* valid */) { 
    436                         for (j = 0; j < 6; j++) { 
     436                        for (j = 0; j < d->ports; j++) { 
    437437                                if (val16 & (1 << j)) { 
    438438                                        len += sprintf(buf + len, "%d", j); 
    439439                                        if (val16 & (1 << (j + 7))) { 
    440                                                 if (j == 5) 
     440                                                if (j == d->cpuport) 
    441441                                                        buf[len++] = 'u'; 
    442442                                        } else { 
     
    456456                val32 = robo_read32(ROBO_VLAN_PAGE, ROBO_VLAN_READ); 
    457457                if ((val32 & (1 << 20)) /* valid */) { 
    458                         for (j = 0; j < 6; j++) { 
     458                        for (j = 0; j < d->ports; j++) { 
    459459                                if (val32 & (1 << j)) { 
    460460                                        len += sprintf(buf + len, "%d", j); 
    461                                         if (val32 & (1 << (j + 6))) { 
    462                                                 if (j == 5) 
     461                                        if (val32 & (1 << (j + d->ports))) { 
     462                                                if (j == d->cpuport) 
    463463                                                        buf[len++] = 'u'; 
    464464                                        } else { 
     
    479479} 
    480480 
     481static int handle_vlan_port_read_new(switch_driver *d, char *buf, int nr) 
     482{ 
     483        __u8 vtbl_entry, vtbl_index, vtbl_access; 
     484        __u32 val32; 
     485        int len = 0; 
     486        int j; 
     487 
     488        if ((robo.devid == ROBO_DEVICE_ID_5395) || 
     489            (robo.devid == ROBO_DEVICE_ID_53115)) { 
     490                vtbl_access = ROBO_VTBL_ACCESS_5395; 
     491                vtbl_index = ROBO_VTBL_INDX_5395; 
     492                vtbl_entry = ROBO_VTBL_ENTRY_5395; 
     493        } else { 
     494                vtbl_access = ROBO_VTBL_ACCESS; 
     495                vtbl_index = ROBO_VTBL_INDX; 
     496                vtbl_entry = ROBO_VTBL_ENTRY; 
     497        } 
     498 
     499        robo_write16(ROBO_ARLIO_PAGE, vtbl_index, nr); 
     500        robo_write16(ROBO_ARLIO_PAGE, vtbl_access, (1 << 7) | (1 << 0)); 
     501        val32 = robo_read32(ROBO_ARLIO_PAGE, vtbl_entry); 
     502        for (j = 0; j < d->ports; j++) { 
     503                if (val32 & (1 << j)) { 
     504                        len += sprintf(buf + len, "%d", j); 
     505                        if (val32 & (1 << (j + d->ports))) { 
     506                                if (j == d->cpuport) 
     507                                        buf[len++] = 'u'; 
     508                        } else { 
     509                                buf[len++] = 't'; 
     510                                if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr) 
     511                                        buf[len++] = '*'; 
     512                        } 
     513                        buf[len++] = '\t'; 
     514                } 
     515        } 
     516        len += sprintf(buf + len, "\n"); 
     517        buf[len] = '\0'; 
     518        return len; 
     519} 
     520 
     521static int handle_vlan_port_read(void *driver, char *buf, int nr) 
     522{ 
     523        switch_driver *d = (switch_driver *) driver; 
     524 
     525        if (robo.devid != ROBO_DEVICE_ID_5325) 
     526                return handle_vlan_port_read_new(d, buf, nr); 
     527        else 
     528                return handle_vlan_port_read_old(d, buf, nr); 
     529} 
     530 
     531static void handle_vlan_port_write_old(switch_driver *d, switch_vlan_config *c, int nr) 
     532{ 
     533        __u16 val16; 
     534        __u32 val32; 
     535        __u32 untag = ((c->untag  & ~(1 << d->cpuport)) << d->ports); 
     536 
     537        /* write config now */ 
     538        val16 = (nr) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; 
     539        if (robo.is_5365) { 
     540                robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365, 
     541                        (1 << 14)  /* valid */ | (untag << 1 ) | c->port); 
     542                robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16); 
     543        } else { 
     544                if (robo.corerev < 3) 
     545                        val32 = (1 << 20) | ((nr >> 4) << 12) | untag | c->port; 
     546                else 
     547                        val32 = (1 << 24) | (nr << 12) | untag | c->port; 
     548                robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, val32); 
     549                robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); 
     550        } 
     551} 
     552 
     553static void handle_vlan_port_write_new(switch_driver *d, switch_vlan_config *c, int nr) 
     554{ 
     555        __u8 vtbl_entry, vtbl_index, vtbl_access; 
     556        __u32 untag = ((c->untag  & ~(1 << d->cpuport)) << d->ports); 
     557 
     558        /* write config now */ 
     559        if ((robo.devid == ROBO_DEVICE_ID_5395) || 
     560            (robo.devid == ROBO_DEVICE_ID_53115)) { 
     561                vtbl_access = ROBO_VTBL_ACCESS_5395; 
     562                vtbl_index = ROBO_VTBL_INDX_5395; 
     563                vtbl_entry = ROBO_VTBL_ENTRY_5395; 
     564        } else { 
     565                vtbl_access = ROBO_VTBL_ACCESS; 
     566                vtbl_index = ROBO_VTBL_INDX; 
     567                vtbl_entry = ROBO_VTBL_ENTRY; 
     568        } 
     569 
     570        robo_write32(ROBO_ARLIO_PAGE, vtbl_entry, untag | c->port); 
     571        robo_write16(ROBO_ARLIO_PAGE, vtbl_index, nr); 
     572        robo_write16(ROBO_ARLIO_PAGE, vtbl_access, 1 << 7); 
     573} 
     574 
    481575static int handle_vlan_port_write(void *driver, char *buf, int nr) 
    482576{ 
    483         switch_driver *d = (switch_driver *) driver; 
     577        switch_driver *d = (switch_driver *)driver; 
    484578        switch_vlan_config *c = switch_parse_vlan(d, buf); 
    485579        int j; 
    486         __u16 val16; 
    487580 
    488581        if (c == NULL) 
     
    490583 
    491584        for (j = 0; j < d->ports; j++) { 
    492                 if ((c->untag | c->pvid) & (1 << j)) 
     585                if ((c->untag | c->pvid) & (1 << j)) { 
    493586                        /* change default vlan tag */ 
    494587                        robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1), nr); 
    495         } 
    496  
    497         /* write config now */ 
    498  
    499         if (robo.devid != ROBO_DEVICE_ID_5325) { 
    500                 __u8 regoff = ((robo.devid == ROBO_DEVICE_ID_5395) || 
    501                         (robo.devid == ROBO_DEVICE_ID_53115)) ? 0x20 : 0; 
    502  
    503                 robo_write32(ROBO_ARLIO_PAGE, 0x63 + regoff, (c->untag << 9) | c->port); 
    504                 robo_write16(ROBO_ARLIO_PAGE, 0x61 + regoff, nr); 
    505                 robo_write16(ROBO_ARLIO_PAGE, 0x60 + regoff, 1 << 7); 
    506                 kfree(c); 
    507                 return 0; 
    508         } 
    509  
    510         val16 = (nr) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; 
    511         if (robo.is_5365) { 
    512                 robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365, 
    513                         (1 << 14)  /* valid */ | (c->untag << 7) | c->port); 
    514                 robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16); 
    515         } else { 
    516                 robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, 
    517                         (1 << 20) /* valid */ | (c->untag << 6) | c->port); 
    518                 robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); 
    519         } 
     588                } 
     589        } 
     590 
     591        if (robo.devid != ROBO_DEVICE_ID_5325) 
     592                handle_vlan_port_write_new(d, c, nr); 
     593        else 
     594                handle_vlan_port_write_old(d, c, nr); 
    520595 
    521596        kfree(c); 
Note: See TracChangeset for help on using the changeset viewer.