From e2a6028da3eccac80337a17129174ae2d7716b66 Mon Sep 17 00:00:00 2001 From: hauke Date: Thu, 3 Jan 2013 01:53:30 +0000 Subject: brcm47xx: add a new version of the nvram rewrite patch This is the version like it was send for mainline inclusion. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34988 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-adm.c | 12 ++++++------ package/switch/src/switch-robo.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-adm.c b/package/switch/src/switch-adm.c index 9a6d32b1e..f21470ed5 100644 --- a/package/switch/src/switch-adm.c +++ b/package/switch/src/switch-adm.c @@ -38,7 +38,7 @@ #include "gpio.h" #ifdef CONFIG_BCM47XX -#include +#include #endif #define DRIVER_NAME "adm6996" @@ -89,7 +89,7 @@ static unsigned int get_gpiopin(char *pin_name, unsigned int def_pin) /* Go thru all possibilities till a match in pin name */ for (pin = 0; pin < 16; pin ++) { sprintf(name, "gpio%d", pin); - if (nvram_getenv(name, val, sizeof(val)) >= 0) { + if (bcm47xx_nvram_getenv(name, val, sizeof(val)) >= 0) { if (!strcmp(val, pin_name)) return pin; } @@ -497,10 +497,10 @@ static int detect_adm(void) int boardflags = 0; int boardnum = 0; - if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) + if (bcm47xx_nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) boardflags = simple_strtoul(buf, NULL, 0); - if (nvram_getenv("boardnum", buf, sizeof(buf)) >= 0) + if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) >= 0) boardnum = simple_strtoul(buf, NULL, 0); if ((boardnum == 44) && (boardflags == 0x0388)) { /* Trendware TEW-411BRP+ */ @@ -519,9 +519,9 @@ static int detect_adm(void) eedi = get_gpiopin("adm_eedi", 4); eerc = get_gpiopin("adm_rc", 0); - } else if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) { + } else if (bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) { if (strcmp(buf, "bcm94710dev") == 0) { - if (nvram_getenv("boardnum", buf, sizeof(buf)) >= 0) { + if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) >= 0) { if (strncmp(buf, "42", 2) == 0) { /* WRT54G v1.1 hack */ eecs = 2; diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index f1160c889..3751653a6 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -35,7 +35,7 @@ #include "etc53xx.h" #ifdef CONFIG_BCM47XX -#include +#include #endif #define DRIVER_NAME "bcm53xx" @@ -236,7 +236,7 @@ static int robo_switch_enable(void) #ifdef CONFIG_BCM47XX /* WAN port LED, except for Netgear WGT634U */ - if (nvram_getenv("nvram_type", buf, sizeof(buf)) >= 0) { + if (bcm47xx_nvram_getenv("nvram_type", buf, sizeof(buf)) >= 0) { if (strcmp(buf, "cfe") != 0) robo_write16(ROBO_CTRL_PAGE, 0x16, 0x1F); } -- cgit v1.2.3 From e3e6518cfee3a14f1165beca0e2b71486243fd39 Mon Sep 17 00:00:00 2001 From: hauke Date: Thu, 3 Jan 2013 01:57:19 +0000 Subject: switch: improve error messages This is in part based on a patch send by Nathan Hintz git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34991 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 3751653a6..f9b306cf1 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -103,8 +103,7 @@ static u16 mdio_read(__u16 phy_id, __u8 reg) err = do_ioctl(SIOCGMIIREG); if (err < 0) { - printk(KERN_ERR PFX - "[%s:%d] SIOCGMIIREG failed! err: %i\n", __FILE__, __LINE__, err); + printk(KERN_ERR PFX "failed to read mdio reg %i with err %i.\n", reg, err); return 0xffff; } @@ -123,8 +122,7 @@ static void mdio_write(__u16 phy_id, __u8 reg, __u16 val) err = do_ioctl(SIOCSMIIREG); if (err < 0) { - printk(KERN_ERR PFX - "[%s:%d] SIOCSMIIREG failed! err: %i\n", __FILE__, __LINE__, err); + printk(KERN_ERR PFX "failed to write mdio reg: %i with err %i.\n", reg, err); return; } } @@ -147,7 +145,7 @@ static int robo_reg(__u8 page, __u8 reg, __u8 op) return 0; } - printk(KERN_ERR PFX "[%s:%d] timeout in robo_reg!\n", __FILE__, __LINE__); + printk(KERN_ERR PFX "timeout in robo_reg on page %i and reg %i with op %i.\n", page, reg, op); return 0; } @@ -224,7 +222,7 @@ static int robo_switch_enable(void) robo_write16(ROBO_CTRL_PAGE, ROBO_SWITCH_MODE, val); val = robo_read16(ROBO_CTRL_PAGE, ROBO_SWITCH_MODE); if (!(val & (1 << 1))) { - printk("Failed to enable switch\n"); + printk(KERN_ERR PFX "Failed to enable switch\n"); return -EBUSY; } @@ -262,15 +260,15 @@ static int robo_probe(char *devname) unsigned int i; int err = 1; - printk(KERN_INFO PFX "Probing device %s: ", devname); + printk(KERN_INFO PFX "Probing device '%s'\n", devname); strcpy(robo.ifr.ifr_name, devname); if ((robo.dev = dev_get_by_name(&init_net, devname)) == NULL) { - printk("No such device\n"); + printk(KERN_ERR PFX "No such device\n"); return 1; } if (!robo.dev->netdev_ops || !robo.dev->netdev_ops->ndo_do_ioctl) { - printk("ndo_do_ioctl not implemented in ethernet driver\n"); + printk(KERN_ERR PFX "ndo_do_ioctl not implemented in ethernet driver\n"); return 1; } @@ -280,8 +278,9 @@ static int robo_probe(char *devname) robo.port[5] = 8; /* try access using MII ioctls - get phy address */ - if (do_ioctl(SIOCGMIIPHY) < 0) { - printk("error while accessing MII phy registers with ioctls\n"); + err = do_ioctl(SIOCGMIIPHY); + if (err < 0) { + printk(KERN_ERR PFX "error (%i) while accessing MII phy registers with ioctls\n", err); goto done; } @@ -290,7 +289,7 @@ static int robo_probe(char *devname) if ((mii->phy_id != ROBO_PHY_ADDR) && (mii->phy_id != ROBO_PHY_ADDR_BCM63XX) && (mii->phy_id != ROBO_PHY_ADDR_TG3)) { - printk("Invalid phy address (%d)\n", mii->phy_id); + printk(KERN_ERR PFX "Invalid phy address (%d)\n", mii->phy_id); goto done; } @@ -298,7 +297,7 @@ static int robo_probe(char *devname) (mdio_read(ROBO_PHY_ADDR, 0x3) << 16); if (phyid == 0xffffffff || phyid == 0x55210022) { - printk("No Robo switch in managed mode found, phy_id = 0x%08x\n", phyid); + printk(KERN_ERR PFX "No Robo switch in managed mode found, phy_id = 0x%08x\n", phyid); goto done; } @@ -319,8 +318,8 @@ static int robo_probe(char *devname) goto done; err = 0; - printk("found a 5%s%x!%s\n", robo.devid & 0xff00 ? "" : "3", robo.devid, - robo.is_5350 ? " It's a 5350." : ""); + printk(KERN_INFO PFX "found a 5%s%x!%s at %s\n", robo.devid & 0xff00 ? "" : "3", robo.devid, + robo.is_5350 ? " It's a 5350." : "", devname); done: if (err) { -- cgit v1.2.3 From e3a81c46a5b399e5579144aec5222d3c82055a63 Mon Sep 17 00:00:00 2001 From: hauke Date: Thu, 3 Jan 2013 01:58:01 +0000 Subject: switch: ROBO Switch Gigabit MII Support I wrote this patch some time ago because I had a need for one of the Gigabit ports (Linksys E3000) to be forced to 100FD. This is based on the robocfg sources included w/ the RT-N16 sources from ASUS. Since work is progressing on a BGMAC driver that could be included in OpenWRT, this may be useful to someone else. In testing, forcing the speed to 10/100 or 1000 worked fine; however, when trying to force full-duplex mode, the result was always half-duplex. I was not able to isolate the source of the problem (this patch, driver or H/W limitation). The only way I could get it to work was to set the port to Auto, but then only advertise 100FD (not included in this patch). I have a modified version of the robocfg package as well, I'd have to clean it up a little first (remove the full-duplex hack) before submitting it if there is interest. Signed-off-by: Nathan Hintz git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34992 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/etc53xx.h | 45 +++++++------- package/switch/src/switch-adm.c | 2 +- package/switch/src/switch-core.c | 16 +++-- package/switch/src/switch-core.h | 1 + package/switch/src/switch-robo.c | 124 ++++++++++++++++++++++++++++++++++++--- 5 files changed, 154 insertions(+), 34 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/etc53xx.h b/package/switch/src/etc53xx.h index d5b1310cb..c21d1bc79 100644 --- a/package/switch/src/etc53xx.h +++ b/package/switch/src/etc53xx.h @@ -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,6 +317,18 @@ typedef struct _ROBO_ARL_SEARCH_RESULT_MCAST_STRUC #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*/ @@ -342,6 +355,8 @@ typedef struct _ROBO_ARL_SEARCH_RESULT_MCAST_STRUC #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 @@ typedef struct _ROBO_VLAN_CTRL0_STRUC #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 @@ typedef struct _ROBO_VLAN_READ_WRITE_STRUC_5350 #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 */ - -/* 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 */ +#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 */ #ifndef _CFE_ #pragma pack() #endif - #endif /* !__BCM535M_H_ */ - - - - - diff --git a/package/switch/src/switch-adm.c b/package/switch/src/switch-adm.c index f21470ed5..2d0fcc35a 100644 --- a/package/switch/src/switch-adm.c +++ b/package/switch/src/switch-adm.c @@ -386,7 +386,7 @@ static int handle_port_media_write(void *driver, char *buf, int nr) int media = switch_parse_media(buf); int reg = adm_rreg(0, port_conf[nr]); - if (media < 0) + if (media < 0 || media & SWITCH_MEDIA_1000) return -1; reg &= ~((1 << 1) | (1 << 2) | (1 << 3)); diff --git a/package/switch/src/switch-core.c b/package/switch/src/switch-core.c index 79b4e93f0..c77e4bba4 100644 --- a/package/switch/src/switch-core.c +++ b/package/switch/src/switch-core.c @@ -26,7 +26,7 @@ * enable_vlan: "0", "1" * port// * enabled: "0", "1" - * media: "AUTO", "100FD", "100HD", "10FD", "10HD" + * media: "AUTO", "1000FD", "1000HD", "100FD", "100HD", "10FD", "10HD" * vlan// * ports: same syntax as for nvram's vlan*ports (eg. "1 2 3 4 5*") */ @@ -305,6 +305,10 @@ int switch_parse_media(char *buf) if (strncmp(str, "AUTO", 4) == 0) return SWITCH_MEDIA_AUTO; + else if (strncmp(str, "1000FD", 6) == 0) + return SWITCH_MEDIA_1000 | SWITCH_MEDIA_FD; + else if (strncmp(str, "1000HD", 6) == 0) + return SWITCH_MEDIA_1000; else if (strncmp(str, "100FD", 5) == 0) return SWITCH_MEDIA_100 | SWITCH_MEDIA_FD; else if (strncmp(str, "100HD", 5) == 0) @@ -322,14 +326,18 @@ int switch_print_media(char *buf, int media) if (media & SWITCH_MEDIA_AUTO) len = sprintf(buf, "Auto"); + else if (media == (SWITCH_MEDIA_1000 | SWITCH_MEDIA_FD)) + len = sprintf(buf, "1000FD"); + else if (media == SWITCH_MEDIA_1000) + len = sprintf(buf, "1000HD"); else if (media == (SWITCH_MEDIA_100 | SWITCH_MEDIA_FD)) len = sprintf(buf, "100FD"); else if (media == SWITCH_MEDIA_100) - len = sprintf(buf, "100HD"); + len = sprintf(buf, "100HD"); else if (media == SWITCH_MEDIA_FD) - len = sprintf(buf, "10FD"); + len = sprintf(buf, "10FD"); else if (media == 0) - len = sprintf(buf, "10HD"); + len = sprintf(buf, "10HD"); else len = sprintf(buf, "Invalid"); diff --git a/package/switch/src/switch-core.h b/package/switch/src/switch-core.h index a2114cf92..7192f7b0f 100644 --- a/package/switch/src/switch-core.h +++ b/package/switch/src/switch-core.h @@ -8,6 +8,7 @@ #define SWITCH_MEDIA_AUTO 1 #define SWITCH_MEDIA_100 2 #define SWITCH_MEDIA_FD 4 +#define SWITCH_MEDIA_1000 8 typedef int (*switch_handler)(void *driver, char *buf, int nr); diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index f9b306cf1..f3a0eacf1 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -72,6 +72,7 @@ struct robo_switch { char *device; /* The device name string (ethX) */ u16 devid; /* ROBO_DEVICE_ID_53xx */ bool is_5350; + u8 gmii; /* gigabit mii */ struct ifreq ifr; struct net_device *dev; unsigned char port[6]; @@ -147,7 +148,7 @@ static int robo_reg(__u8 page, __u8 reg, __u8 op) printk(KERN_ERR PFX "timeout in robo_reg on page %i and reg %i with op %i.\n", page, reg, op); - return 0; + return 1; } /* @@ -173,7 +174,7 @@ static __u32 robo_read32(__u8 page, __u8 reg) { robo_reg(page, reg, REG_MII_ADDR_READ); - return mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0) + + return mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0) | (mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0 + 1) << 16); } @@ -188,21 +189,40 @@ static void robo_write16(__u8 page, __u8 reg, __u16 val16) static void robo_write32(__u8 page, __u8 reg, __u32 val32) { /* write data */ - mdio_write(ROBO_PHY_ADDR, REG_MII_DATA0, val32 & 65535); + mdio_write(ROBO_PHY_ADDR, REG_MII_DATA0, val32 & 0xFFFF); mdio_write(ROBO_PHY_ADDR, REG_MII_DATA0 + 1, val32 >> 16); robo_reg(page, reg, REG_MII_ADDR_WRITE); } -/* checks that attached switch is 5325E/5350 */ -static int robo_vlan5350(void) +/* checks that attached switch is 5325/5352/5354/5356/5357/53115 */ +static int robo_vlan5350(__u32 phyid) { /* set vlan access id to 15 and read it back */ __u16 val16 = 15; robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); /* 5365 will refuse this as it does not have this reg */ - return (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350) == val16); + if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350) != val16) + return 0; + /* gigabit ? */ + if (mdio_read(0, ROBO_MII_STAT) & 0x0100) + robo.gmii = ((mdio_read(0, 0x0f) & 0xf000) != 0); + /* 53115 ? */ + if (robo.gmii && robo_read32(ROBO_STAT_PAGE, ROBO_LSA_IM_PORT) != 0) { + robo_write16(ROBO_ARLIO_PAGE, ROBO_VTBL_INDX_5395, val16); + robo_write16(ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395, + (1 << 7) /* start */ | 1 /* read */); + if (robo_read16(ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395) == 1 && + robo_read16(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; } static int robo_switch_enable(void) @@ -259,6 +279,7 @@ static int robo_probe(char *devname) __u32 phyid; unsigned int i; int err = 1; + struct mii_ioctl_data *mii; printk(KERN_INFO PFX "Probing device '%s'\n", devname); strcpy(robo.ifr.ifr_name, devname); @@ -285,7 +306,7 @@ static int robo_probe(char *devname) } /* got phy address check for robo address */ - struct mii_ioctl_data *mii = if_mii(&robo.ifr); + mii = if_mii(&robo.ifr); if ((mii->phy_id != ROBO_PHY_ADDR) && (mii->phy_id != ROBO_PHY_ADDR_BCM63XX) && (mii->phy_id != ROBO_PHY_ADDR_TG3)) { @@ -310,7 +331,7 @@ static int robo_probe(char *devname) } if (!robo.devid) robo.devid = ROBO_DEVICE_ID_5325; /* Fake it */ - robo.is_5350 = robo_vlan5350(); + robo.is_5350 = robo_vlan5350(phyid); robo_switch_reset(); err = robo_switch_enable(); @@ -445,6 +466,80 @@ static int handle_enable_write(void *driver, char *buf, int nr) return 0; } +static int handle_port_enable_read(void *driver, char *buf, int nr) +{ + return sprintf(buf, "%d\n", ((robo_read16(ROBO_CTRL_PAGE, robo.port[nr]) & 3) == 3 ? 0 : 1)); +} + +static int handle_port_enable_write(void *driver, char *buf, int nr) +{ + u16 val16; + + if (buf[0] == '0') + val16 = 3; /* disabled */ + else if (buf[0] == '1') + val16 = 0; /* enabled */ + else + return -EINVAL; + + robo_write16(ROBO_CTRL_PAGE, robo.port[nr], + (robo_read16(ROBO_CTRL_PAGE, robo.port[nr]) & ~3) | val16); + + return 0; +} + +static int handle_port_media_read(void *driver, char *buf, int nr) +{ + u16 bmcr = mdio_read(robo.port[nr], MII_BMCR); + int media, len; + + if (bmcr & BMCR_ANENABLE) + media = SWITCH_MEDIA_AUTO; + else { + if (bmcr & BMCR_SPEED1000) + media = SWITCH_MEDIA_1000; + else if (bmcr & BMCR_SPEED100) + media = SWITCH_MEDIA_100; + else + media = 0; + + if (bmcr & BMCR_FULLDPLX) + media |= SWITCH_MEDIA_FD; + } + + len = switch_print_media(buf, media); + return len + sprintf(buf + len, "\n"); +} + +static int handle_port_media_write(void *driver, char *buf, int nr) +{ + int media = switch_parse_media(buf); + u16 bmcr, bmcr_mask; + + if (media & SWITCH_MEDIA_AUTO) + bmcr = BMCR_ANENABLE | BMCR_ANRESTART; + else { + if (media & SWITCH_MEDIA_1000) { + if (!robo.gmii) + return -EINVAL; + bmcr = BMCR_SPEED1000; + } + else if (media & SWITCH_MEDIA_100) + bmcr = BMCR_SPEED100; + else + bmcr = 0; + + if (media & SWITCH_MEDIA_FD) + bmcr |= BMCR_FULLDPLX; + } + + bmcr_mask = ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_ANRESTART); + mdio_write(robo.port[nr], MII_BMCR, + (mdio_read(robo.port[nr], MII_BMCR) & bmcr_mask) | bmcr); + + return 0; +} + static int handle_enable_vlan_read(void *driver, char *buf, int nr) { return sprintf(buf, "%d\n", (((robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0) & (1 << 7)) == (1 << 7)) ? 1 : 0)); @@ -539,6 +634,17 @@ static int __init robo_init(void) .write = handle_reset }, { NULL, }, }; + static const switch_config port[] = { + { + .name = "enable", + .read = handle_port_enable_read, + .write = handle_port_enable_write + }, { + .name = "media", + .read = handle_port_media_read, + .write = handle_port_media_write + }, { NULL, }, + }; static const switch_config vlan[] = { { .name = "ports", @@ -554,7 +660,7 @@ static int __init robo_init(void) .ports = 6, .vlans = 16, .driver_handlers = cfg, - .port_handlers = NULL, + .port_handlers = port, .vlan_handlers = vlan, }; if (robo.devid != ROBO_DEVICE_ID_5325) { -- cgit v1.2.3 From 2a26e021e1be150d25b9075b0c234a086823d5ef Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:01:50 +0000 Subject: switch: run cleanfile over the source code git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35577 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index f3a0eacf1..1372fbd62 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ @@ -314,7 +314,7 @@ static int robo_probe(char *devname) goto done; } - phyid = mdio_read(ROBO_PHY_ADDR, 0x2) | + phyid = mdio_read(ROBO_PHY_ADDR, 0x2) | (mdio_read(ROBO_PHY_ADDR, 0x3) << 16); if (phyid == 0xffffffff || phyid == 0x55210022) { @@ -534,7 +534,7 @@ static int handle_port_media_write(void *driver, char *buf, int nr) } bmcr_mask = ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_ANRESTART); - mdio_write(robo.port[nr], MII_BMCR, + mdio_write(robo.port[nr], MII_BMCR, (mdio_read(robo.port[nr], MII_BMCR) & bmcr_mask) | bmcr); return 0; -- cgit v1.2.3 From fa24ec668f8441354bad7e274a7b333219b3fff2 Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:02:20 +0000 Subject: switch: improve error handling in robo_probe() git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35578 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 1372fbd62..e33c30ec4 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -278,7 +278,7 @@ static int robo_probe(char *devname) { __u32 phyid; unsigned int i; - int err = 1; + int err = -1; struct mii_ioctl_data *mii; printk(KERN_INFO PFX "Probing device '%s'\n", devname); @@ -286,11 +286,13 @@ static int robo_probe(char *devname) if ((robo.dev = dev_get_by_name(&init_net, devname)) == NULL) { printk(KERN_ERR PFX "No such device\n"); - return 1; + err = -ENODEV; + goto err_done; } if (!robo.dev->netdev_ops || !robo.dev->netdev_ops->ndo_do_ioctl) { printk(KERN_ERR PFX "ndo_do_ioctl not implemented in ethernet driver\n"); - return 1; + err = -ENXIO; + goto err_put; } robo.device = devname; @@ -302,7 +304,7 @@ static int robo_probe(char *devname) err = do_ioctl(SIOCGMIIPHY); if (err < 0) { printk(KERN_ERR PFX "error (%i) while accessing MII phy registers with ioctls\n", err); - goto done; + goto err_put; } /* got phy address check for robo address */ @@ -311,7 +313,8 @@ static int robo_probe(char *devname) (mii->phy_id != ROBO_PHY_ADDR_BCM63XX) && (mii->phy_id != ROBO_PHY_ADDR_TG3)) { printk(KERN_ERR PFX "Invalid phy address (%d)\n", mii->phy_id); - goto done; + err = -ENODEV; + goto err_put; } phyid = mdio_read(ROBO_PHY_ADDR, 0x2) | @@ -319,7 +322,8 @@ static int robo_probe(char *devname) if (phyid == 0xffffffff || phyid == 0x55210022) { printk(KERN_ERR PFX "No Robo switch in managed mode found, phy_id = 0x%08x\n", phyid); - goto done; + err = -ENODEV; + goto err_put; } /* Get the device ID */ @@ -336,17 +340,16 @@ static int robo_probe(char *devname) robo_switch_reset(); err = robo_switch_enable(); if (err) - goto done; - err = 0; + goto err_put; printk(KERN_INFO PFX "found a 5%s%x!%s at %s\n", robo.devid & 0xff00 ? "" : "3", robo.devid, robo.is_5350 ? " It's a 5350." : "", devname); -done: - if (err) { - dev_put(robo.dev); - robo.dev = NULL; - } + return 0; +err_put: + dev_put(robo.dev); + robo.dev = NULL; +err_done: return err; } -- cgit v1.2.3 From a72556358d30103084e9ebf0561d68db5fca89a1 Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:02:41 +0000 Subject: switch: reset switch before using it. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35579 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 72 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index e33c30ec4..38aa9eff5 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "switch-core.h" @@ -73,6 +74,8 @@ struct robo_switch { u16 devid; /* ROBO_DEVICE_ID_53xx */ bool is_5350; u8 gmii; /* gigabit mii */ + int gpio_robo_reset; + int gpio_lanports_enable; struct ifreq ifr; struct net_device *dev; unsigned char port[6]; @@ -274,6 +277,27 @@ static void robo_switch_reset(void) } } +#ifdef CONFIG_BCM47XX +static int get_gpio_pin(const char *name) +{ + int i, err; + char nvram_var[10]; + char buf[30]; + + for (i = 0; i < 16; i++) { + err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i); + if (err <= 0) + continue; + err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf)); + if (err <= 0) + continue; + if (!strcmp(name, buf)) + return i; + } + return -1; +} +#endif + static int robo_probe(char *devname) { __u32 phyid; @@ -317,13 +341,46 @@ static int robo_probe(char *devname) goto err_put; } +#ifdef CONFIG_BCM47XX + robo.gpio_lanports_enable = get_gpio_pin("lanports_enable"); + if (robo.gpio_lanports_enable >= 0) { + err = gpio_request(robo.gpio_lanports_enable, "lanports_enable"); + if (err) { + printk(KERN_ERR PFX "error (%i) requesting lanports_enable gpio (%i)\n", + err, robo.gpio_lanports_enable); + goto err_put; + } + gpio_direction_output(robo.gpio_lanports_enable, 1); + mdelay(5); + } + + robo.gpio_robo_reset = get_gpio_pin("robo_reset"); + if (robo.gpio_robo_reset >= 0) { + err = gpio_request(robo.gpio_robo_reset, "robo_reset"); + if (err) { + printk(KERN_ERR PFX "error (%i) requesting robo_reset gpio (%i)\n", + err, robo.gpio_robo_reset); + goto err_gpio_robo; + } + gpio_set_value(robo.gpio_robo_reset, 0); + gpio_direction_output(robo.gpio_robo_reset, 1); + gpio_set_value(robo.gpio_robo_reset, 0); + mdelay(50); + + gpio_set_value(robo.gpio_robo_reset, 1); + mdelay(20); + } else { + // TODO: reset the internal robo switch + } +#endif + phyid = mdio_read(ROBO_PHY_ADDR, 0x2) | (mdio_read(ROBO_PHY_ADDR, 0x3) << 16); if (phyid == 0xffffffff || phyid == 0x55210022) { printk(KERN_ERR PFX "No Robo switch in managed mode found, phy_id = 0x%08x\n", phyid); err = -ENODEV; - goto err_put; + goto err_gpio_lanports; } /* Get the device ID */ @@ -340,12 +397,19 @@ static int robo_probe(char *devname) robo_switch_reset(); err = robo_switch_enable(); if (err) - goto err_put; + goto err_gpio_lanports; printk(KERN_INFO PFX "found a 5%s%x!%s at %s\n", robo.devid & 0xff00 ? "" : "3", robo.devid, robo.is_5350 ? " It's a 5350." : "", devname); return 0; + +err_gpio_lanports: + if (robo.gpio_lanports_enable >= 0) + gpio_free(robo.gpio_lanports_enable); +err_gpio_robo: + if (robo.gpio_robo_reset >= 0) + gpio_free(robo.gpio_robo_reset); err_put: dev_put(robo.dev); robo.dev = NULL; @@ -680,6 +744,10 @@ static void __exit robo_exit(void) switch_unregister_driver(DRIVER_NAME); if (robo.dev) dev_put(robo.dev); + if (robo.gpio_robo_reset >= 0) + gpio_free(robo.gpio_robo_reset); + if (robo.gpio_lanports_enable >= 0) + gpio_free(robo.gpio_lanports_enable); kfree(robo.device); } -- cgit v1.2.3 From 7e9ad0bcc3c9b3d83ae6424e5a68d2d32849a2d4 Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:03:03 +0000 Subject: switch: the BCM5365 is a special switch and the BCM5350 or BCM5325 is the normal case. This makes it easier to compare this code with the code from the Broadcom SDK. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35580 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/etc53xx.h | 14 ++++---- package/switch/src/switch-robo.c | 73 ++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 47 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/etc53xx.h b/package/switch/src/etc53xx.h index c21d1bc79..0cd217e51 100644 --- a/package/switch/src/etc53xx.h +++ b/package/switch/src/etc53xx.h @@ -542,9 +542,9 @@ typedef struct _ROBO_VLAN_CTRL0_STRUC #define VLAN_TABLE_WRITE 1 /* for read/write state in table access reg */ #define VLAN_TABLE_READ 0 /* for read/write state in table access reg */ #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_MAX 15 /* max VLAN id (5350) */ +#define VLAN_ID_MAX_5365 255 /* max VLAN id */ +#define VLAN_ID_MAX_5395 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 */ @@ -595,10 +595,10 @@ typedef struct _ROBO_VLAN_READ_WRITE_STRUC_5350 #define ROBO_VLAN_CTRL3 0x03 /* 8b: VLAN Control 3 Register */ #define ROBO_VLAN_CTRL4 0x04 /* 8b: VLAN Control 4 Register */ #define ROBO_VLAN_CTRL5 0x05 /* 8b: VLAN Control 5 Register */ -#define ROBO_VLAN_TABLE_ACCESS 0x08 /* 14b: VLAN Table Access Register */ -#define ROBO_VLAN_TABLE_ACCESS_5350 0x06 /* 14b: VLAN Table Access Register (5350) */ -#define ROBO_VLAN_WRITE 0x0a /* 15b: VLAN Write Register */ -#define ROBO_VLAN_WRITE_5350 0x08 /* 15b: VLAN Write Register (5350) */ +#define ROBO_VLAN_TABLE_ACCESS_5365 0x08 /* 14b: VLAN Table Access Register */ +#define ROBO_VLAN_TABLE_ACCESS 0x06 /* 14b: VLAN Table Access Register (5350) */ +#define ROBO_VLAN_WRITE_5365 0x0a /* 15b: VLAN Write Register */ +#define ROBO_VLAN_WRITE 0x08 /* 15b: VLAN Write Register (5350) */ #define ROBO_VLAN_READ 0x0c /* 15b: VLAN Read Register */ #define ROBO_VLAN_PORT0_DEF_TAG 0x10 /* 16b: VLAN Port 0 Default Tag Register */ #define ROBO_VLAN_PORT1_DEF_TAG 0x12 /* 16b: VLAN Port 1 Default Tag Register */ diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 38aa9eff5..9c78d8281 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -72,8 +72,8 @@ struct robo_switch { char *device; /* The device name string (ethX) */ u16 devid; /* ROBO_DEVICE_ID_53xx */ - bool is_5350; - u8 gmii; /* gigabit mii */ + bool is_5365; + bool gmii; /* gigabit mii */ int gpio_robo_reset; int gpio_lanports_enable; struct ifreq ifr; @@ -198,34 +198,22 @@ static void robo_write32(__u8 page, __u8 reg, __u32 val32) robo_reg(page, reg, REG_MII_ADDR_WRITE); } -/* checks that attached switch is 5325/5352/5354/5356/5357/53115 */ -static int robo_vlan5350(__u32 phyid) +/* checks that attached switch is 5365 */ +static bool robo_bcm5365(void) { /* set vlan access id to 15 and read it back */ __u16 val16 = 15; - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); /* 5365 will refuse this as it does not have this reg */ - if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350) != val16) - return 0; - /* gigabit ? */ + return robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS) != val16; +} + +static bool robo_gmii(void) +{ if (mdio_read(0, ROBO_MII_STAT) & 0x0100) - robo.gmii = ((mdio_read(0, 0x0f) & 0xf000) != 0); - /* 53115 ? */ - if (robo.gmii && robo_read32(ROBO_STAT_PAGE, ROBO_LSA_IM_PORT) != 0) { - robo_write16(ROBO_ARLIO_PAGE, ROBO_VTBL_INDX_5395, val16); - robo_write16(ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395, - (1 << 7) /* start */ | 1 /* read */); - if (robo_read16(ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395) == 1 && - robo_read16(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; + return ((mdio_read(0, 0x0f) & 0xf000) != 0); + return false; } static int robo_switch_enable(void) @@ -392,7 +380,12 @@ static int robo_probe(char *devname) } if (!robo.devid) robo.devid = ROBO_DEVICE_ID_5325; /* Fake it */ - robo.is_5350 = robo_vlan5350(phyid); + if (robo.devid == ROBO_DEVICE_ID_5325) + robo.is_5365 = robo_bcm5365(); + else + robo.is_5365 = false; + + robo.gmii = robo_gmii(); robo_switch_reset(); err = robo_switch_enable(); @@ -400,7 +393,7 @@ static int robo_probe(char *devname) goto err_gpio_lanports; printk(KERN_INFO PFX "found a 5%s%x!%s at %s\n", robo.devid & 0xff00 ? "" : "3", robo.devid, - robo.is_5350 ? " It's a 5350." : "", devname); + robo.is_5365 ? " It's a BCM5365." : "", devname); return 0; @@ -426,9 +419,9 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr) val16 = (nr) /* vlan */ | (0 << 12) /* read */ | (1 << 13) /* enable */; - if (robo.is_5350) { + if (!robo.is_5365) { u32 val32; - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); /* actual read */ val32 = robo_read32(ROBO_VLAN_PAGE, ROBO_VLAN_READ); if ((val32 & (1 << 20)) /* valid */) { @@ -448,7 +441,7 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr) len += sprintf(buf + len, "\n"); } } else { - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16); /* actual read */ val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_READ); if ((val16 & (1 << 14)) /* valid */) { @@ -504,13 +497,13 @@ static int handle_vlan_port_write(void *driver, char *buf, int nr) } val16 = (nr) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; - if (robo.is_5350) { - robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, - (1 << 20) /* valid */ | (c->untag << 6) | c->port); - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); - } else { - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, + if (robo.is_5365) { + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365, (1 << 14) /* valid */ | (c->untag << 7) | c->port); + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16); + } else { + robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, + (1 << 20) /* valid */ | (c->untag << 6) | c->port); robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); } @@ -643,14 +636,14 @@ static int handle_reset(void *driver, char *buf, int nr) set_switch(0); /* reset vlans */ - for (j = 0; j <= ((robo.is_5350) ? VLAN_ID_MAX5350 : VLAN_ID_MAX); j++) { + for (j = 0; j <= ((robo.is_5365) ? VLAN_ID_MAX_5365 : VLAN_ID_MAX); j++) { /* write config now */ val16 = (j) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; - if (robo.is_5350) - robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, 0); + if (robo.is_5365) + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365, 0); else - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, 0); - robo_write16(ROBO_VLAN_PAGE, robo.is_5350 ? ROBO_VLAN_TABLE_ACCESS_5350 : + robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, 0); + robo_write16(ROBO_VLAN_PAGE, robo.is_5365 ? ROBO_VLAN_TABLE_ACCESS_5365 : ROBO_VLAN_TABLE_ACCESS, val16); } -- cgit v1.2.3 From 1e779318e345ed83a51915307ede3d1e578d1301 Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:03:27 +0000 Subject: switch: reverse if else in handle_vlan_port_read() git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35581 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 9c78d8281..0ab2f6934 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -419,17 +419,17 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr) val16 = (nr) /* vlan */ | (0 << 12) /* read */ | (1 << 13) /* enable */; - if (!robo.is_5365) { - u32 val32; - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); + if (robo.is_5365) { + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16); /* actual read */ - val32 = robo_read32(ROBO_VLAN_PAGE, ROBO_VLAN_READ); - if ((val32 & (1 << 20)) /* valid */) { + val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_READ); + if ((val16 & (1 << 14)) /* valid */) { for (j = 0; j < 6; j++) { - if (val32 & (1 << j)) { + if (val16 & (1 << j)) { len += sprintf(buf + len, "%d", j); - if (val32 & (1 << (j + 6))) { - if (j == 5) buf[len++] = 'u'; + if (val16 & (1 << (j + 7))) { + if (j == 5) + buf[len++] = 'u'; } else { buf[len++] = 't'; if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr) @@ -441,15 +441,17 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr) len += sprintf(buf + len, "\n"); } } else { - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16); + u32 val32; + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); /* actual read */ - val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_READ); - if ((val16 & (1 << 14)) /* valid */) { + val32 = robo_read32(ROBO_VLAN_PAGE, ROBO_VLAN_READ); + if ((val32 & (1 << 20)) /* valid */) { for (j = 0; j < 6; j++) { - if (val16 & (1 << j)) { + if (val32 & (1 << j)) { len += sprintf(buf + len, "%d", j); - if (val16 & (1 << (j + 7))) { - if (j == 5) buf[len++] = 'u'; + if (val32 & (1 << (j + 6))) { + if (j == 5) + buf[len++] = 'u'; } else { buf[len++] = 't'; if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr) -- cgit v1.2.3 From 0d72440fc6085ca9144c0eebd3a6bd9d02e1448d Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:03:47 +0000 Subject: switch: fix switches with more than 6 ports This is based on a patch by jcharest and the Broadcom SDK. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35582 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 0ab2f6934..0e39c8fe5 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -78,7 +78,7 @@ struct robo_switch { int gpio_lanports_enable; struct ifreq ifr; struct net_device *dev; - unsigned char port[6]; + unsigned char port[9]; }; /* Currently we can only have one device in the system. */ @@ -308,9 +308,6 @@ static int robo_probe(char *devname) } robo.device = devname; - for (i = 0; i < 5; i++) - robo.port[i] = i; - robo.port[5] = 8; /* try access using MII ioctls - get phy address */ err = do_ioctl(SIOCGMIIPHY); @@ -386,6 +383,14 @@ static int robo_probe(char *devname) robo.is_5365 = false; robo.gmii = robo_gmii(); + if (robo.devid == ROBO_DEVICE_ID_5325) { + for (i = 0; i < 5; i++) + robo.port[i] = i; + } else { + for (i = 0; i < 8; i++) + robo.port[i] = i; + } + robo.port[i] = ROBO_IM_PORT_CTRL; robo_switch_reset(); err = robo_switch_enable(); -- cgit v1.2.3 From 5b0d941a4dab394beb8c93e138ae84641e7b9de7 Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:04:18 +0000 Subject: switch: improve robo_switch_enable() This is based on a patch by jcharest and the Broadcom SDK. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35583 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 0e39c8fe5..41f0c1826 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -237,10 +237,14 @@ static int robo_switch_enable(void) return -EBUSY; } + /* No spanning tree for unmanaged mode */ last_port = (robo.devid == ROBO_DEVICE_ID_5398) ? - ROBO_PORT6_CTRL : ROBO_PORT3_CTRL; - for (i = ROBO_PORT0_CTRL; i < last_port + 1; i++) + ROBO_PORT7_CTRL : ROBO_PORT4_CTRL; + for (i = ROBO_PORT0_CTRL; i <= last_port; i++) robo_write16(ROBO_CTRL_PAGE, i, 0); + + /* No spanning tree on IMP port too */ + robo_write16(ROBO_CTRL_PAGE, ROBO_IM_PORT_CTRL, 0); } #ifdef CONFIG_BCM47XX -- cgit v1.2.3 From f39bb781b8e91b9a592ca948da3a2590e0a95e8d Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:04:50 +0000 Subject: 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. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35584 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 135 ++++++++++++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 30 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 41f0c1826..aaccdd9f6 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -74,6 +74,7 @@ struct robo_switch { u16 devid; /* ROBO_DEVICE_ID_53xx */ bool is_5365; bool gmii; /* gigabit mii */ + u8 corerev; int gpio_robo_reset; int gpio_lanports_enable; struct ifreq ifr; @@ -419,8 +420,7 @@ err_done: return err; } - -static int handle_vlan_port_read(void *driver, char *buf, int nr) +static int handle_vlan_port_read_old(switch_driver *d, char *buf, int nr) { __u16 val16; int len = 0; @@ -433,11 +433,11 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr) /* actual read */ val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_READ); if ((val16 & (1 << 14)) /* valid */) { - for (j = 0; j < 6; j++) { + for (j = 0; j < d->ports; j++) { if (val16 & (1 << j)) { len += sprintf(buf + len, "%d", j); if (val16 & (1 << (j + 7))) { - if (j == 5) + if (j == d->cpuport) buf[len++] = 'u'; } else { buf[len++] = 't'; @@ -455,11 +455,11 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr) /* actual read */ val32 = robo_read32(ROBO_VLAN_PAGE, ROBO_VLAN_READ); if ((val32 & (1 << 20)) /* valid */) { - for (j = 0; j < 6; j++) { + for (j = 0; j < d->ports; j++) { if (val32 & (1 << j)) { len += sprintf(buf + len, "%d", j); - if (val32 & (1 << (j + 6))) { - if (j == 5) + if (val32 & (1 << (j + d->ports))) { + if (j == d->cpuport) buf[len++] = 'u'; } else { buf[len++] = 't'; @@ -478,45 +478,120 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr) return len; } -static int handle_vlan_port_write(void *driver, char *buf, int nr) +static int handle_vlan_port_read_new(switch_driver *d, char *buf, int nr) { - switch_driver *d = (switch_driver *) driver; - switch_vlan_config *c = switch_parse_vlan(d, buf); + __u8 vtbl_entry, vtbl_index, vtbl_access; + __u32 val32; + int len = 0; int j; - __u16 val16; - if (c == NULL) - return -EINVAL; + if ((robo.devid == ROBO_DEVICE_ID_5395) || + (robo.devid == ROBO_DEVICE_ID_53115)) { + vtbl_access = ROBO_VTBL_ACCESS_5395; + vtbl_index = ROBO_VTBL_INDX_5395; + vtbl_entry = ROBO_VTBL_ENTRY_5395; + } else { + vtbl_access = ROBO_VTBL_ACCESS; + vtbl_index = ROBO_VTBL_INDX; + vtbl_entry = ROBO_VTBL_ENTRY; + } + robo_write16(ROBO_ARLIO_PAGE, vtbl_index, nr); + robo_write16(ROBO_ARLIO_PAGE, vtbl_access, (1 << 7) | (1 << 0)); + val32 = robo_read32(ROBO_ARLIO_PAGE, vtbl_entry); for (j = 0; j < d->ports; j++) { - if ((c->untag | c->pvid) & (1 << j)) - /* change default vlan tag */ - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1), nr); + if (val32 & (1 << j)) { + len += sprintf(buf + len, "%d", j); + if (val32 & (1 << (j + d->ports))) { + if (j == d->cpuport) + buf[len++] = 'u'; + } else { + buf[len++] = 't'; + if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr) + buf[len++] = '*'; + } + buf[len++] = '\t'; + } } + len += sprintf(buf + len, "\n"); + buf[len] = '\0'; + return len; +} - /* write config now */ +static int handle_vlan_port_read(void *driver, char *buf, int nr) +{ + switch_driver *d = (switch_driver *) driver; - if (robo.devid != ROBO_DEVICE_ID_5325) { - __u8 regoff = ((robo.devid == ROBO_DEVICE_ID_5395) || - (robo.devid == ROBO_DEVICE_ID_53115)) ? 0x20 : 0; + if (robo.devid != ROBO_DEVICE_ID_5325) + return handle_vlan_port_read_new(d, buf, nr); + else + return handle_vlan_port_read_old(d, buf, nr); +} - robo_write32(ROBO_ARLIO_PAGE, 0x63 + regoff, (c->untag << 9) | c->port); - robo_write16(ROBO_ARLIO_PAGE, 0x61 + regoff, nr); - robo_write16(ROBO_ARLIO_PAGE, 0x60 + regoff, 1 << 7); - kfree(c); - return 0; - } +static void handle_vlan_port_write_old(switch_driver *d, switch_vlan_config *c, int nr) +{ + __u16 val16; + __u32 val32; + __u32 untag = ((c->untag & ~(1 << d->cpuport)) << d->ports); + /* write config now */ val16 = (nr) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; if (robo.is_5365) { - robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365, - (1 << 14) /* valid */ | (c->untag << 7) | c->port); + robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365, + (1 << 14) /* valid */ | (untag << 1 ) | c->port); robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16); } else { - robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, - (1 << 20) /* valid */ | (c->untag << 6) | c->port); + if (robo.corerev < 3) + val32 = (1 << 20) | ((nr >> 4) << 12) | untag | c->port; + else + val32 = (1 << 24) | (nr << 12) | untag | c->port; + robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, val32); robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); } +} + +static void handle_vlan_port_write_new(switch_driver *d, switch_vlan_config *c, int nr) +{ + __u8 vtbl_entry, vtbl_index, vtbl_access; + __u32 untag = ((c->untag & ~(1 << d->cpuport)) << d->ports); + + /* write config now */ + if ((robo.devid == ROBO_DEVICE_ID_5395) || + (robo.devid == ROBO_DEVICE_ID_53115)) { + vtbl_access = ROBO_VTBL_ACCESS_5395; + vtbl_index = ROBO_VTBL_INDX_5395; + vtbl_entry = ROBO_VTBL_ENTRY_5395; + } else { + vtbl_access = ROBO_VTBL_ACCESS; + vtbl_index = ROBO_VTBL_INDX; + vtbl_entry = ROBO_VTBL_ENTRY; + } + + robo_write32(ROBO_ARLIO_PAGE, vtbl_entry, untag | c->port); + robo_write16(ROBO_ARLIO_PAGE, vtbl_index, nr); + robo_write16(ROBO_ARLIO_PAGE, vtbl_access, 1 << 7); +} + +static int handle_vlan_port_write(void *driver, char *buf, int nr) +{ + switch_driver *d = (switch_driver *)driver; + switch_vlan_config *c = switch_parse_vlan(d, buf); + int j; + + if (c == NULL) + return -EINVAL; + + for (j = 0; j < d->ports; j++) { + if ((c->untag | c->pvid) & (1 << j)) { + /* change default vlan tag */ + robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1), nr); + } + } + + if (robo.devid != ROBO_DEVICE_ID_5325) + handle_vlan_port_write_new(d, c, nr); + else + handle_vlan_port_write_old(d, c, nr); kfree(c); return 0; -- cgit v1.2.3 From fe6514cec0f6d694ecfd8adb0d75ce3711f3d073 Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:05:13 +0000 Subject: switch: resetting and enabling vlan write for gigabit switches This patch makes it possible to reset and enable writing vlans to recent switchs. This is based on a patch by jcharest and the Broadcom SDK. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35585 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 52 ++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index aaccdd9f6..2aacc3666 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -693,12 +693,16 @@ static int handle_enable_vlan_read(void *driver, char *buf, int nr) static int handle_enable_vlan_write(void *driver, char *buf, int nr) { + __u16 val16; int disable = ((buf[0] != '1') ? 1 : 0); + val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0); robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0, disable ? 0 : - (1 << 7) /* 802.1Q VLAN */ | (3 << 5) /* mac check and hash */); + val16 | (1 << 7) /* 802.1Q VLAN */ | (3 << 5) /* mac check and hash */); + + val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL1); robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_CTRL1, disable ? 0 : - (robo.devid == ROBO_DEVICE_ID_5325 ? (1 << 1) : + val16 | (robo.devid == ROBO_DEVICE_ID_5325 ? (1 << 1) : 0) | (1 << 2) | (1 << 3)); /* RSV multicast */ if (robo.devid != ROBO_DEVICE_ID_5325) @@ -712,15 +716,11 @@ static int handle_enable_vlan_write(void *driver, char *buf, int nr) return 0; } -static int handle_reset(void *driver, char *buf, int nr) +static void handle_reset_old(switch_driver *d, char *buf, int nr) { - switch_driver *d = (switch_driver *) driver; int j; __u16 val16; - /* disable switching */ - set_switch(0); - /* reset vlans */ for (j = 0; j <= ((robo.is_5365) ? VLAN_ID_MAX_5365 : VLAN_ID_MAX); j++) { /* write config now */ @@ -733,6 +733,44 @@ static int handle_reset(void *driver, char *buf, int nr) ROBO_VLAN_TABLE_ACCESS, val16); } +} + +static void handle_reset_new(switch_driver *d, char *buf, int nr) +{ + int j; + __u8 vtbl_entry, vtbl_index, vtbl_access; + + if ((robo.devid == ROBO_DEVICE_ID_5395) || + (robo.devid == ROBO_DEVICE_ID_53115)) { + vtbl_access = ROBO_VTBL_ACCESS_5395; + vtbl_index = ROBO_VTBL_INDX_5395; + vtbl_entry = ROBO_VTBL_ENTRY_5395; + } else { + vtbl_access = ROBO_VTBL_ACCESS; + vtbl_index = ROBO_VTBL_INDX; + vtbl_entry = ROBO_VTBL_ENTRY; + } + + for (j = 0; j <= VLAN_ID_MAX; j++) { + /* write config now */ + robo_write32(ROBO_ARLIO_PAGE, vtbl_entry, 0); + robo_write16(ROBO_ARLIO_PAGE, vtbl_index, j); + robo_write16(ROBO_ARLIO_PAGE, vtbl_access, 1 << 7); + } +} + +static int handle_reset(void *driver, char *buf, int nr) +{ + int j; + switch_driver *d = (switch_driver *) driver; + + /* disable switching */ + set_switch(0); + + if (robo.devid != ROBO_DEVICE_ID_5325) + handle_reset_new(d, buf, nr); + else + handle_reset_old(d, buf, nr); /* reset ports to a known good state */ for (j = 0; j < d->ports; j++) { -- cgit v1.2.3 From ecb8ddded5785d75acc2b7639c30691a6ab10e04 Mon Sep 17 00:00:00 2001 From: hauke Date: Wed, 13 Feb 2013 16:05:32 +0000 Subject: switch: add support for BCM53125 git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35586 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-robo.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 2aacc3666..57240a3fd 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -63,6 +63,7 @@ #define ROBO_DEVICE_ID_5397 0x97 #define ROBO_DEVICE_ID_5398 0x98 #define ROBO_DEVICE_ID_53115 0x3115 +#define ROBO_DEVICE_ID_53125 0x3125 /* Private et.o ioctls */ #define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9) @@ -248,6 +249,13 @@ static int robo_switch_enable(void) robo_write16(ROBO_CTRL_PAGE, ROBO_IM_PORT_CTRL, 0); } + if (robo.devid == ROBO_DEVICE_ID_53125) { + /* Make IM port status link by default */ + val = robo_read16(ROBO_CTRL_PAGE, ROBO_PORT_OVERRIDE_CTRL) | 0xb1; + robo_write16(ROBO_CTRL_PAGE, ROBO_PORT_OVERRIDE_CTRL, val); + // TODO: init EEE feature + } + #ifdef CONFIG_BCM47XX /* WAN port LED, except for Netgear WGT634U */ if (bcm47xx_nvram_getenv("nvram_type", buf, sizeof(buf)) >= 0) { @@ -486,7 +494,8 @@ static int handle_vlan_port_read_new(switch_driver *d, char *buf, int nr) int j; if ((robo.devid == ROBO_DEVICE_ID_5395) || - (robo.devid == ROBO_DEVICE_ID_53115)) { + (robo.devid == ROBO_DEVICE_ID_53115) || + (robo.devid == ROBO_DEVICE_ID_53125)) { vtbl_access = ROBO_VTBL_ACCESS_5395; vtbl_index = ROBO_VTBL_INDX_5395; vtbl_entry = ROBO_VTBL_ENTRY_5395; @@ -557,7 +566,8 @@ static void handle_vlan_port_write_new(switch_driver *d, switch_vlan_config *c, /* write config now */ if ((robo.devid == ROBO_DEVICE_ID_5395) || - (robo.devid == ROBO_DEVICE_ID_53115)) { + (robo.devid == ROBO_DEVICE_ID_53115) || + (robo.devid == ROBO_DEVICE_ID_53125)) { vtbl_access = ROBO_VTBL_ACCESS_5395; vtbl_index = ROBO_VTBL_INDX_5395; vtbl_entry = ROBO_VTBL_ENTRY_5395; @@ -741,7 +751,8 @@ static void handle_reset_new(switch_driver *d, char *buf, int nr) __u8 vtbl_entry, vtbl_index, vtbl_access; if ((robo.devid == ROBO_DEVICE_ID_5395) || - (robo.devid == ROBO_DEVICE_ID_53115)) { + (robo.devid == ROBO_DEVICE_ID_53115) || + (robo.devid == ROBO_DEVICE_ID_53125)) { vtbl_access = ROBO_VTBL_ACCESS_5395; vtbl_index = ROBO_VTBL_INDX_5395; vtbl_entry = ROBO_VTBL_ENTRY_5395; -- cgit v1.2.3 From 03eaf681abe52e6ea4bf52670f0a69baceb30245 Mon Sep 17 00:00:00 2001 From: hauke Date: Thu, 14 Feb 2013 12:36:13 +0000 Subject: switch: export cpuport, ports and vlans via /proc git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35595 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-core.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-core.c b/package/switch/src/switch-core.c index c77e4bba4..ab0754c94 100644 --- a/package/switch/src/switch-core.c +++ b/package/switch/src/switch-core.c @@ -138,6 +138,24 @@ static int handle_driver_version(void *driver, char *buf, int nr) return sprintf(buf, "%s\n", version); } +static int handle_driver_cpuport(void *driver, char *buf, int nr) +{ + int cpuport = ((switch_driver *) driver)->cpuport; + return sprintf(buf, "%i\n", cpuport); +} + +static int handle_driver_ports(void *driver, char *buf, int nr) +{ + int ports = ((switch_driver *) driver)->ports; + return sprintf(buf, "%i\n", ports); +} + +static int handle_driver_vlans(void *driver, char *buf, int nr) +{ + int vlans = ((switch_driver *) driver)->vlans; + return sprintf(buf, "%i\n", vlans); +} + static void add_handler(switch_driver *driver, const switch_config *handler, struct proc_dir_entry *parent, int nr) { switch_priv *priv = (switch_priv *) driver->data; @@ -221,6 +239,9 @@ static void do_unregister(switch_driver *driver) switch_config global_driver_handlers[] = { {"driver", handle_driver_name, NULL}, {"version", handle_driver_version, NULL}, + {"cpuport", handle_driver_cpuport, NULL}, + {"ports", handle_driver_ports, NULL}, + {"vlans", handle_driver_vlans, NULL}, {NULL, NULL, NULL} }; -- cgit v1.2.3 From d8af1489e0e3cbeba49897e8f6dee1572295dd43 Mon Sep 17 00:00:00 2001 From: hauke Date: Thu, 14 Feb 2013 12:36:52 +0000 Subject: switch: export name of device found via /proc git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35596 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/switch/src/switch-adm.c | 1 + package/switch/src/switch-core.c | 7 +++++++ package/switch/src/switch-core.h | 2 ++ package/switch/src/switch-robo.c | 7 ++++++- 4 files changed, 16 insertions(+), 1 deletion(-) (limited to 'package/switch/src') diff --git a/package/switch/src/switch-adm.c b/package/switch/src/switch-adm.c index 2d0fcc35a..8c0ddc6c9 100644 --- a/package/switch/src/switch-adm.c +++ b/package/switch/src/switch-adm.c @@ -578,6 +578,7 @@ static int __init adm_init(void) port_handlers: port, vlan_handlers: vlan, }; + snprintf(driver.dev_name, SWITCH_NAME_BUFSZ, DRIVER_NAME); if (!detect_adm()) return -ENODEV; diff --git a/package/switch/src/switch-core.c b/package/switch/src/switch-core.c index ab0754c94..fc8a6bf2c 100644 --- a/package/switch/src/switch-core.c +++ b/package/switch/src/switch-core.c @@ -156,6 +156,12 @@ static int handle_driver_vlans(void *driver, char *buf, int nr) return sprintf(buf, "%i\n", vlans); } +static int handle_driver_dev_name(void *driver, char *buf, int nr) +{ + char *dev_name = ((switch_driver *) driver)->dev_name; + return sprintf(buf, "%s\n", dev_name); +} + static void add_handler(switch_driver *driver, const switch_config *handler, struct proc_dir_entry *parent, int nr) { switch_priv *priv = (switch_priv *) driver->data; @@ -242,6 +248,7 @@ switch_config global_driver_handlers[] = { {"cpuport", handle_driver_cpuport, NULL}, {"ports", handle_driver_ports, NULL}, {"vlans", handle_driver_vlans, NULL}, + {"dev_name", handle_driver_dev_name, NULL}, {NULL, NULL, NULL} }; diff --git a/package/switch/src/switch-core.h b/package/switch/src/switch-core.h index 7192f7b0f..cc520e493 100644 --- a/package/switch/src/switch-core.h +++ b/package/switch/src/switch-core.h @@ -4,6 +4,7 @@ #include #include #define SWITCH_MAX_BUFSZ 4096 +#define SWITCH_NAME_BUFSZ 16 #define SWITCH_MEDIA_AUTO 1 #define SWITCH_MEDIA_100 2 @@ -28,6 +29,7 @@ typedef struct { const switch_config *driver_handlers, *port_handlers, *vlan_handlers; void *data; void *priv; + char dev_name[SWITCH_NAME_BUFSZ]; } switch_driver; typedef struct { diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c index 57240a3fd..f7159729b 100644 --- a/package/switch/src/switch-robo.c +++ b/package/switch/src/switch-robo.c @@ -3,6 +3,7 @@ * * Copyright (C) 2005 Felix Fietkau * Copyright (C) 2008 Michael Buesch + * Copyright (C) 2013 Hauke Mehrtens * Based on 'robocfg' by Oleg I. Vdovikin * * This program is free software; you can redistribute it and/or @@ -40,7 +41,7 @@ #endif #define DRIVER_NAME "bcm53xx" -#define DRIVER_VERSION "0.02" +#define DRIVER_VERSION "0.03" #define PFX "roboswitch: " #define ROBO_PHY_ADDR 0x1E /* robo switch phy address */ @@ -862,6 +863,10 @@ static int __init robo_init(void) driver.ports = 9; driver.cpuport = 8; } + if (robo.is_5365) + snprintf(driver.dev_name, SWITCH_NAME_BUFSZ, "BCM5365"); + else + snprintf(driver.dev_name, SWITCH_NAME_BUFSZ, "BCM5%s%x", robo.devid & 0xff00 ? "" : "3", robo.devid); return switch_register_driver(&driver); } -- cgit v1.2.3