X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fgeneric%2Ffiles%2Fdrivers%2Fnet%2Fphy%2Fb53%2Fb53_common.c;h=d911ab7fb539f946c923b45df6f413f7e29a2fff;hb=6aad15a22cf17833485a92c5e8c0034d12c78afb;hp=c1cf513266a812fdccf86990bb53e522c6cafc9d;hpb=2ccb9e15c45b7159e5c09f49ab4062c8d34b779e;p=openwrt.git diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c index c1cf513266..d911ab7fb5 100644 --- a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c +++ b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -187,8 +188,13 @@ static void b53_set_vlan_entry(struct b53_device *dev, u16 vid, u16 members, if (is5325(dev)) { u32 entry = 0; - if (members) - entry = (untag << VA_UNTAG_S) | members | VA_VALID_25; + if (members) { + entry = (untag << VA_UNTAG_S) | members; + if (dev->core_rev >= 3) + entry |= VA_VALID_25_R4 | vid << VA_VID_HIGH_S; + else + entry |= VA_VALID_25; + } b53_write32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, entry); b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | @@ -244,10 +250,9 @@ static void b53_enable_vlan(struct b53_device *dev, int enable) b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5); } - if (enable) { - if (!is63xx(dev)) - mgmt |= SM_SW_FWD_MODE; + mgmt &= ~SM_SW_FWD_MODE; + if (enable) { vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID; vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN; vc4 &= ~VC4_ING_VID_CHECK_MASK; @@ -267,7 +272,6 @@ static void b53_enable_vlan(struct b53_device *dev, int enable) vc5 &= ~VC5_VID_FFF_EN; } } else { - mgmt &= ~SM_SW_FWD_MODE; vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID); vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN); vc4 &= ~VC4_ING_VID_CHECK_MASK; @@ -362,7 +366,7 @@ static void b53_enable_ports(struct b53_device *dev) u8 port_ctrl; u16 pvlan_mask; - /* + /* * prevent leaking packets between wan and lan in unmanaged * mode through port vlans. */ @@ -371,7 +375,7 @@ static void b53_enable_ports(struct b53_device *dev) else if (is531x5(dev)) /* BCM53115 may use a different port as cpu port */ pvlan_mask = BIT(dev->sw_dev.cpu_port); - else + else pvlan_mask = BIT(B53_CPU_PORT); /* BCM5325 CPU port is at 8 */ @@ -453,10 +457,36 @@ static int b53_apply(struct b53_device *dev) return 0; } +void b53_switch_reset_gpio(struct b53_device *dev) +{ + int gpio = dev->reset_gpio; + + if (gpio < 0) + return; + + /* + * Reset sequence: RESET low(50ms)->high(20ms) + */ + gpio_set_value(gpio, 0); + mdelay(50); + + gpio_set_value(gpio, 1); + mdelay(20); + + dev->current_page = 0xff; +} + static int b53_switch_reset(struct b53_device *dev) { u8 mgmt; + b53_switch_reset_gpio(dev); + + if (is539x(dev)) { + b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x83); + b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x00); + } + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); if (!(mgmt & SM_SW_FWD_EN)) { @@ -946,11 +976,11 @@ static const struct switch_dev_ops b53_switch_ops_25 = { static const struct switch_dev_ops b53_switch_ops_65 = { .attr_global = { - .attr = b53_global_ops_25, + .attr = b53_global_ops_65, .n_attr = ARRAY_SIZE(b53_global_ops_65), }, .attr_port = { - .attr = b53_no_ops, + .attr = b53_port_ops, .n_attr = ARRAY_SIZE(b53_port_ops), }, .attr_vlan = { @@ -1116,6 +1146,7 @@ int b53_switch_init(struct b53_device *dev) { struct switch_dev *sw_dev = &dev->sw_dev; unsigned i; + int ret; for (i = 0; i < ARRAY_SIZE(b53_switch_chips); i++) { const struct b53_chip_data *chip = &b53_switch_chips[i]; @@ -1157,8 +1188,13 @@ int b53_switch_init(struct b53_device *dev) dev->enabled_ports &= ~BIT(4); break; default: +/* On the BCM47XX SoCs this is the supported internal switch.*/ +#ifndef CONFIG_BCM47XX /* BCM5325M */ return -EINVAL; +#else + break; +#endif } } else if (dev->chip_id == BCM53115_DEVICE_ID) { u64 strap_value; @@ -1189,6 +1225,13 @@ int b53_switch_init(struct b53_device *dev) if (!dev->buf) return -ENOMEM; + dev->reset_gpio = b53_switch_get_reset_gpio(dev); + if (dev->reset_gpio >= 0) { + ret = devm_gpio_request_one(dev->dev, dev->reset_gpio, GPIOF_OUT_INIT_HIGH, "robo_reset"); + if (ret) + return ret; + } + return b53_switch_reset(dev); } @@ -1262,7 +1305,12 @@ int b53_switch_detect(struct b53_device *dev) } } - return b53_read8(dev, B53_MGMT_PAGE, B53_REV_ID, &dev->core_rev); + if (dev->chip_id == BCM5325_DEVICE_ID) + return b53_read8(dev, B53_STAT_PAGE, B53_REV_ID_25, + &dev->core_rev); + else + return b53_read8(dev, B53_MGMT_PAGE, B53_REV_ID, + &dev->core_rev); } EXPORT_SYMBOL(b53_switch_detect);