Commit 3d5cc728 authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-b53-bcm_sf2-cleanups'

Florian Fainelli says:

====================
net: dsa: b53/bcm_sf2 cleanups

This patch series is a first pass set of clean-ups to reduce the number of LOCs
between b53 and bcm_sf2 and sharing as many functions as possible.

There is a number of additional cleanups queued up locally that require more
thorough testing.

Changes in v3:

- remove one extra argument for the b53_build_io_op macro (David Laight)
- added additional Reviewed-by tags from Vivien

Changes in v2:

- added Reviewed-by tags from Vivien
- added a missing EXPORT_SYMBOL() in patch 8
- fixed a typo in patch 5
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d43a9d19 f86ad77f
...@@ -484,7 +484,7 @@ static int b53_fast_age_vlan(struct b53_device *dev, u16 vid) ...@@ -484,7 +484,7 @@ static int b53_fast_age_vlan(struct b53_device *dev, u16 vid)
return b53_flush_arl(dev, FAST_AGE_VLAN); return b53_flush_arl(dev, FAST_AGE_VLAN);
} }
static void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port)
{ {
struct b53_device *dev = ds->priv; struct b53_device *dev = ds->priv;
unsigned int i; unsigned int i;
...@@ -500,9 +500,9 @@ static void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) ...@@ -500,9 +500,9 @@ static void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port)
b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), pvlan); b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), pvlan);
} }
} }
EXPORT_SYMBOL(b53_imp_vlan_setup);
static int b53_enable_port(struct dsa_switch *ds, int port, int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
struct phy_device *phy)
{ {
struct b53_device *dev = ds->priv; struct b53_device *dev = ds->priv;
unsigned int cpu_port = dev->cpu_port; unsigned int cpu_port = dev->cpu_port;
...@@ -523,11 +523,15 @@ static int b53_enable_port(struct dsa_switch *ds, int port, ...@@ -523,11 +523,15 @@ static int b53_enable_port(struct dsa_switch *ds, int port,
b53_imp_vlan_setup(ds, cpu_port); b53_imp_vlan_setup(ds, cpu_port);
/* If EEE was enabled, restore it */
if (dev->ports[port].eee.eee_enabled)
b53_eee_enable_set(ds, port, true);
return 0; return 0;
} }
EXPORT_SYMBOL(b53_enable_port);
static void b53_disable_port(struct dsa_switch *ds, int port, void b53_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
struct phy_device *phy)
{ {
struct b53_device *dev = ds->priv; struct b53_device *dev = ds->priv;
u8 reg; u8 reg;
...@@ -537,20 +541,67 @@ static void b53_disable_port(struct dsa_switch *ds, int port, ...@@ -537,20 +541,67 @@ static void b53_disable_port(struct dsa_switch *ds, int port,
reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE; reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE;
b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg); b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg);
} }
EXPORT_SYMBOL(b53_disable_port);
static void b53_enable_cpu_port(struct b53_device *dev) void b53_brcm_hdr_setup(struct dsa_switch *ds, int port)
{
struct b53_device *dev = ds->priv;
u8 hdr_ctl, val;
u16 reg;
/* Resolve which bit controls the Broadcom tag */
switch (port) {
case 8:
val = BRCM_HDR_P8_EN;
break;
case 7:
val = BRCM_HDR_P7_EN;
break;
case 5:
val = BRCM_HDR_P5_EN;
break;
default:
val = 0;
break;
}
/* Enable Broadcom tags for IMP port */
b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl);
hdr_ctl |= val;
b53_write8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, hdr_ctl);
/* Registers below are only accessible on newer devices */
if (!is58xx(dev))
return;
/* Enable reception Broadcom tag for CPU TX (switch RX) to
* allow us to tag outgoing frames
*/
b53_read16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_RX_DIS, &reg);
reg &= ~BIT(port);
b53_write16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_RX_DIS, reg);
/* Enable transmission of Broadcom tags from the switch (CPU RX) to
* allow delivering frames to the per-port net_devices
*/
b53_read16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_TX_DIS, &reg);
reg &= ~BIT(port);
b53_write16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_TX_DIS, reg);
}
EXPORT_SYMBOL(b53_brcm_hdr_setup);
static void b53_enable_cpu_port(struct b53_device *dev, int port)
{ {
unsigned int cpu_port = dev->cpu_port;
u8 port_ctrl; u8 port_ctrl;
/* BCM5325 CPU port is at 8 */ /* BCM5325 CPU port is at 8 */
if ((is5325(dev) || is5365(dev)) && cpu_port == B53_CPU_PORT_25) if ((is5325(dev) || is5365(dev)) && port == B53_CPU_PORT_25)
cpu_port = B53_CPU_PORT; port = B53_CPU_PORT;
port_ctrl = PORT_CTRL_RX_BCST_EN | port_ctrl = PORT_CTRL_RX_BCST_EN |
PORT_CTRL_RX_MCST_EN | PORT_CTRL_RX_MCST_EN |
PORT_CTRL_RX_UCST_EN; PORT_CTRL_RX_UCST_EN;
b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(cpu_port), port_ctrl); b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), port_ctrl);
} }
static void b53_enable_mib(struct b53_device *dev) static void b53_enable_mib(struct b53_device *dev)
...@@ -816,12 +867,13 @@ static int b53_setup(struct dsa_switch *ds) ...@@ -816,12 +867,13 @@ static int b53_setup(struct dsa_switch *ds)
if (ret) if (ret)
dev_err(ds->dev, "failed to apply configuration\n"); dev_err(ds->dev, "failed to apply configuration\n");
/* Configure IMP/CPU port, disable unused ports. Enabled
* ports will be configured with .port_enable
*/
for (port = 0; port < dev->num_ports; port++) { for (port = 0; port < dev->num_ports; port++) {
if (BIT(port) & ds->enabled_port_mask) if (dsa_is_cpu_port(ds, port))
b53_enable_port(ds, port, NULL); b53_enable_cpu_port(dev, port);
else if (dsa_is_cpu_port(ds, port)) else if (!(BIT(port) & ds->enabled_port_mask))
b53_enable_cpu_port(dev);
else
b53_disable_port(ds, port, NULL); b53_disable_port(ds, port, NULL);
} }
...@@ -832,6 +884,7 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, ...@@ -832,6 +884,7 @@ static void b53_adjust_link(struct dsa_switch *ds, int port,
struct phy_device *phydev) struct phy_device *phydev)
{ {
struct b53_device *dev = ds->priv; struct b53_device *dev = ds->priv;
struct ethtool_eee *p = &dev->ports[port].eee;
u8 rgmii_ctrl = 0, reg = 0, off; u8 rgmii_ctrl = 0, reg = 0, off;
if (!phy_is_pseudo_fixed_link(phydev)) if (!phy_is_pseudo_fixed_link(phydev))
...@@ -953,6 +1006,9 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, ...@@ -953,6 +1006,9 @@ static void b53_adjust_link(struct dsa_switch *ds, int port,
b53_write8(dev, B53_CTRL_PAGE, po_reg, gmii_po); b53_write8(dev, B53_CTRL_PAGE, po_reg, gmii_po);
} }
} }
/* Re-negotiate EEE if it was enabled already */
p->eee_enabled = b53_eee_init(ds, port, phydev);
} }
int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering) int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering)
...@@ -1484,6 +1540,69 @@ void b53_mirror_del(struct dsa_switch *ds, int port, ...@@ -1484,6 +1540,69 @@ void b53_mirror_del(struct dsa_switch *ds, int port,
} }
EXPORT_SYMBOL(b53_mirror_del); EXPORT_SYMBOL(b53_mirror_del);
void b53_eee_enable_set(struct dsa_switch *ds, int port, bool enable)
{
struct b53_device *dev = ds->priv;
u16 reg;
b53_read16(dev, B53_EEE_PAGE, B53_EEE_EN_CTRL, &reg);
if (enable)
reg |= BIT(port);
else
reg &= ~BIT(port);
b53_write16(dev, B53_EEE_PAGE, B53_EEE_EN_CTRL, reg);
}
EXPORT_SYMBOL(b53_eee_enable_set);
/* Returns 0 if EEE was not enabled, or 1 otherwise
*/
int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy)
{
int ret;
ret = phy_init_eee(phy, 0);
if (ret)
return 0;
b53_eee_enable_set(ds, port, true);
return 1;
}
EXPORT_SYMBOL(b53_eee_init);
int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
{
struct b53_device *dev = ds->priv;
struct ethtool_eee *p = &dev->ports[port].eee;
u16 reg;
if (is5325(dev) || is5365(dev))
return -EOPNOTSUPP;
b53_read16(dev, B53_EEE_PAGE, B53_EEE_LPI_INDICATE, &reg);
e->eee_enabled = p->eee_enabled;
e->eee_active = !!(reg & BIT(port));
return 0;
}
EXPORT_SYMBOL(b53_get_mac_eee);
int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
{
struct b53_device *dev = ds->priv;
struct ethtool_eee *p = &dev->ports[port].eee;
if (is5325(dev) || is5365(dev))
return -EOPNOTSUPP;
p->eee_enabled = e->eee_enabled;
b53_eee_enable_set(ds, port, e->eee_enabled);
return 0;
}
EXPORT_SYMBOL(b53_set_mac_eee);
static const struct dsa_switch_ops b53_switch_ops = { static const struct dsa_switch_ops b53_switch_ops = {
.get_tag_protocol = b53_get_tag_protocol, .get_tag_protocol = b53_get_tag_protocol,
.setup = b53_setup, .setup = b53_setup,
...@@ -1495,6 +1614,8 @@ static const struct dsa_switch_ops b53_switch_ops = { ...@@ -1495,6 +1614,8 @@ static const struct dsa_switch_ops b53_switch_ops = {
.adjust_link = b53_adjust_link, .adjust_link = b53_adjust_link,
.port_enable = b53_enable_port, .port_enable = b53_enable_port,
.port_disable = b53_disable_port, .port_disable = b53_disable_port,
.get_mac_eee = b53_get_mac_eee,
.set_mac_eee = b53_set_mac_eee,
.port_bridge_join = b53_br_join, .port_bridge_join = b53_br_join,
.port_bridge_leave = b53_br_leave, .port_bridge_leave = b53_br_leave,
.port_stp_state_set = b53_br_set_stp_state, .port_stp_state_set = b53_br_set_stp_state,
......
...@@ -70,6 +70,7 @@ enum { ...@@ -70,6 +70,7 @@ enum {
struct b53_port { struct b53_port {
u16 vlan_ctl_mask; u16 vlan_ctl_mask;
struct ethtool_eee eee;
}; };
struct b53_vlan { struct b53_vlan {
...@@ -186,11 +187,6 @@ static inline int is58xx(struct b53_device *dev) ...@@ -186,11 +187,6 @@ static inline int is58xx(struct b53_device *dev)
#define B53_CPU_PORT_25 5 #define B53_CPU_PORT_25 5
#define B53_CPU_PORT 8 #define B53_CPU_PORT 8
static inline int is_cpu_port(struct b53_device *dev, int port)
{
return dev->cpu_port;
}
struct b53_device *b53_switch_alloc(struct device *base, struct b53_device *b53_switch_alloc(struct device *base,
const struct b53_io_ops *ops, const struct b53_io_ops *ops,
void *priv); void *priv);
...@@ -204,119 +200,30 @@ static inline void b53_switch_remove(struct b53_device *dev) ...@@ -204,119 +200,30 @@ static inline void b53_switch_remove(struct b53_device *dev)
dsa_unregister_switch(dev->ds); dsa_unregister_switch(dev->ds);
} }
static inline int b53_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) #define b53_build_op(type_op_size, val_type) \
{ static inline int b53_##type_op_size(struct b53_device *dev, u8 page, \
int ret; u8 reg, val_type val) \
{ \
mutex_lock(&dev->reg_mutex); int ret; \
ret = dev->ops->read8(dev, page, reg, val); \
mutex_unlock(&dev->reg_mutex); mutex_lock(&dev->reg_mutex); \
ret = dev->ops->type_op_size(dev, page, reg, val); \
return ret; mutex_unlock(&dev->reg_mutex); \
\
return ret; \
} }
static inline int b53_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) b53_build_op(read8, u8 *);
{ b53_build_op(read16, u16 *);
int ret; b53_build_op(read32, u32 *);
b53_build_op(read48, u64 *);
mutex_lock(&dev->reg_mutex); b53_build_op(read64, u64 *);
ret = dev->ops->read16(dev, page, reg, val);
mutex_unlock(&dev->reg_mutex);
return ret;
}
static inline int b53_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val)
{
int ret;
mutex_lock(&dev->reg_mutex);
ret = dev->ops->read32(dev, page, reg, val);
mutex_unlock(&dev->reg_mutex);
return ret;
}
static inline int b53_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val)
{
int ret;
mutex_lock(&dev->reg_mutex);
ret = dev->ops->read48(dev, page, reg, val);
mutex_unlock(&dev->reg_mutex);
return ret;
}
static inline int b53_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val)
{
int ret;
mutex_lock(&dev->reg_mutex);
ret = dev->ops->read64(dev, page, reg, val);
mutex_unlock(&dev->reg_mutex);
return ret;
}
static inline int b53_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) b53_build_op(write8, u8);
{ b53_build_op(write16, u16);
int ret; b53_build_op(write32, u32);
b53_build_op(write48, u64);
mutex_lock(&dev->reg_mutex); b53_build_op(write64, u64);
ret = dev->ops->write8(dev, page, reg, value);
mutex_unlock(&dev->reg_mutex);
return ret;
}
static inline int b53_write16(struct b53_device *dev, u8 page, u8 reg,
u16 value)
{
int ret;
mutex_lock(&dev->reg_mutex);
ret = dev->ops->write16(dev, page, reg, value);
mutex_unlock(&dev->reg_mutex);
return ret;
}
static inline int b53_write32(struct b53_device *dev, u8 page, u8 reg,
u32 value)
{
int ret;
mutex_lock(&dev->reg_mutex);
ret = dev->ops->write32(dev, page, reg, value);
mutex_unlock(&dev->reg_mutex);
return ret;
}
static inline int b53_write48(struct b53_device *dev, u8 page, u8 reg,
u64 value)
{
int ret;
mutex_lock(&dev->reg_mutex);
ret = dev->ops->write48(dev, page, reg, value);
mutex_unlock(&dev->reg_mutex);
return ret;
}
static inline int b53_write64(struct b53_device *dev, u8 page, u8 reg,
u64 value)
{
int ret;
mutex_lock(&dev->reg_mutex);
ret = dev->ops->write64(dev, page, reg, value);
mutex_unlock(&dev->reg_mutex);
return ret;
}
struct b53_arl_entry { struct b53_arl_entry {
u8 port; u8 port;
...@@ -377,6 +284,7 @@ static inline int b53_switch_get_reset_gpio(struct b53_device *dev) ...@@ -377,6 +284,7 @@ static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
#endif #endif
/* Exported functions towards other drivers */ /* Exported functions towards other drivers */
void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port);
void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data); void b53_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data); void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
int b53_get_sset_count(struct dsa_switch *ds); int b53_get_sset_count(struct dsa_switch *ds);
...@@ -403,5 +311,12 @@ int b53_mirror_add(struct dsa_switch *ds, int port, ...@@ -403,5 +311,12 @@ int b53_mirror_add(struct dsa_switch *ds, int port,
struct dsa_mall_mirror_tc_entry *mirror, bool ingress); struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
void b53_mirror_del(struct dsa_switch *ds, int port, void b53_mirror_del(struct dsa_switch *ds, int port,
struct dsa_mall_mirror_tc_entry *mirror); struct dsa_mall_mirror_tc_entry *mirror);
int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
void b53_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
void b53_brcm_hdr_setup(struct dsa_switch *ds, int port);
void b53_eee_enable_set(struct dsa_switch *ds, int port, bool enable);
int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy);
int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
#endif #endif
...@@ -50,6 +50,9 @@ ...@@ -50,6 +50,9 @@
/* Jumbo Frame Registers */ /* Jumbo Frame Registers */
#define B53_JUMBO_PAGE 0x40 #define B53_JUMBO_PAGE 0x40
/* EEE Control Registers Page */
#define B53_EEE_PAGE 0x92
/* CFP Configuration Registers Page */ /* CFP Configuration Registers Page */
#define B53_CFP_PAGE 0xa1 #define B53_CFP_PAGE 0xa1
...@@ -210,6 +213,7 @@ ...@@ -210,6 +213,7 @@
#define B53_BRCM_HDR 0x03 #define B53_BRCM_HDR 0x03
#define BRCM_HDR_P8_EN BIT(0) /* Enable tagging on port 8 */ #define BRCM_HDR_P8_EN BIT(0) /* Enable tagging on port 8 */
#define BRCM_HDR_P5_EN BIT(1) /* Enable tagging on port 5 */ #define BRCM_HDR_P5_EN BIT(1) /* Enable tagging on port 5 */
#define BRCM_HDR_P7_EN BIT(2) /* Enable tagging on port 7 */
/* Mirror capture control register (16 bit) */ /* Mirror capture control register (16 bit) */
#define B53_MIR_CAP_CTL 0x10 #define B53_MIR_CAP_CTL 0x10
...@@ -249,6 +253,12 @@ ...@@ -249,6 +253,12 @@
/* Revision ID register (8 bit) */ /* Revision ID register (8 bit) */
#define B53_REV_ID 0x40 #define B53_REV_ID 0x40
/* Broadcom header RX control (16 bit) */
#define B53_BRCM_HDR_RX_DIS 0x60
/* Broadcom header TX control (16 bit) */
#define B53_BRCM_HDR_TX_DIS 0x62
/************************************************************************* /*************************************************************************
* ARL Access Page Registers * ARL Access Page Registers
*************************************************************************/ *************************************************************************/
...@@ -464,6 +474,44 @@ ...@@ -464,6 +474,44 @@
#define JMS_MIN_SIZE 1518 #define JMS_MIN_SIZE 1518
#define JMS_MAX_SIZE 9724 #define JMS_MAX_SIZE 9724
/*************************************************************************
* EEE Configuration Page Registers
*************************************************************************/
/* EEE Enable control register (16 bit) */
#define B53_EEE_EN_CTRL 0x00
/* EEE LPI assert status register (16 bit) */
#define B53_EEE_LPI_ASSERT_STS 0x02
/* EEE LPI indicate status register (16 bit) */
#define B53_EEE_LPI_INDICATE 0x4
/* EEE Receiving idle symbols status register (16 bit) */
#define B53_EEE_RX_IDLE_SYM_STS 0x6
/* EEE Pipeline timer register (32 bit) */
#define B53_EEE_PIP_TIMER 0xC
/* EEE Sleep timer Gig register (32 bit) */
#define B53_EEE_SLEEP_TIMER_GIG(i) (0x10 + 4 * (i))
/* EEE Sleep timer FE register (32 bit) */
#define B53_EEE_SLEEP_TIMER_FE(i) (0x34 + 4 * (i))
/* EEE Minimum LP timer Gig register (32 bit) */
#define B53_EEE_MIN_LP_TIMER_GIG(i) (0x58 + 4 * (i))
/* EEE Minimum LP timer FE register (32 bit) */
#define B53_EEE_MIN_LP_TIMER_FE(i) (0x7c + 4 * (i))
/* EEE Wake timer Gig register (16 bit) */
#define B53_EEE_WAKE_TIMER_GIG(i) (0xa0 + 2 * (i))
/* EEE Wake timer FE register (16 bit) */
#define B53_EEE_WAKE_TIMER_FE(i) (0xb2 + 2 * (i))
/************************************************************************* /*************************************************************************
* CFP Configuration Page Registers * CFP Configuration Page Registers
*************************************************************************/ *************************************************************************/
......
...@@ -40,66 +40,6 @@ static enum dsa_tag_protocol bcm_sf2_sw_get_tag_protocol(struct dsa_switch *ds) ...@@ -40,66 +40,6 @@ static enum dsa_tag_protocol bcm_sf2_sw_get_tag_protocol(struct dsa_switch *ds)
return DSA_TAG_PROTO_BRCM; return DSA_TAG_PROTO_BRCM;
} }
static void bcm_sf2_imp_vlan_setup(struct dsa_switch *ds, int cpu_port)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
unsigned int i;
u32 reg;
/* Enable the IMP Port to be in the same VLAN as the other ports
* on a per-port basis such that we only have Port i and IMP in
* the same VLAN.
*/
for (i = 0; i < priv->hw_params.num_ports; i++) {
if (!((1 << i) & ds->enabled_port_mask))
continue;
reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(i));
reg |= (1 << cpu_port);
core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(i));
}
}
static void bcm_sf2_brcm_hdr_setup(struct bcm_sf2_priv *priv, int port)
{
u32 reg, val;
/* Resolve which bit controls the Broadcom tag */
switch (port) {
case 8:
val = BRCM_HDR_EN_P8;
break;
case 7:
val = BRCM_HDR_EN_P7;
break;
case 5:
val = BRCM_HDR_EN_P5;
break;
default:
val = 0;
break;
}
/* Enable Broadcom tags for IMP port */
reg = core_readl(priv, CORE_BRCM_HDR_CTRL);
reg |= val;
core_writel(priv, reg, CORE_BRCM_HDR_CTRL);
/* Enable reception Broadcom tag for CPU TX (switch RX) to
* allow us to tag outgoing frames
*/
reg = core_readl(priv, CORE_BRCM_HDR_RX_DIS);
reg &= ~(1 << port);
core_writel(priv, reg, CORE_BRCM_HDR_RX_DIS);
/* Enable transmission of Broadcom tags from the switch (CPU RX) to
* allow delivering frames to the per-port net_devices
*/
reg = core_readl(priv, CORE_BRCM_HDR_TX_DIS);
reg &= ~(1 << port);
core_writel(priv, reg, CORE_BRCM_HDR_TX_DIS);
}
static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
{ {
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
...@@ -138,7 +78,7 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) ...@@ -138,7 +78,7 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
reg |= i << (PRT_TO_QID_SHIFT * i); reg |= i << (PRT_TO_QID_SHIFT * i);
core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port)); core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port));
bcm_sf2_brcm_hdr_setup(priv, port); b53_brcm_hdr_setup(ds, port);
/* Force link status for IMP port */ /* Force link status for IMP port */
reg = core_readl(priv, offset); reg = core_readl(priv, offset);
...@@ -146,19 +86,6 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) ...@@ -146,19 +86,6 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
core_writel(priv, reg, offset); core_writel(priv, reg, offset);
} }
static void bcm_sf2_eee_enable_set(struct dsa_switch *ds, int port, bool enable)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
u32 reg;
reg = core_readl(priv, CORE_EEE_EN_CTRL);
if (enable)
reg |= 1 << port;
else
reg &= ~(1 << port);
core_writel(priv, reg, CORE_EEE_EN_CTRL);
}
static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable) static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable)
{ {
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
...@@ -236,7 +163,6 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, ...@@ -236,7 +163,6 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
struct phy_device *phy) struct phy_device *phy)
{ {
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
s8 cpu_port = ds->dst->cpu_dp->index;
unsigned int i; unsigned int i;
u32 reg; u32 reg;
...@@ -247,7 +173,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, ...@@ -247,7 +173,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
/* Enable Broadcom tags for that port if requested */ /* Enable Broadcom tags for that port if requested */
if (priv->brcm_tag_mask & BIT(port)) if (priv->brcm_tag_mask & BIT(port))
bcm_sf2_brcm_hdr_setup(priv, port); b53_brcm_hdr_setup(ds, port);
/* Configure Traffic Class to QoS mapping, allow each priority to map /* Configure Traffic Class to QoS mapping, allow each priority to map
* to a different queue number * to a different queue number
...@@ -257,9 +183,6 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, ...@@ -257,9 +183,6 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
reg |= i << (PRT_TO_QID_SHIFT * i); reg |= i << (PRT_TO_QID_SHIFT * i);
core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port)); core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port));
/* Clear the Rx and Tx disable bits and set to no spanning tree */
core_writel(priv, 0, CORE_G_PCTL_PORT(port));
/* Re-enable the GPHY and re-apply workarounds */ /* Re-enable the GPHY and re-apply workarounds */
if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1) { if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1) {
bcm_sf2_gphy_enable_set(ds, true); bcm_sf2_gphy_enable_set(ds, true);
...@@ -282,23 +205,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, ...@@ -282,23 +205,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
if (port == priv->moca_port) if (port == priv->moca_port)
bcm_sf2_port_intr_enable(priv, port); bcm_sf2_port_intr_enable(priv, port);
/* Set this port, and only this one to be in the default VLAN, return b53_enable_port(ds, port, phy);
* if member of a bridge, restore its membership prior to
* bringing down this port.
*/
reg = core_readl(priv, CORE_PORT_VLAN_CTL_PORT(port));
reg &= ~PORT_VLAN_CTRL_MASK;
reg |= (1 << port);
reg |= priv->dev->ports[port].vlan_ctl_mask;
core_writel(priv, reg, CORE_PORT_VLAN_CTL_PORT(port));
bcm_sf2_imp_vlan_setup(ds, cpu_port);
/* If EEE was enabled, restore it */
if (priv->port_sts[port].eee.eee_enabled)
bcm_sf2_eee_enable_set(ds, port, true);
return 0;
} }
static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, static void bcm_sf2_port_disable(struct dsa_switch *ds, int port,
...@@ -321,9 +228,7 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, ...@@ -321,9 +228,7 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port,
else else
off = CORE_G_PCTL_PORT(port); off = CORE_G_PCTL_PORT(port);
reg = core_readl(priv, off); b53_disable_port(ds, port, phy);
reg |= RX_DIS | TX_DIS;
core_writel(priv, reg, off);
/* Power down the port memory */ /* Power down the port memory */
reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL);
...@@ -331,47 +236,6 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port, ...@@ -331,47 +236,6 @@ static void bcm_sf2_port_disable(struct dsa_switch *ds, int port,
core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
} }
/* Returns 0 if EEE was not enabled, or 1 otherwise
*/
static int bcm_sf2_eee_init(struct dsa_switch *ds, int port,
struct phy_device *phy)
{
int ret;
ret = phy_init_eee(phy, 0);
if (ret)
return 0;
bcm_sf2_eee_enable_set(ds, port, true);
return 1;
}
static int bcm_sf2_sw_get_mac_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct ethtool_eee *p = &priv->port_sts[port].eee;
u32 reg;
reg = core_readl(priv, CORE_EEE_LPI_INDICATE);
e->eee_enabled = p->eee_enabled;
e->eee_active = !!(reg & (1 << port));
return 0;
}
static int bcm_sf2_sw_set_mac_eee(struct dsa_switch *ds, int port,
struct ethtool_eee *e)
{
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct ethtool_eee *p = &priv->port_sts[port].eee;
p->eee_enabled = e->eee_enabled;
bcm_sf2_eee_enable_set(ds, port, e->eee_enabled);
return 0;
}
static int bcm_sf2_sw_indir_rw(struct bcm_sf2_priv *priv, int op, int addr, static int bcm_sf2_sw_indir_rw(struct bcm_sf2_priv *priv, int op, int addr,
int regnum, u16 val) int regnum, u16 val)
...@@ -606,7 +470,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, ...@@ -606,7 +470,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port,
struct phy_device *phydev) struct phy_device *phydev)
{ {
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
struct ethtool_eee *p = &priv->port_sts[port].eee; struct ethtool_eee *p = &priv->dev->ports[port].eee;
u32 id_mode_dis = 0, port_mode; u32 id_mode_dis = 0, port_mode;
const char *str = NULL; const char *str = NULL;
u32 reg, offset; u32 reg, offset;
...@@ -688,7 +552,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, ...@@ -688,7 +552,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port,
core_writel(priv, reg, offset); core_writel(priv, reg, offset);
if (!phydev->is_pseudo_fixed_link) if (!phydev->is_pseudo_fixed_link)
p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev); p->eee_enabled = b53_eee_init(ds, port, phydev);
} }
static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port,
...@@ -890,14 +754,11 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) ...@@ -890,14 +754,11 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
unsigned int port; unsigned int port;
/* Enable all valid ports and disable those unused */ /* Disable unused ports and configure IMP port */
for (port = 0; port < priv->hw_params.num_ports; port++) { for (port = 0; port < priv->hw_params.num_ports; port++) {
/* IMP port receives special treatment */ if (dsa_is_cpu_port(ds, port))
if ((1 << port) & ds->enabled_port_mask)
bcm_sf2_port_setup(ds, port, NULL);
else if (dsa_is_cpu_port(ds, port))
bcm_sf2_imp_setup(ds, port); bcm_sf2_imp_setup(ds, port);
else else if (!((1 << port) & ds->enabled_port_mask))
bcm_sf2_port_disable(ds, port, NULL); bcm_sf2_port_disable(ds, port, NULL);
} }
...@@ -1020,8 +881,8 @@ static const struct dsa_switch_ops bcm_sf2_ops = { ...@@ -1020,8 +881,8 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
.set_wol = bcm_sf2_sw_set_wol, .set_wol = bcm_sf2_sw_set_wol,
.port_enable = bcm_sf2_port_setup, .port_enable = bcm_sf2_port_setup,
.port_disable = bcm_sf2_port_disable, .port_disable = bcm_sf2_port_disable,
.get_mac_eee = bcm_sf2_sw_get_mac_eee, .get_mac_eee = b53_get_mac_eee,
.set_mac_eee = bcm_sf2_sw_set_mac_eee, .set_mac_eee = b53_set_mac_eee,
.port_bridge_join = b53_br_join, .port_bridge_join = b53_br_join,
.port_bridge_leave = b53_br_leave, .port_bridge_leave = b53_br_leave,
.port_stp_state_set = b53_br_set_stp_state, .port_stp_state_set = b53_br_set_stp_state,
......
...@@ -48,8 +48,6 @@ struct bcm_sf2_hw_params { ...@@ -48,8 +48,6 @@ struct bcm_sf2_hw_params {
struct bcm_sf2_port_status { struct bcm_sf2_port_status {
unsigned int link; unsigned int link;
struct ethtool_eee eee;
}; };
struct bcm_sf2_cfp_priv { struct bcm_sf2_cfp_priv {
......
...@@ -144,7 +144,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, ...@@ -144,7 +144,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
* destination port is enabled and that we are within the * destination port is enabled and that we are within the
* number of ports supported by the switch * number of ports supported by the switch
*/ */
port_num = fs->ring_cookie / 8; port_num = fs->ring_cookie / SF2_NUM_EGRESS_QUEUES;
if (fs->ring_cookie == RX_CLS_FLOW_DISC || if (fs->ring_cookie == RX_CLS_FLOW_DISC ||
!(BIT(port_num) & ds->enabled_port_mask) || !(BIT(port_num) & ds->enabled_port_mask) ||
...@@ -280,7 +280,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, ...@@ -280,7 +280,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
* We have a small oddity where Port 6 just does not have a * We have a small oddity where Port 6 just does not have a
* valid bit here (so we subtract by one). * valid bit here (so we subtract by one).
*/ */
queue_num = fs->ring_cookie % 8; queue_num = fs->ring_cookie % SF2_NUM_EGRESS_QUEUES;
if (port_num >= 7) if (port_num >= 7)
port_num -= 1; port_num -= 1;
...@@ -401,7 +401,7 @@ static int bcm_sf2_cfp_rule_get(struct bcm_sf2_priv *priv, int port, ...@@ -401,7 +401,7 @@ static int bcm_sf2_cfp_rule_get(struct bcm_sf2_priv *priv, int port,
/* There is no Port 6, so we compensate for that here */ /* There is no Port 6, so we compensate for that here */
if (nfc->fs.ring_cookie >= 6) if (nfc->fs.ring_cookie >= 6)
nfc->fs.ring_cookie++; nfc->fs.ring_cookie++;
nfc->fs.ring_cookie *= 8; nfc->fs.ring_cookie *= SF2_NUM_EGRESS_QUEUES;
/* Extract the destination queue */ /* Extract the destination queue */
queue_num = (reg >> NEW_TC_SHIFT) & NEW_TC_MASK; queue_num = (reg >> NEW_TC_SHIFT) & NEW_TC_MASK;
......
...@@ -205,16 +205,8 @@ enum bcm_sf2_reg_offs { ...@@ -205,16 +205,8 @@ enum bcm_sf2_reg_offs {
#define CORE_IMP0_PRT_ID 0x0804 #define CORE_IMP0_PRT_ID 0x0804
#define CORE_BRCM_HDR_CTRL 0x0080c
#define BRCM_HDR_EN_P8 (1 << 0)
#define BRCM_HDR_EN_P5 (1 << 1)
#define BRCM_HDR_EN_P7 (1 << 2)
#define CORE_RST_MIB_CNT_EN 0x0950 #define CORE_RST_MIB_CNT_EN 0x0950
#define CORE_BRCM_HDR_RX_DIS 0x0980
#define CORE_BRCM_HDR_TX_DIS 0x0988
#define CORE_ARLA_VTBL_RWCTRL 0x1600 #define CORE_ARLA_VTBL_RWCTRL 0x1600
#define ARLA_VTBL_CMD_WRITE 0 #define ARLA_VTBL_CMD_WRITE 0
#define ARLA_VTBL_CMD_READ 1 #define ARLA_VTBL_CMD_READ 1
...@@ -252,9 +244,6 @@ enum bcm_sf2_reg_offs { ...@@ -252,9 +244,6 @@ enum bcm_sf2_reg_offs {
#define CORE_JOIN_ALL_VLAN_EN 0xd140 #define CORE_JOIN_ALL_VLAN_EN 0xd140
#define CORE_EEE_EN_CTRL 0x24800
#define CORE_EEE_LPI_INDICATE 0x24810
#define CORE_CFP_ACC 0x28000 #define CORE_CFP_ACC 0x28000
#define OP_STR_DONE (1 << 0) #define OP_STR_DONE (1 << 0)
#define OP_SEL_SHIFT 1 #define OP_SEL_SHIFT 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment