Changeset 2819


Ignore:
Timestamp:
2006-01-04T20:10:06+01:00 (12 years ago)
Author:
nbd
Message:

kmod-switch: vlan parser rewrite, some api changes, minor fixes

Location:
trunk/openwrt/target/linux/package/switch/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/openwrt/target/linux/package/switch/src/switch-adm.c

    r2783 r2819  
    241241static int vlan_ports[] = { 1 << 0, 1 << 2, 1 << 4, 1 << 6, 1 << 7, 1 << 8 }; 
    242242 
    243 static int handle_vlan_port_read(char *buf, int nr) 
     243static int handle_vlan_port_read(void *driver, char *buf, int nr) 
    244244{ 
    245245        int ports, i, c, len = 0; 
     
    262262} 
    263263 
    264 static int handle_vlan_port_write(char *buf, int nr) 
    265 { 
    266         int i, c, ports; 
    267         int map = switch_parse_vlan(buf); 
    268  
    269         if (map == -1) 
     264static int handle_vlan_port_write(void *driver, char *buf, int nr) 
     265{ 
     266        int i, cfg, ports; 
     267        switch_driver *d = (switch_driver *) driver; 
     268        switch_vlan_config *c = switch_parse_vlan(d, buf); 
     269 
     270        if (c == NULL) 
    270271                return -1; 
    271272 
    272273        ports = adm_rreg(0, 0x13 + nr); 
    273         for (i = 0; i <= 5; i++) { 
    274                 if (map & (1 << i)) { 
     274        for (i = 0; i < d->ports; i++) { 
     275                if (c->port & (1 << i)) { 
    275276                        ports |= vlan_ports[i]; 
    276277 
    277                         c = adm_rreg(0, port_conf[i]); 
     278                        cfg = adm_rreg(0, port_conf[i]); 
    278279                         
    279280                        /* Tagging */ 
    280                         if (map & (1 << (8 + i))) 
    281                                 c |= (1 << 4); 
     281                        if (c->untag & (1 << i)) 
     282                                cfg &= ~(1 << 4); 
    282283                        else 
    283                                 c &= ~(1 << 4); 
    284  
    285                         c = (c & ~(0xf << 10)) | (nr << 10); 
     284                                cfg |= (1 << 4); 
    286285                         
    287                         adm_wreg(port_conf[i], (__u16) c); 
     286                        if ((c->untag | c->pvid) & (1 << i)) { 
     287                                cfg = (cfg & ~(0xf << 10)) | (nr << 10); 
     288                        } 
     289                         
     290                        adm_wreg(port_conf[i], (__u16) cfg); 
    288291                } else { 
    289292                        ports &= ~(vlan_ports[i]); 
     
    295298} 
    296299 
    297 static int handle_port_enable_read(char *buf, int nr) 
     300static int handle_port_enable_read(void *driver, char *buf, int nr) 
    298301{ 
    299302        return sprintf(buf, "%d\n", ((adm_rreg(0, port_conf[nr]) & (1 << 5)) ? 0 : 1)); 
    300303} 
    301304 
    302 static int handle_port_enable_write(char *buf, int nr) 
     305static int handle_port_enable_write(void *driver, char *buf, int nr) 
    303306{ 
    304307        int reg = adm_rreg(0, port_conf[nr]); 
     
    314317} 
    315318 
    316 static int handle_port_media_read(char *buf, int nr) 
     319static int handle_port_media_read(void *driver, char *buf, int nr) 
    317320{ 
    318321        int len; 
     
    331334} 
    332335 
    333 static int handle_port_media_write(char *buf, int nr) 
     336static int handle_port_media_write(void *driver, char *buf, int nr) 
    334337{ 
    335338        int media = switch_parse_media(buf); 
     
    352355} 
    353356 
    354 static int handle_vlan_enable_read(char *buf, int nr) 
     357static int handle_vlan_enable_read(void *driver, char *buf, int nr) 
    355358{ 
    356359        return sprintf(buf, "%d\n", ((adm_rreg(0, 0x11) & (1 << 5)) ? 1 : 0)); 
    357360} 
    358361 
    359 static int handle_vlan_enable_write(char *buf, int nr) 
     362static int handle_vlan_enable_write(void *driver, char *buf, int nr) 
    360363{ 
    361364        int reg = adm_rreg(0, 0x11); 
     
    371374} 
    372375 
    373 static int handle_reset(char *buf, int nr) 
     376static int handle_reset(void *driver, char *buf, int nr) 
    374377{ 
    375378        int i; 
     
    413416} 
    414417 
    415 static int handle_registers(char *buf, int nr) 
     418static int handle_registers(void *driver, char *buf, int nr) 
    416419{ 
    417420        int i, len = 0; 
     
    424427} 
    425428 
    426 static int handle_counters(char *buf, int nr) 
     429static int handle_counters(void *driver, char *buf, int nr) 
    427430{ 
    428431        int i, len = 0; 
     
    452455        ret = 1; 
    453456#endif 
     457        if (ret == 1) { 
     458                int i = adm_rreg(0, 0); 
     459                if ((i == 0) || (i == 0xffff)) { 
     460                        printk("No ADM6996 chip detected.\n"); 
     461                        ret = 0; 
     462                } 
     463        } 
    454464 
    455465        return ret; 
     
    476486        switch_driver driver = { 
    477487                name: DRIVER_NAME, 
     488                interface: "eth0", 
    478489                ports: 6, 
     490                cpuport: 5, 
    479491                vlans: 16, 
    480492                driver_handlers: cfg, 
  • trunk/openwrt/target/linux/package/switch/src/switch-core.c

    r2776 r2819  
    3838        struct proc_dir_entry *parent; 
    3939        int nr; 
     40        void *driver; 
    4041        switch_config handler; 
    4142} switch_proc_handler; 
     
    4849} switch_priv; 
    4950 
    50  
    5151static ssize_t switch_proc_read(struct file *file, char *buf, size_t count, loff_t *ppos); 
    5252static ssize_t switch_proc_write(struct file *file, const char *buf, size_t count, void *data); 
     
    5757}; 
    5858 
    59 static char *strdup(char *str) 
     59static inline char *strdup(char *str) 
    6060{ 
    6161        char *new = kmalloc(strlen(str) + 1, GFP_KERNEL); 
     
    8181                switch_proc_handler *handler = (switch_proc_handler *) dent->data; 
    8282                if (handler->handler.read != NULL) 
    83                         len += handler->handler.read(page + len, handler->nr); 
     83                        len += handler->handler.read(handler->driver, page + len, handler->nr); 
    8484        } 
    8585        len += 1; 
     
    123123                switch_proc_handler *handler = (switch_proc_handler *) dent->data; 
    124124                if (handler->handler.write != NULL) { 
    125                         if ((ret = handler->handler.write(page, handler->nr)) >= 0) 
     125                        if ((ret = handler->handler.write(handler->driver, page, handler->nr)) >= 0) 
    126126                                ret = count; 
    127127                } 
     
    132132} 
    133133 
    134 static void add_handlers(switch_priv *priv, switch_config *handlers, struct proc_dir_entry *parent, int nr) 
    135 { 
     134static void add_handlers(switch_driver *driver, switch_config *handlers, struct proc_dir_entry *parent, int nr) 
     135{ 
     136        switch_priv *priv = (switch_priv *) driver->data; 
    136137        switch_proc_handler *tmp; 
    137138        int i, mode; 
     
    143144                tmp->parent = parent; 
    144145                tmp->nr = nr; 
     146                tmp->driver = driver; 
    145147                memcpy(&tmp->handler, &(handlers[i]), sizeof(switch_config)); 
    146148                list_add(&tmp->list, &priv->data.list); 
     
    193195        remove_proc_entry("vlan", priv->driver_dir); 
    194196 
    195         remove_proc_entry(driver->name, switch_root); 
     197        remove_proc_entry(driver->interface, switch_root); 
    196198                         
    197199        if (priv->nr == (drv_num - 1)) 
     
    214216         
    215217        priv->nr = drv_num++; 
    216         sprintf(buf, "%d", priv->nr); 
    217         priv->driver_dir = proc_mkdir(buf, switch_root); 
     218        priv->driver_dir = proc_mkdir(driver->interface, switch_root); 
    218219        if (driver->driver_handlers != NULL) 
    219                 add_handlers(priv, driver->driver_handlers, priv->driver_dir, 0); 
     220                add_handlers(driver, driver->driver_handlers, priv->driver_dir, 0); 
    220221         
    221222        priv->port_dir = proc_mkdir("port", priv->driver_dir); 
     
    225226                priv->ports[i] = proc_mkdir(buf, priv->port_dir); 
    226227                if (driver->port_handlers != NULL) 
    227                         add_handlers(priv, driver->port_handlers, priv->ports[i], i); 
     228                        add_handlers(driver, driver->port_handlers, priv->ports[i], i); 
    228229        } 
    229230        priv->ports[i] = NULL; 
     
    235236                priv->vlans[i] = proc_mkdir(buf, priv->vlan_dir); 
    236237                if (driver->vlan_handlers != NULL) 
    237                         add_handlers(priv, driver->vlan_handlers, priv->vlans[i], i); 
     238                        add_handlers(driver, driver->vlan_handlers, priv->vlans[i], i); 
    238239        } 
    239240        priv->vlans[i] = NULL; 
     
    243244} 
    244245 
    245 static int isspace(char c) { 
     246static inline int isspace(char c) { 
    246247        switch(c) { 
    247248                case ' ': 
     
    299300} 
    300301 
    301 int switch_parse_vlan(char *buf) 
    302 { 
    303         char vlan = 0, tag = 0, pvid_port = 0; 
    304         int untag, j; 
     302switch_vlan_config *switch_parse_vlan(switch_driver *driver, char *buf) 
     303{ 
     304        switch_vlan_config *c; 
     305        int j, u, p, s; 
     306         
     307        c = kmalloc(sizeof(switch_vlan_config), GFP_KERNEL); 
     308        memset(c, 0, sizeof(switch_vlan_config)); 
    305309 
    306310        while (isspace(*buf)) buf++; 
    307          
     311        j = 0; 
    308312        while (*buf >= '0' && *buf <= '9') { 
    309                 j = *buf++ - '0'; 
    310                 vlan |= 1 << j; 
    311                  
    312                 untag = 0; 
    313                 /* untag if needed, CPU port requires special handling */ 
    314                 if (*buf == 'u' || (j != 5 && (isspace(*buf) || *buf == 0))) { 
    315                         untag = 1; 
    316                         if (*buf) buf++; 
    317                 } else if (*buf == '*') { 
    318                         pvid_port |= (1 << j); 
    319                         buf++; 
    320                 } else if (*buf == 't' || isspace(*buf)) { 
    321                         buf++; 
    322                 } else break; 
    323  
    324                 if (!untag) 
    325                         tag |= 1 << j; 
     313                j *= 10; 
     314                j += *buf++ - '0'; 
     315 
     316                u = ((j == driver->cpuport) ? 0 : 1); 
     317                p = 0; 
     318                s = !(*buf >= '0' && *buf <= '9'); 
     319         
     320                if (s) { 
     321                        while (s && !isspace(*buf) && (*buf != 0)) { 
     322                                switch(*buf) { 
     323                                        case 'u': 
     324                                                u = 1; 
     325                                                break; 
     326                                        case 't': 
     327                                                u = 0; 
     328                                                break; 
     329                                        case '*': 
     330                                                p = 1; 
     331                                                break; 
     332                                } 
     333                                buf++; 
     334                        } 
     335                        c->port |= (1 << j); 
     336                        if (u) 
     337                                c->untag |= (1 << j); 
     338                        if (p) 
     339                                c->pvid |= (1 << j); 
     340 
     341                        j = 0; 
     342                } 
    326343                 
    327344                while (isspace(*buf)) buf++; 
    328345        } 
    329          
    330         if (*buf) 
    331                 return -1; 
    332  
    333         return (pvid_port << 16) | (tag << 8) | vlan; 
     346        if (*buf != 0) return NULL; 
     347 
     348        c->port &= (1 << driver->ports) - 1; 
     349        c->untag &= (1 << driver->ports) - 1; 
     350        c->pvid &= (1 << driver->ports) - 1; 
     351         
     352        return c; 
    334353} 
    335354 
     
    346365                        return -EINVAL; 
    347366                } 
     367                if (strcmp(list_entry(pos, switch_driver, list)->interface, driver->interface) == 0) { 
     368                        printk("There is already a switch registered on the device '%s'\n", driver->interface); 
     369                        return -EINVAL; 
     370                } 
    348371        } 
    349372 
     
    351374        memcpy(new, driver, sizeof(switch_driver)); 
    352375        new->name = strdup(driver->name); 
     376        new->interface = strdup(driver->interface); 
    353377         
    354378        if ((ret = do_register(new)) < 0) { 
  • trunk/openwrt/target/linux/package/switch/src/switch-core.h

    r2782 r2819  
    1818#endif 
    1919 
    20 typedef int (*switch_handler)(char *buf, int nr); 
     20typedef int (*switch_handler)(void *driver, char *buf, int nr); 
    2121 
    2222typedef struct { 
     
    2525} switch_config; 
    2626 
    27  
    2827typedef struct { 
    2928        struct list_head list; 
    3029        char *name; 
     30        char *interface; 
     31        int cpuport; 
    3132        int ports; 
    3233        int vlans; 
    3334        switch_config *driver_handlers, *port_handlers, *vlan_handlers; 
    3435        void *data; 
     36        void *priv; 
    3537} switch_driver; 
     38 
     39typedef struct { 
     40        u32 port, untag, pvid; 
     41} switch_vlan_config; 
    3642 
    3743 
    3844extern int switch_register_driver(switch_driver *driver); 
    3945extern void switch_unregister_driver(char *name); 
    40 extern int switch_parse_vlan(char *buf); 
     46extern switch_vlan_config *switch_parse_vlan(switch_driver *driver, char *buf); 
    4147extern int switch_parse_media(char *buf); 
    4248extern int switch_print_media(char *buf, int media); 
  • trunk/openwrt/target/linux/package/switch/src/switch-robo.c

    r2776 r2819  
    5757static struct net_device *dev; 
    5858 
    59 static int isspace(char c) { 
    60         switch(c) { 
    61                 case ' ': 
    62                 case 0x09: 
    63                 case 0x0a: 
    64                 case 0x0d: 
    65                         return 1; 
    66                 default: 
    67                         return 0; 
    68         } 
    69 } 
    70  
    7159static int do_ioctl(int cmd, void *buf) 
    7260{ 
     
    298286 
    299287 
    300 static int handle_vlan_port_read(char *buf, int nr) 
     288static int handle_vlan_port_read(void *driver, char *buf, int nr) 
    301289{ 
    302290        __u16 val16; 
     
    338326} 
    339327 
    340 static int handle_vlan_port_write(char *buf, int nr) 
    341 { 
    342         int untag = 0; 
    343         int member = 0; 
     328static int handle_vlan_port_write(void *driver, char *buf, int nr) 
     329{ 
     330        switch_driver *d = (switch_driver *) driver; 
     331        switch_vlan_config *c = switch_parse_vlan(d, buf); 
    344332        int j; 
    345333        __u16 val16; 
    346334         
    347         while (*buf >= '0' && *buf <= '9') { 
    348                 j = *buf++ - '0'; 
    349                 member |= 1 << j; 
    350                  
    351                 /* untag if needed, CPU port requires special handling */ 
    352                 if (*buf == 'u' || (j != 5 && (isspace(*buf) || *buf == 0))) { 
    353                         untag |= 1 << j; 
    354                         if (*buf) buf++; 
     335        if (c == NULL) 
     336                return -EINVAL; 
     337 
     338        for (j = 0; j < d->ports; j++) { 
     339                if ((c->untag | c->pvid) & (1 << j)) 
    355340                        /* change default vlan tag */ 
    356341                        robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1), nr); 
    357                 } else if (*buf == '*' || *buf == 't' || isspace(*buf)) { 
    358                         buf++; 
    359                 } else break; 
    360                  
    361                 while (isspace(*buf)) buf++; 
    362         } 
    363          
    364         if (*buf) { 
    365                 return -1; 
     342        } 
     343 
     344        /* write config now */ 
     345        val16 = (nr) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; 
     346        if (is_5350) { 
     347                robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, 
     348                        (1 << 20) /* valid */ | (c->untag << 6) | c->port); 
     349                robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); 
    366350        } else { 
    367                 /* write config now */ 
    368                 val16 = (nr) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; 
    369                 if (is_5350) { 
    370                         robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, 
    371                                 (1 << 20) /* valid */ | (untag << 6) | member); 
    372                         robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); 
    373                 } else { 
    374                         robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, 
    375                                 (1 << 14)  /* valid */ | (untag << 7) | member); 
    376                         robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); 
    377                 } 
    378         } 
     351                robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, 
     352                        (1 << 14)  /* valid */ | (c->untag << 7) | c->port); 
     353                robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); 
     354        } 
     355 
    379356        return 0; 
    380357} 
     
    388365                notfound = robo_probe(device); 
    389366        } 
     367        device[3]--; 
    390368         
    391369        if (notfound) 
     
    398376                switch_driver driver = { 
    399377                        name: DRIVER_NAME, 
     378                        interface: device, 
     379                        cpuport: max_ports - 1, 
    400380                        ports: max_ports, 
    401381                        vlans: max_vlans, 
Note: See TracChangeset for help on using the changeset viewer.