I would recommend not merging this patch. It is not working w/ the bgmac driver in trunk. Likely a driver issue, but just to be safe.
Thanks, Nathan On Wed, 2013-01-02 at 21:11 -0800, Nathan Hintz wrote: > Companion patch to: > https://lists.openwrt.org/pipermail/openwrt-devel/2012-December/017995.html > > Signed-off-by: Nathan Hintz <nlhi...@hotmail.com> > > Index: package/robocfg/src/etc53xx.h > =================================================================== > --- package/robocfg/src/etc53xx.h (revision 34996) > +++ package/robocfg/src/etc53xx.h (working copy) > @@ -15,9 +15,10 @@ > #define __BCM535M_H_ > > /* ROBO embedded device type */ > -#define ROBO_DEV_5380 1 > -#define ROBO_DEV_5365 2 > -#define ROBO_DEV_5350 3 > +#define ROBO_DEV_5380 1 > +#define ROBO_DEV_5365 2 > +#define ROBO_DEV_5350 3 > +#define ROBO_DEV_53115 4 > > /* BCM5325m GLOBAL PAGE REGISTER MAP */ > #ifndef _CFE_ > @@ -316,7 +317,19 @@ > #define ROBO_ARL_SEARCH_RESULT_EXT 0x2c /* ARL Search Result Extension > (5350): 8bit */ > #define ROBO_ARL_VID_ENTRY0 0x30 /* ARL VID Entry 0: 64bit */ > #define ROBO_ARL_VID_ENTRY1 0x32 /* ARL VID Entry 1: 64bit */ > +#define ROBO_ARL_SEARCH_CTRL_53115 0x50 /* ARL Search Control: 8bit */ > +#define ROBO_ARL_SEARCH_ADDR_53115 0x51 /* ARL Search Address: 16bit */ > +#define ROBO_ARL_SEARCH_RESULT_53115 0x60 /* ARL Search Result: 64bit */ > +#define ROBO_ARL_SEARCH_RESULT_EXT_53115 0x68 /* ARL Search Result Extension > (53115): 16bit */ > > +/* BCM5395/5397/5398/53115 */ > +#define ROBO_VTBL_ACCESS 0x60 /* VLAN table access: 8bit */ > +#define ROBO_VTBL_INDX 0x61 /* VLAN table address index: 16bit */ > +#define ROBO_VTBL_ENTRY 0x63 /* VLAN table entry: 32bit */ > +#define ROBO_VTBL_ACCESS_5395 0x80 /* VLAN table access: 8bit */ > +#define ROBO_VTBL_INDX_5395 0x81 /* VLAN table address index: 16bit */ > +#define ROBO_VTBL_ENTRY_5395 0x83 /* VLAN table entry: 32bit */ > + > /* BCM5325m MANAGEMENT FRAME REGISTERS (0x6) REGISTER MAP: 8/16 bit regs */ > #define ROBO_MGMT_FRAME_RD_DATA 0x00 /* Management Frame Read Data :8bit*/ > #define ROBO_MGMT_FRAME_WR_DATA 0x01 /* Management Frame Write Data:8bit*/ > @@ -342,6 +355,8 @@ > #define NUM_VLAN_TABLE_ENTRIES_5350 16 /* number of entries in VLAN table */ > #define ARL_TABLE_ADDR_5350 0x1c00 /* offset of ARL table start (5350) > */ > #endif > +#define NUM_ARL_TABLE_ENTRIES_53115 4096 /* number of entries in ARL table > (53115) */ > +#define NUM_VLAN_TABLE_ENTRIES_53115 4096 /* number of entries in VLAN table > */ > typedef struct _ROBO_MEM_ACCESS_CTRL_STRUC > { > unsigned int memAddr:14; /* 64-bit memory address */ > @@ -529,6 +544,7 @@ > #define VLAN_ID_HIGH_BITS 0 /* static high bits in table access > reg */ > #define VLAN_ID_MAX 255 /* max VLAN id */ > #define VLAN_ID_MAX5350 15 /* max VLAN id (5350) */ > +#define VLAN_ID_MAX5395 4094 /* max VLAN id (5395) */ > #define VLAN_ID_MASK VLAN_ID_MAX /* VLAN id mask */ > #ifdef BCM5380 > #define VLAN_UNTAG_SHIFT 13 /* for postioning untag bits in > write reg */ > @@ -594,26 +610,15 @@ > #define ROBO_VLAN_PORT5_DEF_TAG 0x1a /* 16b: VLAN Port 5 Default Tag > Register */ > #define ROBO_VLAN_PORT6_DEF_TAG 0x1c /* 16b: VLAN Port 6 Default Tag > Register */ > #define ROBO_VLAN_PORT7_DEF_TAG 0x1e /* 16b: VLAN Port 7 Default Tag > Register */ > +#define ROBO_VLAN_PORT8_DEF_TAG 0x20 /* 16b: VLAN Port 8 Default Tag > Register */ > +/* 53115 only */ > +#define ROBO_DUPLEX_STAT_SUMMARY_53115 0x08 /* Duplex Status Summary: 16bit > */ > +#define ROBO_JUMBO_PAGE 0x40 > +#define ROBO_JUMBO_CTRL 0x01 /* 32bit */ > +#define ROBO_JUMBO_SIZE 0x05 /* 16bit */ > > -/* obsolete */ > -#define ROBO_VLAN_PORT0_CTRL 0x00 /* 16b: Port 0 VLAN Register */ > -#define ROBO_VLAN_PORT1_CTRL 0x02 /* 16b: Port 1 VLAN Register */ > -#define ROBO_VLAN_PORT2_CTRL 0x04 /* 16b: Port 2 VLAN Register */ > -#define ROBO_VLAN_PORT3_CTRL 0x06 /* 16b: Port 3 VLAN Register */ > -#define ROBO_VLAN_PORT4_CTRL 0x08 /* 16b: Port 4 VLAN Register */ > -#define ROBO_VLAN_IM_PORT_CTRL 0x10 /* 16b: Inverse MII Port VLAN Reg */ > -#define ROBO_VLAN_SMP_PORT_CTRL 0x12 /* 16b: Serial Port VLAN Register */ > -#define ROBO_VLAN_PORTSPI_DEF_TAG 0x1c /* 16b: VLAN Port SPI Default Tag > Register */ > -#define ROBO_VLAN_PRIORITY_REMAP 0x20 /* 24b: VLAN Priority Re-Map > Register */ > - > #ifndef _CFE_ > #pragma pack() > #endif > > - > #endif /* !__BCM535M_H_ */ > - > - > - > - > - > Index: package/robocfg/src/robocfg.c > =================================================================== > --- package/robocfg/src/robocfg.c (revision 34996) > +++ package/robocfg/src/robocfg.c (working copy) > @@ -2,6 +2,7 @@ > * Broadcom BCM5325E/536x switch configuration utility > * > * Copyright (C) 2005 Oleg I. Vdovikin > + * Copyright (C) 2005 Dmitry 'dimss' Ivanov of "Telecentrs" (Riga, Latvia) > * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License > @@ -19,7 +20,6 @@ > * 02110-1301, USA. > */ > > -#include <errno.h> > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > @@ -36,6 +36,7 @@ > #include <linux/if.h> > #include <linux/sockios.h> > #include <linux/ethtool.h> > +#include <linux/types.h> > #include <linux/mii.h> > > #include "etc53xx.h" > @@ -51,87 +52,79 @@ > #define REG_MII_ADDR_READ 2 > > /* Private et.o ioctls */ > -#define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9) > -#define SIOCSETCPHYWR (SIOCDEVPRIVATE + 10) > +#define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9) > +#define SIOCSETCPHYWR (SIOCDEVPRIVATE + 10) > +#define SIOCGETCPHYRD2 (SIOCDEVPRIVATE + 12) > +#define SIOCSETCPHYWR2 (SIOCDEVPRIVATE + 13) > +#define SIOCGETCROBORD (SIOCDEVPRIVATE + 14) > +#define SIOCSETCROBOWR (SIOCDEVPRIVATE + 15) > > typedef struct { > struct ifreq ifr; > int fd; > - int et; /* use private ioctls */ > + u8 et; /* use private ioctls */ > + u8 gmii; /* gigabit mii */ > } robo_t; > > -static u16 mdio_read(robo_t *robo, u16 phy_id, u8 reg) > +static u16 __mdio_access(robo_t *robo, u16 phy_id, u8 reg, u16 val, u16 wr) > { > + static int __ioctl_args[2][3] = { {SIOCGETCPHYRD, SIOCGETCPHYRD2, > SIOCGMIIREG}, > + {SIOCSETCPHYWR, SIOCSETCPHYWR2, > SIOCSMIIREG} }; > + > if (robo->et) { > - int args[2] = { reg }; > - > + u32 args[2] = { reg, val }; > + int cmd = 0; > + > if (phy_id != ROBO_PHY_ADDR) { > - fprintf(stderr, > - "Access to real 'phy' registers unavaliable.\n" > - "Upgrade kernel driver.\n"); > - > - return 0xffff; > + cmd = 1; > + args[0] |= ((u32)phy_id) << 16; > } > - > robo->ifr.ifr_data = (caddr_t) args; > - if (ioctl(robo->fd, SIOCGETCPHYRD, (caddr_t)&robo->ifr) < 0) { > - perror("SIOCGETCPHYRD"); > + if (ioctl(robo->fd, __ioctl_args[wr][cmd], (caddr_t)&robo->ifr) > < 0) { > + if (phy_id != ROBO_PHY_ADDR) { > + fprintf(stderr, > + "Access to real 'phy' registers > unavaliable.\n" > + "Upgrade kernel driver.\n"); > + return 0xffff; > + } > + perror("ET ioctl"); > exit(1); > } > - > return args[1]; > } else { > struct mii_ioctl_data *mii = (struct mii_ioctl_data > *)&robo->ifr.ifr_data; > mii->phy_id = phy_id; > mii->reg_num = reg; > - if (ioctl(robo->fd, SIOCGMIIREG, &robo->ifr) < 0) { > - perror("SIOCGMIIREG"); > + mii->val_in = val; > + if (ioctl(robo->fd, __ioctl_args[wr][2], &robo->ifr) < 0) { > + perror("MII ioctl"); > exit(1); > } > return mii->val_out; > } > } > > -static void mdio_write(robo_t *robo, u16 phy_id, u8 reg, u16 val) > +static inline u16 mdio_read(robo_t *robo, u16 phy_id, u8 reg) > { > - if (robo->et) { > - int args[2] = { reg, val }; > + return __mdio_access(robo, phy_id, reg, 0, 0); > +} > > - if (phy_id != ROBO_PHY_ADDR) { > - fprintf(stderr, > - "Access to real 'phy' registers unavaliable.\n" > - "Upgrade kernel driver.\n"); > - return; > - } > - > - robo->ifr.ifr_data = (caddr_t) args; > - if (ioctl(robo->fd, SIOCSETCPHYWR, (caddr_t)&robo->ifr) < 0) { > - perror("SIOCGETCPHYWR"); > - exit(1); > - } > - } else { > - struct mii_ioctl_data *mii = (struct mii_ioctl_data > *)&robo->ifr.ifr_data; > - mii->phy_id = phy_id; > - mii->reg_num = reg; > - mii->val_in = val; > - if (ioctl(robo->fd, SIOCSMIIREG, &robo->ifr) < 0) { > - perror("SIOCSMIIREG"); > - exit(1); > - } > - } > +static inline void mdio_write(robo_t *robo, u16 phy_id, u8 reg, u16 val) > +{ > + __mdio_access(robo, phy_id, reg, val, 1); > } > > -static int robo_reg(robo_t *robo, u8 page, u8 reg, u8 op) > +static int _robo_reg(robo_t *robo, u8 page, u8 reg, u8 op) > { > int i = 3; > > /* set page number */ > mdio_write(robo, ROBO_PHY_ADDR, REG_MII_PAGE, > - (page << 8) | REG_MII_PAGE_ENABLE); > + (((u16)page) << 8) | REG_MII_PAGE_ENABLE); > > /* set register address */ > mdio_write(robo, ROBO_PHY_ADDR, REG_MII_ADDR, > - (reg << 8) | op); > + (((u16)reg) << 8) | op); > > /* check if operation completed */ > while (i--) { > @@ -139,9 +132,17 @@ > return 0; > } > > - fprintf(stderr, "robo_reg: timeout\n"); > - exit(1); > - > + return -1; > +} > + > +static int robo_reg(robo_t *robo, u8 page, u8 reg, u8 op) > +{ > + if (_robo_reg(robo, page, reg, op)) > + { > + fprintf(stderr, "robo_reg: %x/%x timeout\n", page, reg); > + exit(1); > + } > + > return 0; > } > > @@ -166,10 +167,20 @@ > { > robo_reg(robo, page, reg, REG_MII_ADDR_READ); > > - return mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0) + > - (mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + 1) << 16); > + return ((u32)mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0)) | > + ((u32)mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + 1) << 16); > } > > +static void robo_write(robo_t *robo, u8 page, u8 reg, u16 *val, int count) > +{ > + int i; > + > + for (i = 0; i < count; i++) > + mdio_write(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + i, val[i]); > + > + robo_reg(robo, page, reg, REG_MII_ADDR_WRITE); > +} > + > static void robo_write16(robo_t *robo, u8 page, u8 reg, u16 val16) > { > /* write data */ > @@ -181,44 +192,79 @@ > static void robo_write32(robo_t *robo, u8 page, u8 reg, u32 val32) > { > /* write data */ > - mdio_write(robo, ROBO_PHY_ADDR, REG_MII_DATA0, val32 & 65535); > - mdio_write(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + 1, val32 >> 16); > + mdio_write(robo, ROBO_PHY_ADDR, REG_MII_DATA0, (u16)(val32 & 0xFFFF)); > + mdio_write(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + 1, (u16)(val32 >> 16)); > > robo_reg(robo, page, reg, REG_MII_ADDR_WRITE); > } > > -/* checks that attached switch is 5325E/5350 */ > -static int robo_vlan5350(robo_t *robo) > +/* checks that attached switch is 5325/5352/5354/5356/5357/53115 */ > +static int robo_vlan535x(robo_t *robo, u32 phyid) > { > /* set vlan access id to 15 and read it back */ > u16 val16 = 15; > robo_write16(robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); > > /* 5365 will refuse this as it does not have this reg */ > - return (robo_read16(robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350) > == val16); > + if (robo_read16(robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350) != > val16) > + return 0; > + /* gigabit ? */ > + if (robo->et != 1 && (mdio_read(robo, 0, ROBO_MII_STAT) & 0x0100)) > + robo->gmii = ((mdio_read(robo, 0, 0x0f) & 0xf000) != 0); > + /* 53115 ? */ > + if (robo->gmii && robo_read32(robo, ROBO_STAT_PAGE, ROBO_LSA_IM_PORT) > != 0) { > + robo_write16(robo, ROBO_ARLIO_PAGE, ROBO_VTBL_INDX_5395, val16); > + robo_write16(robo, ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395, > + (1 << 7) /* start */ | 1 /* read */); > + if (robo_read16(robo, ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395) > == 1 > + && robo_read16(robo, ROBO_ARLIO_PAGE, ROBO_VTBL_INDX_5395) > == val16) > + return 4; > + } > + /* dirty trick for 5356/5357 */ > + if ((phyid & 0xfff0ffff ) == 0x5da00362 || > + (phyid & 0xfff0ffff ) == 0x5e000362) > + return 3; > + /* 5325/5352/5354*/ > + return 1; > } > > -u8 port[6] = { 0, 1, 2, 3, 4, 8 }; > -char ports[6] = { 'W', '4', '3', '2', '1', 'C' }; > +u8 port[9] = { 0, 1, 2, 3, 4, 8, 0, 0, 8}; > +char ports[] = "01234???5???????"; > +char *speed[4] = { "10", "100", "1000" , "4" }; > char *rxtx[4] = { "enabled", "rx_disabled", "tx_disabled", "disabled" }; > char *stp[8] = { "none", "disable", "block", "listen", "learn", "forward", > "6", "7" }; > +char *jumbo[2] = { "off", "on" }; > > struct { > char *name; > u16 bmcr; > -} media[5] = { { "auto", BMCR_ANENABLE | BMCR_ANRESTART }, > - { "10HD", 0 }, { "10FD", BMCR_FULLDPLX }, > - { "100HD", BMCR_SPEED100 }, { "100FD", BMCR_SPEED100 | BMCR_FULLDPLX } > }; > +} media[7] = { > + { "auto", BMCR_ANENABLE | BMCR_ANRESTART }, > + { "10HD", 0 }, > + { "10FD", BMCR_FULLDPLX }, > + { "100HD", BMCR_SPEED100 }, > + { "100FD", BMCR_SPEED100 | BMCR_FULLDPLX }, > + { "1000HD", BMCR_SPEED1000 }, > + { "1000FD", BMCR_SPEED1000 | BMCR_FULLDPLX } > +}; > > struct { > char *name; > u16 value; > -} mdix[3] = { { "auto", 0x0000 }, { "on", 0x1800 }, { "off", 0x0800 } }; > + u16 value1; > + u16 value2; > + u16 value3; > +} mdix[3] = { > + { "auto", 0x0000, 0x0000, 0x8207, 0x0000 }, > + { "on", 0x1800, 0x4000, 0x8007, 0x0080 }, > + { "off", 0x0800, 0x4000, 0x8007, 0x0000 } > +}; > > void usage() > { > - fprintf(stderr, "Broadcom BCM5325E/536x switch configuration utility\n" > - "Copyright (C) 2005 Oleg I. Vdovikin\n\n" > + fprintf(stderr, "Broadcom BCM5325/535x/536x/5311x switch configuration > utility\n" > + "Copyright (C) 2005-2008 Oleg I. Vdovikin (o...@cs.msu.su)\n" > + "Copyright (C) 2005 Dmitry 'dimss' Ivanov of \"Telecentrs\" > (Riga, Latvia)\n\n" > "This program is distributed in the hope that it will be > useful,\n" > "but WITHOUT ANY WARRANTY; without even the implied warranty > of\n" > "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" > @@ -226,10 +272,13 @@ > > fprintf(stderr, "Usage: robocfg <op> ... <op>\n" > "Operations are as below:\n" > - "\tshow\n" > + "\tshow -- show current config\n" > + "\tshowmacs -- show known MAC addresses\n" > "\tswitch <enable|disable>\n" > - "\tport <port_number> [state <%s|%s|%s|%s>]\n\t\t[stp > %s|%s|%s|%s|%s|%s] [tag <vlan_tag>]\n" > - "\t\t[media %s|%s|%s|%s|%s] [mdi-x %s|%s|%s]\n" > + "\tport <port_number> [state <%s|%s|%s|%s>]\n" > + "\t\t[stp %s|%s|%s|%s|%s|%s] [tag <vlan_tag>]\n" > + "\t\t[media %s|%s|%s|%s|%s|%s|%s]\n" > + "\t\t[mdi-x %s|%s|%s] [jumbo %s|%s]\n" > "\tvlan <vlan_number> [ports <ports_list>]\n" > "\tvlans <enable|disable|reset>\n\n" > "\tports_list should be one argument, space separated, > quoted if needed,\n" > @@ -244,113 +293,132 @@ > "robocfg switch disable vlans enable reset vlan 0 ports > \"1 2 3 4 5t\" vlan 1 ports \"0 5t\"" > " port 0 state enabled stp none switch enable\n", > rxtx[0], rxtx[1], rxtx[2], rxtx[3], stp[0], stp[1], > stp[2], stp[3], stp[4], stp[5], > - media[0].name, media[1].name, media[2].name, > media[3].name, media[4].name, > - mdix[0].name, mdix[1].name, mdix[2].name); > + media[0].name, media[1].name, media[2].name, > media[3].name, media[4].name, media[5].name, media[6].name, > + mdix[0].name, mdix[1].name, mdix[2].name, > + jumbo[0], jumbo[1]); > } > > -static robo_t robo; > -int bcm53xx_probe(const char *dev) > +int > +main(int argc, char *argv[]) > { > + u16 val16; > + u32 val32; > + u16 mac[3]; > + int i = 0, j; > + int robo535x = 0; /* 0 - 5365, 1 - 5325/5352/5354, 3 - 5356, 4 - 53115 > */ > + u32 phyid; > + > + static robo_t robo; > struct ethtool_drvinfo info; > - unsigned int phyid; > - int ret; > + > + memset(&robo, 0, sizeof(robo)); > + if ((robo.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { > + perror("socket"); > + exit(1); > + } > > - fprintf(stderr, "probing %s\n", dev); > + /* the only interface for now */ > + strcpy(robo.ifr.ifr_name, "eth0"); > > - strcpy(robo.ifr.ifr_name, dev); > memset(&info, 0, sizeof(info)); > info.cmd = ETHTOOL_GDRVINFO; > robo.ifr.ifr_data = (caddr_t)&info; > - ret = ioctl(robo.fd, SIOCETHTOOL, (caddr_t)&robo.ifr); > - if (ret < 0) { > - perror("SIOCETHTOOL"); > - return ret; > + if (ioctl(robo.fd, SIOCETHTOOL, (caddr_t)&robo.ifr) < 0) { > + perror("SIOCETHTOOL: your ethernet module is either unsupported > or outdated"); > + exit(1); > + } else > + if (strcmp(info.driver, "et0") && > + strcmp(info.driver, "b44") && > + strcmp(info.driver, "bgmac") && > + strcmp(info.driver, "bcm63xx_enet") ) { > + fprintf(stderr, "No suitable module found for %s (managed by > %s)\n", > + robo.ifr.ifr_name, info.driver); > + exit(1); > } > - > - if ( strcmp(info.driver, "et0") && > - strcmp(info.driver, "b44") && > - strcmp(info.driver, "bcm63xx_enet") ) { > - fprintf(stderr, "driver not supported %s\n", > info.driver); > - return -ENOSYS; > - } > - > + > /* try access using MII ioctls - get phy address */ > - robo.et = 0; > - if (ioctl(robo.fd, SIOCGMIIPHY, &robo.ifr) < 0) > - robo.et = 1; > + if (ioctl(robo.fd, SIOCGMIIPHY, &robo.ifr) < 0) { > + u32 args[2] = { ((u32)ROBO_PHY_ADDR) << 16, 0x0 }; > > - if (robo.et) { > - unsigned int args[2] = { 2 }; > - > robo.ifr.ifr_data = (caddr_t) args; > - ret = ioctl(robo.fd, SIOCGETCPHYRD, (caddr_t)&robo.ifr); > - if (ret < 0) { > - perror("SIOCGETCPHYRD"); > - return ret; > - } > - phyid = args[1] & 0xffff; > - > - args[0] = 3; > - robo.ifr.ifr_data = (caddr_t) args; > - ret = ioctl(robo.fd, SIOCGETCPHYRD, (caddr_t)&robo.ifr); > - if (ret < 0) { > - perror("SIOCGETCPHYRD"); > - return ret; > - } > - phyid |= args[1] << 16; > + if (ioctl(robo.fd, SIOCGETCPHYRD2, &robo.ifr) < 0) > + robo.et = 1; > + else > + robo.et = 2; > } else { > + /* got phy address check for robo address */ > struct mii_ioctl_data *mii = (struct mii_ioctl_data > *)&robo.ifr.ifr_data; > - mii->phy_id = ROBO_PHY_ADDR; > - mii->reg_num = 2; > - ret = ioctl(robo.fd, SIOCGMIIREG, &robo.ifr); > - if (ret < 0) { > - perror("SIOCGMIIREG"); > - return ret; > + if (mii->phy_id != ROBO_PHY_ADDR) { > + fprintf(stderr, "Invalid phy address (%d)\n", > mii->phy_id); > + exit(1); > } > - phyid = mii->val_out & 0xffff; > - > - mii->phy_id = ROBO_PHY_ADDR; > - mii->reg_num = 3; > - ret = ioctl(robo.fd, SIOCGMIIREG, &robo.ifr); > - if (ret < 0) { > - perror("SIOCGMIIREG"); > - return ret; > - } > - phyid |= mii->val_out << 16; > } > > + phyid = ((u32)mdio_read(&robo, ROBO_PHY_ADDR, 0x2)) | > + (((u32)mdio_read(&robo, ROBO_PHY_ADDR, 0x3)) << 16); > + if (phyid == 0 && robo.et != 1) > + phyid = ((u32)mdio_read(&robo, 0, 0x2)) | > + (((u32)mdio_read(&robo, 0, 0x3)) << 16); > + > if (phyid == 0xffffffff || phyid == 0x55210022) { > - perror("phyid"); > - return -EIO; > + fprintf(stderr, "No Robo switch in managed mode found\n"); > + exit(1); > } > > - return 0; > -} > - > -int > -main(int argc, char *argv[]) > -{ > - u16 val16; > - u16 mac[3]; > - int i = 0, j; > - int robo5350 = 0; > - u32 phyid; > + robo535x = robo_vlan535x(&robo, phyid); > + /* fprintf(stderr, "phyid %08x id %d\n", phyid, robo535x); */ > > - if ((robo.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { > - perror("socket"); > - exit(1); > - } > + for (i = 1; i < argc;) { > + if (strcasecmp(argv[i], "showmacs") == 0) > + { > + /* show MAC table of switch */ > + u16 buf[6]; > + int idx, off, base_vlan; > > - if (bcm53xx_probe("eth1")) { > - if (bcm53xx_probe("eth0")) { > - perror("bcm53xx_probe"); > - exit(1); > - } > - } > + base_vlan = 0; /*get_vid_by_idx(&robo, 0);*/ > > - robo5350 = robo_vlan5350(&robo); > - > - for (i = 1; i < argc;) { > + printf( > + "--------------------------------------\n" > + "VLAN MAC Type Port\n" > + "--------------------------------------\n"); > + robo_write16(&robo, ROBO_ARLIO_PAGE, ROBO_ARL_RW_CTRL, > 0x81); > + robo_write16(&robo, ROBO_ARLIO_PAGE, (robo535x == 4) ? > + ROBO_ARL_SEARCH_CTRL_53115 : ROBO_ARL_SEARCH_CTRL, > 0x80); > + for (idx = 0; idx < ((robo535x == 4) ? > + NUM_ARL_TABLE_ENTRIES_53115 : robo535x ? > + NUM_ARL_TABLE_ENTRIES_5350 : > NUM_ARL_TABLE_ENTRIES); idx++) > + { > + if (robo535x == 4) > + { > + off = (idx & 0x01) << 4; > + if (!off && (robo_read16(&robo, > ROBO_ARLIO_PAGE, > + ROBO_ARL_SEARCH_CTRL_53115) & 0x80) > == 0) break; > + robo_read(&robo, ROBO_ARLIO_PAGE, > + ROBO_ARL_SEARCH_RESULT_53115 + off, > buf, 4); > + robo_read(&robo, ROBO_ARLIO_PAGE, > + ROBO_ARL_SEARCH_RESULT_EXT_53115 + > off, &buf[4], 2); > + } else > + robo_read(&robo, ROBO_ARLIO_PAGE, > ROBO_ARL_SEARCH_RESULT, > + buf, robo535x ? 4 : 5); > + if ((robo535x == 4) ? (buf[5] & 0x01) : (buf[3] > & 0x8000) /* valid */) > + { > + printf("%04i > %02x:%02x:%02x:%02x:%02x:%02x %7s %c\n", > + (base_vlan | (robo535x == 4) ? > + (base_vlan | (buf[3] & > 0xfff)) : > + ((buf[3] >> 5) & 0x0f) | > + (robo535x ? 0 : > ((buf[4] & 0x0f) << 4))), > + buf[2] >> 8, buf[2] & 255, > + buf[1] >> 8, buf[1] & 255, > + buf[0] >> 8, buf[0] & 255, > + ((robo535x == 4 ? > + (buf[4] & 0x8000) : (buf[3] > & 0x4000)) ? "STATIC" : "DYNAMIC"), > + ((robo535x == 4) ? > + '0'+(buf[4] & 0x0f) : > ports[buf[3] & 0x0f]) > + ); > + } > + } > + i++; > + } else > if (strcasecmp(argv[i], "port") == 0 && (i + 1) < argc) > { > int index = atoi(argv[++i]); > @@ -379,8 +447,9 @@ > } > } else > if (strcasecmp(argv[i], "media") == 0 && ++i < > argc) { > - for (j = 0; j < 5 && > strcasecmp(argv[i], media[j].name); j++); > - if (j < 5) { > + for (j = 0; j < 7 && > strcasecmp(argv[i], media[j].name); j++); > + if (j < ((robo535x == 4) ? 7 : 5)) { > + /* change media */ > mdio_write(&robo, port[index], > MII_BMCR, media[j].bmcr); > } else { > fprintf(stderr, "Invalid media > '%s'.\n", argv[i]); > @@ -390,8 +459,18 @@ > if (strcasecmp(argv[i], "mdi-x") == 0 && ++i < > argc) { > for (j = 0; j < 3 && > strcasecmp(argv[i], mdix[j].name); j++); > if (j < 3) { > - mdio_write(&robo, port[index], > 0x1c, mdix[j].value | > - (mdio_read(&robo, > port[index], 0x1c) & ~0x1800)); > + /* change mdi-x */ > + if (robo535x == 4) { > + mdio_write(&robo, > port[index], 0x10, mdix[j].value1 | > + (mdio_read(&robo, > port[index], 0x10) & ~0x4000)); > + mdio_write(&robo, > port[index], 0x18, 0x7007); > + mdio_write(&robo, > port[index], 0x18, mdix[j].value2 | > + (mdio_read(&robo, > port[index], 0x18) & ~0x8207)); > + mdio_write(&robo, > port[index], 0x1e, mdix[j].value3 | > + (mdio_read(&robo, > port[index], 0x1e) & ~0x0080)); > + } else > + mdio_write(&robo, > port[index], 0x1c, mdix[j].value | > + (mdio_read(&robo, > port[index], 0x1c) & ~0x1800)); > } else { > fprintf(stderr, "Invalid mdi-x > '%s'.\n", argv[i]); > exit(1); > @@ -401,12 +480,24 @@ > j = atoi(argv[i]); > /* change vlan tag */ > robo_write16(&robo, ROBO_VLAN_PAGE, > ROBO_VLAN_PORT0_DEF_TAG + (index << 1), j); > + } else > + if (strcasecmp(argv[i], "jumbo") == 0 && ++i < > argc) { > + for (j = 0; j < 2 && > strcasecmp(argv[i], jumbo[j]); j++); > + if (robo535x == 4 && j < 2) { > + /* change jumbo frame feature */ > + robo_write32(&robo, > ROBO_JUMBO_PAGE, ROBO_JUMBO_CTRL, > + (robo_read32(&robo, > ROBO_JUMBO_PAGE, ROBO_JUMBO_CTRL) & > + ~(1 << port[index])) | > (j << port[index])); > + } else { > + fprintf(stderr, "Invalid jumbo > state '%s'.\n", argv[i]); > + exit(1); > + } > } else break; > } > } else > if (strcasecmp(argv[i], "vlan") == 0 && (i + 1) < argc) > { > - int index = atoi(argv[++i]); > + int vid = atoi(argv[++i]); > while (++i < argc) { > if (strcasecmp(argv[i], "ports") == 0 && ++i < > argc) { > char *ports = argv[i]; > @@ -424,7 +515,7 @@ > if (*ports) ports++; > /* change default vlan > tag */ > robo_write16(&robo, > ROBO_VLAN_PAGE, > - > ROBO_VLAN_PORT0_DEF_TAG + (j << 1), index); > + > ROBO_VLAN_PORT0_DEF_TAG + (j << 1), vid); > } else > if (*ports == '*' || *ports == > 't' || *ports == ' ') ports++; > else break; > @@ -437,10 +528,22 @@ > exit(1); > } else { > /* write config now */ > - val16 = (index) /* vlan */ | (1 > << 12) /* write */ | (1 << 13) /* enable */; > - if (robo5350) { > - robo_write32(&robo, > ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, > - (1 << 20) /* > valid */ | (untag << 6) | member); > + val16 = (vid) /* vlan */ | (1 > << 12) /* write */ | (1 << 13) /* enable */; > + if (robo535x == 4) { > + val32 = (untag << 9) | > member; > + /* entry */ > + robo_write32(&robo, > ROBO_ARLIO_PAGE, ROBO_VTBL_ENTRY_5395, val32); > + /* index */ > + robo_write16(&robo, > ROBO_ARLIO_PAGE, ROBO_VTBL_INDX_5395, vid); > + /* access */ > + robo_write16(&robo, > ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395, > + > (1 << 7) /* start */ | 0 /* write */); > + } else if (robo535x) { > + if (robo535x == 3) > + val32 = (1 << > 24) /* valid */ | (untag << 6) | member | (vid << 12); > + else > + val32 = (1 << > 20) /* valid */ | (untag << 6) | member | ((vid >> 4) << 12); > + robo_write32(&robo, > ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, val32); > robo_write16(&robo, > ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); > } else { > robo_write16(&robo, > ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, > @@ -463,12 +566,16 @@ > { > while (++i < argc) { > if (strcasecmp(argv[i], "reset") == 0) { > + if (robo535x == 4) { > + robo_write16(&robo, > ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395, > + (1 << > 7) /* start */ | 2 /* flush */); > + } else > /* reset vlan validity bit */ > - for (j = 0; j <= (robo5350 ? > VLAN_ID_MAX5350 : VLAN_ID_MAX); j++) > + for (j = 0; j <= ((robo535x == 1) ? > VLAN_ID_MAX5350 : VLAN_ID_MAX); j++) > { > /* write config now */ > val16 = (j) /* vlan */ | (1 << > 12) /* write */ | (1 << 13) /* enable */; > - if (robo5350) { > + if (robo535x) { > robo_write32(&robo, > ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, 0); > robo_write16(&robo, > ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); > } else { > @@ -499,6 +606,68 @@ > if (strcasecmp(argv[i], "show") == 0) > { > break; > + } else > + if (strncasecmp(argv[i], "robowr", 6) == 0 && (i + 2) < argc) > + { > + long pagereg = strtoul(argv[i + 1], NULL, 0); > + int size = strtoul(argv[i] + 6, NULL, 0); > + int k; > + unsigned long long int v; > + u16 buf[4]; > + > + size = (size > 0 && size <= sizeof(buf) * 16) ? (size + > 15) >> 4 : 1; > + > + v = strtoull(argv[i + 2], NULL, 0); > + for (k = 0; k < size; k++) > + { > + buf[k] = (u16 )(v & 0xFFFF); > + v >>= 16; > + } > + robo_write(&robo, pagereg >> 8, pagereg & 255, buf, > size); > + > + printf("Page 0x%02x, Reg 0x%02x: ", > + (u16 )(pagereg >> 8), (u8 )(pagereg & 255)); > + robo_read(&robo, pagereg >> 8, pagereg & 255, buf, > size); > + while (size > 0) > + printf("%04x", buf[--size]); > + printf("\n"); > + > + i += 3; > + } else > + if (strncasecmp(argv[i], "robord", 6) == 0 && (i + 1) < argc) > + { > + long pagereg = strtoul(argv[i + 1], NULL, 0); > + int size = strtoul(argv[i] + 6, NULL, 0); > + u16 buf[4]; > + > + size = (size > 0 && size <= sizeof(buf) * 16) ? (size + > 15) >> 4 : 1; > + > + printf("Page 0x%02x, Reg 0x%02x: ", > + (u16 )(pagereg >> 8), (u8 )(pagereg & 255)); > + > + robo_read(&robo, pagereg >> 8, pagereg & 255, buf, > size); > + while (size > 0) > + printf("%04x", buf[--size]); > + printf("\n"); > + > + i += 2; > + } else > + if (strcasecmp(argv[i], "dump") == 0) > + { > + for (i = 0; i < 256; i++) > + { > + if (_robo_reg(&robo, i, 0, REG_MII_ADDR_READ)) > + continue; > + > + printf("Page %02x\n", i); > + > + for (j = 0; j < 128; j++) { > + printf(" %04x%s", > + robo_read16(&robo, i, j), (j % > 16) == 15 ? "\n" : ""); > + } > + } > + > + i = 2; > } else { > fprintf(stderr, "Invalid option %s\n", argv[i]); > usage(); > @@ -513,21 +682,29 @@ > > /* show config */ > > - printf("Switch: %sabled\n", robo_read16(&robo, ROBO_CTRL_PAGE, > ROBO_SWITCH_MODE) & 2 ? "en" : "dis"); > + printf("Switch: %sabled %s\n", robo_read16(&robo, ROBO_CTRL_PAGE, > ROBO_SWITCH_MODE) & 2 ? "en" : "dis", > + robo.gmii ? "gigabit" : ""); > > for (i = 0; i < 6; i++) { > printf(robo_read16(&robo, ROBO_STAT_PAGE, > ROBO_LINK_STAT_SUMMARY) & (1 << port[i]) ? > - "Port %d(%c): %s%s " : "Port %d(%c): DOWN ", i, > ports[i], > - robo_read16(&robo, ROBO_STAT_PAGE, > ROBO_SPEED_STAT_SUMMARY) & (1 << port[i]) ? "100" : " 10", > - robo_read16(&robo, ROBO_STAT_PAGE, > ROBO_DUPLEX_STAT_SUMMARY) & (1 << port[i]) ? "FD" : "HD"); > - > + "Port %d: %4s%s " : "Port %d: DOWN ", > + (robo535x == 4) ? port[i] : i, > + speed[(robo535x == 4) ? > + (robo_read32(&robo, ROBO_STAT_PAGE, > ROBO_SPEED_STAT_SUMMARY) >> port[i] * 2) & 3 : > + (robo_read16(&robo, ROBO_STAT_PAGE, > ROBO_SPEED_STAT_SUMMARY) >> port[i]) & 1], > + robo_read16(&robo, ROBO_STAT_PAGE, (robo535x == 4) ? > + ROBO_DUPLEX_STAT_SUMMARY_53115 : > ROBO_DUPLEX_STAT_SUMMARY) & (1 << port[i]) ? "FD" : "HD"); > + > val16 = robo_read16(&robo, ROBO_CTRL_PAGE, port[i]); > - > + > printf("%s stp: %s vlan: %d ", rxtx[val16 & 3], stp[(val16 >> > 5) & 7], > robo_read16(&robo, ROBO_VLAN_PAGE, > ROBO_VLAN_PORT0_DEF_TAG + (i << 1))); > - > + > + if (robo535x == 4) > + printf("jumbo: %s ", jumbo[(robo_read32(&robo, > ROBO_JUMBO_PAGE, ROBO_JUMBO_CTRL) >> port[i]) & 1]); > + > robo_read(&robo, ROBO_STAT_PAGE, ROBO_LSA_PORT0 + port[i] * 6, > mac, 3); > - > + > printf("mac: %02x:%02x:%02x:%02x:%02x:%02x\n", > mac[2] >> 8, mac[2] & 255, mac[1] >> 8, mac[1] & 255, > mac[0] >> 8, mac[0] & 255); > } > @@ -535,23 +712,45 @@ > val16 = robo_read16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0); > > printf("VLANs: %s %sabled%s%s\n", > - robo5350 ? "BCM5325/535x" : "BCM536x", > + (robo535x == 4) ? "BCM53115" : (robo535x ? "BCM5325/535x" : > "BCM536x"), > (val16 & (1 << 7)) ? "en" : "dis", > (val16 & (1 << 6)) ? " mac_check" : "", > (val16 & (1 << 5)) ? " mac_hash" : ""); > > /* scan VLANs */ > - for (i = 0; i <= (robo5350 ? VLAN_ID_MAX5350 : VLAN_ID_MAX); i++) { > + for (i = 0; i <= ((robo535x == 4) ? VLAN_ID_MAX5395 /* slow, needs > rework, but how? */ : > + (robo535x ? VLAN_ID_MAX5350 : VLAN_ID_MAX)); i++) > + { > /* issue read */ > val16 = (i) /* vlan */ | (0 << 12) /* read */ | (1 << 13) /* > enable */; > > - if (robo5350) { > - u32 val32; > + if (robo535x == 4) { > + /* index */ > + robo_write16(&robo, ROBO_ARLIO_PAGE, > ROBO_VTBL_INDX_5395, i); > + /* access */ > + robo_write16(&robo, ROBO_ARLIO_PAGE, > ROBO_VTBL_ACCESS_5395, > + (1 << 7) /* start */ | 1 /* > read */); > + /* actual read */ > + val32 = robo_read32(&robo, ROBO_ARLIO_PAGE, > ROBO_VTBL_ENTRY_5395); > + if ((val32)) { > + printf("%4d: vlan%d:", i, i); > + for (j = 0; j <= 8; j++) { > + if (val32 & (1 << j)) { > + printf(" %d%s", j, (val32 & (1 > << (j + 9))) ? > + (j == 8 ? "u" : "") : > "t"); > + } > + } > + printf("\n"); > + } > + } else if (robo535x) { > robo_write16(&robo, ROBO_VLAN_PAGE, > ROBO_VLAN_TABLE_ACCESS_5350, val16); > /* actual read */ > val32 = robo_read32(&robo, ROBO_VLAN_PAGE, > ROBO_VLAN_READ); > - if ((val32 & (1 << 20)) /* valid */) { > - printf("vlan%d:", i); > + if ((val32 & (robo535x == 3 ? (1 << 24) : (1 << 20))) > /* valid */) { > + val16 = (robo535x == 3) > + ? ((val32 & 0xff000) >> 12) > + : ((val32 & 0xff000) >> 12) << 4; > + printf("%4d: vlan%d:", i, val16 | i); > for (j = 0; j < 6; j++) { > if (val32 & (1 << j)) { > printf(" %d%s", j, (val32 & (1 > << (j + 6))) ? > @@ -565,7 +764,7 @@ > /* actual read */ > val16 = robo_read16(&robo, ROBO_VLAN_PAGE, > ROBO_VLAN_READ); > if ((val16 & (1 << 14)) /* valid */) { > - printf("vlan%d:", i); > + printf("%4d: vlan%d:", i, i); > for (j = 0; j < 6; j++) { > if (val16 & (1 << j)) { > printf(" %d%s", j, (val16 & (1 > << (j + 7))) ? > Index: package/robocfg/Makefile > =================================================================== > --- package/robocfg/Makefile (revision 34996) > +++ package/robocfg/Makefile (working copy) > @@ -9,7 +9,7 @@ > > PKG_NAME:=robocfg > PKG_VERSION:=0.01 > -PKG_RELEASE:=1 > +PKG_RELEASE:=2 > > PKG_BUILD_DIR:=$(BUILD_DIR)/robocfg > _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel