mirror of
https://github.com/torvalds/linux.git
synced 2024-12-13 06:32:50 +00:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
3d5cc728c4
@ -484,7 +484,7 @@ static int b53_fast_age_vlan(struct b53_device *dev, u16 vid)
|
||||
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;
|
||||
unsigned int i;
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(b53_imp_vlan_setup);
|
||||
|
||||
static int b53_enable_port(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phy)
|
||||
int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
|
||||
{
|
||||
struct b53_device *dev = ds->priv;
|
||||
unsigned int cpu_port = dev->cpu_port;
|
||||
@ -523,11 +523,15 @@ static int b53_enable_port(struct dsa_switch *ds, int 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;
|
||||
}
|
||||
EXPORT_SYMBOL(b53_enable_port);
|
||||
|
||||
static void b53_disable_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)
|
||||
{
|
||||
struct b53_device *dev = ds->priv;
|
||||
u8 reg;
|
||||
@ -537,20 +541,67 @@ static void b53_disable_port(struct dsa_switch *ds, int port,
|
||||
reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE;
|
||||
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 &= ~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 &= ~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;
|
||||
|
||||
/* BCM5325 CPU port is at 8 */
|
||||
if ((is5325(dev) || is5365(dev)) && cpu_port == B53_CPU_PORT_25)
|
||||
cpu_port = B53_CPU_PORT;
|
||||
if ((is5325(dev) || is5365(dev)) && port == B53_CPU_PORT_25)
|
||||
port = B53_CPU_PORT;
|
||||
|
||||
port_ctrl = PORT_CTRL_RX_BCST_EN |
|
||||
PORT_CTRL_RX_MCST_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)
|
||||
@ -816,12 +867,13 @@ static int b53_setup(struct dsa_switch *ds)
|
||||
if (ret)
|
||||
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++) {
|
||||
if (BIT(port) & ds->enabled_port_mask)
|
||||
b53_enable_port(ds, port, NULL);
|
||||
else if (dsa_is_cpu_port(ds, port))
|
||||
b53_enable_cpu_port(dev);
|
||||
else
|
||||
if (dsa_is_cpu_port(ds, port))
|
||||
b53_enable_cpu_port(dev, port);
|
||||
else if (!(BIT(port) & ds->enabled_port_mask))
|
||||
b53_disable_port(ds, port, NULL);
|
||||
}
|
||||
|
||||
@ -832,6 +884,7 @@ static void b53_adjust_link(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phydev)
|
||||
{
|
||||
struct b53_device *dev = ds->priv;
|
||||
struct ethtool_eee *p = &dev->ports[port].eee;
|
||||
u8 rgmii_ctrl = 0, reg = 0, off;
|
||||
|
||||
if (!phy_is_pseudo_fixed_link(phydev))
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
@ -1484,6 +1540,69 @@ void b53_mirror_del(struct dsa_switch *ds, int port,
|
||||
}
|
||||
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, ®);
|
||||
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, ®);
|
||||
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 = {
|
||||
.get_tag_protocol = b53_get_tag_protocol,
|
||||
.setup = b53_setup,
|
||||
@ -1495,6 +1614,8 @@ static const struct dsa_switch_ops b53_switch_ops = {
|
||||
.adjust_link = b53_adjust_link,
|
||||
.port_enable = b53_enable_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_leave = b53_br_leave,
|
||||
.port_stp_state_set = b53_br_set_stp_state,
|
||||
|
@ -70,6 +70,7 @@ enum {
|
||||
|
||||
struct b53_port {
|
||||
u16 vlan_ctl_mask;
|
||||
struct ethtool_eee eee;
|
||||
};
|
||||
|
||||
struct b53_vlan {
|
||||
@ -186,11 +187,6 @@ static inline int is58xx(struct b53_device *dev)
|
||||
#define B53_CPU_PORT_25 5
|
||||
#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,
|
||||
const struct b53_io_ops *ops,
|
||||
void *priv);
|
||||
@ -204,119 +200,30 @@ static inline void b53_switch_remove(struct b53_device *dev)
|
||||
dsa_unregister_switch(dev->ds);
|
||||
}
|
||||
|
||||
static inline int b53_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->reg_mutex);
|
||||
ret = dev->ops->read8(dev, page, reg, val);
|
||||
mutex_unlock(&dev->reg_mutex);
|
||||
|
||||
return ret;
|
||||
#define b53_build_op(type_op_size, val_type) \
|
||||
static inline int b53_##type_op_size(struct b53_device *dev, u8 page, \
|
||||
u8 reg, val_type val) \
|
||||
{ \
|
||||
int ret; \
|
||||
\
|
||||
mutex_lock(&dev->reg_mutex); \
|
||||
ret = dev->ops->type_op_size(dev, page, reg, val); \
|
||||
mutex_unlock(&dev->reg_mutex); \
|
||||
\
|
||||
return ret; \
|
||||
}
|
||||
|
||||
static inline int b53_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val)
|
||||
{
|
||||
int ret;
|
||||
b53_build_op(read8, u8 *);
|
||||
b53_build_op(read16, u16 *);
|
||||
b53_build_op(read32, u32 *);
|
||||
b53_build_op(read48, u64 *);
|
||||
b53_build_op(read64, u64 *);
|
||||
|
||||
mutex_lock(&dev->reg_mutex);
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->reg_mutex);
|
||||
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;
|
||||
}
|
||||
b53_build_op(write8, u8);
|
||||
b53_build_op(write16, u16);
|
||||
b53_build_op(write32, u32);
|
||||
b53_build_op(write48, u64);
|
||||
b53_build_op(write64, u64);
|
||||
|
||||
struct b53_arl_entry {
|
||||
u8 port;
|
||||
@ -377,6 +284,7 @@ static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
|
||||
#endif
|
||||
|
||||
/* 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_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
|
||||
int b53_get_sset_count(struct dsa_switch *ds);
|
||||
@ -403,5 +311,12 @@ int b53_mirror_add(struct dsa_switch *ds, int port,
|
||||
struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
|
||||
void b53_mirror_del(struct dsa_switch *ds, int port,
|
||||
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
|
||||
|
@ -50,6 +50,9 @@
|
||||
/* Jumbo Frame Registers */
|
||||
#define B53_JUMBO_PAGE 0x40
|
||||
|
||||
/* EEE Control Registers Page */
|
||||
#define B53_EEE_PAGE 0x92
|
||||
|
||||
/* CFP Configuration Registers Page */
|
||||
#define B53_CFP_PAGE 0xa1
|
||||
|
||||
@ -210,6 +213,7 @@
|
||||
#define B53_BRCM_HDR 0x03
|
||||
#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_P7_EN BIT(2) /* Enable tagging on port 7 */
|
||||
|
||||
/* Mirror capture control register (16 bit) */
|
||||
#define B53_MIR_CAP_CTL 0x10
|
||||
@ -249,6 +253,12 @@
|
||||
/* Revision ID register (8 bit) */
|
||||
#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
|
||||
*************************************************************************/
|
||||
@ -464,6 +474,44 @@
|
||||
#define JMS_MIN_SIZE 1518
|
||||
#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
|
||||
*************************************************************************/
|
||||
|
@ -40,66 +40,6 @@ static enum dsa_tag_protocol bcm_sf2_sw_get_tag_protocol(struct dsa_switch *ds)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
reg |= i << (PRT_TO_QID_SHIFT * i);
|
||||
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 */
|
||||
reg = core_readl(priv, offset);
|
||||
@ -146,19 +86,6 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
|
||||
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)
|
||||
{
|
||||
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,
|
||||
struct phy_device *phy)
|
||||
{
|
||||
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
|
||||
s8 cpu_port = ds->dst->cpu_dp->index;
|
||||
unsigned int i;
|
||||
u32 reg;
|
||||
|
||||
@ -247,7 +173,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
|
||||
|
||||
/* Enable Broadcom tags for that port if requested */
|
||||
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
|
||||
* to a different queue number
|
||||
@ -257,9 +183,6 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
|
||||
reg |= i << (PRT_TO_QID_SHIFT * i);
|
||||
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 */
|
||||
if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1) {
|
||||
bcm_sf2_gphy_enable_set(ds, true);
|
||||
@ -282,23 +205,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
|
||||
if (port == priv->moca_port)
|
||||
bcm_sf2_port_intr_enable(priv, port);
|
||||
|
||||
/* Set this port, and only this one to be in the default VLAN,
|
||||
* 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;
|
||||
return b53_enable_port(ds, port, phy);
|
||||
}
|
||||
|
||||
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
|
||||
off = CORE_G_PCTL_PORT(port);
|
||||
|
||||
reg = core_readl(priv, off);
|
||||
reg |= RX_DIS | TX_DIS;
|
||||
core_writel(priv, reg, off);
|
||||
b53_disable_port(ds, port, phy);
|
||||
|
||||
/* Power down the port memory */
|
||||
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,
|
||||
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,
|
||||
int regnum, u16 val)
|
||||
@ -606,7 +470,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phydev)
|
||||
{
|
||||
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;
|
||||
const char *str = NULL;
|
||||
u32 reg, offset;
|
||||
@ -688,7 +552,7 @@ force_link:
|
||||
core_writel(priv, reg, offset);
|
||||
|
||||
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,
|
||||
@ -890,14 +754,11 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
|
||||
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
|
||||
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++) {
|
||||
/* IMP port receives special treatment */
|
||||
if ((1 << port) & ds->enabled_port_mask)
|
||||
bcm_sf2_port_setup(ds, port, NULL);
|
||||
else if (dsa_is_cpu_port(ds, port))
|
||||
if (dsa_is_cpu_port(ds, port))
|
||||
bcm_sf2_imp_setup(ds, port);
|
||||
else
|
||||
else if (!((1 << port) & ds->enabled_port_mask))
|
||||
bcm_sf2_port_disable(ds, port, NULL);
|
||||
}
|
||||
|
||||
@ -1020,8 +881,8 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
|
||||
.set_wol = bcm_sf2_sw_set_wol,
|
||||
.port_enable = bcm_sf2_port_setup,
|
||||
.port_disable = bcm_sf2_port_disable,
|
||||
.get_mac_eee = bcm_sf2_sw_get_mac_eee,
|
||||
.set_mac_eee = bcm_sf2_sw_set_mac_eee,
|
||||
.get_mac_eee = b53_get_mac_eee,
|
||||
.set_mac_eee = b53_set_mac_eee,
|
||||
.port_bridge_join = b53_br_join,
|
||||
.port_bridge_leave = b53_br_leave,
|
||||
.port_stp_state_set = b53_br_set_stp_state,
|
||||
|
@ -48,8 +48,6 @@ struct bcm_sf2_hw_params {
|
||||
|
||||
struct bcm_sf2_port_status {
|
||||
unsigned int link;
|
||||
|
||||
struct ethtool_eee eee;
|
||||
};
|
||||
|
||||
struct bcm_sf2_cfp_priv {
|
||||
|
@ -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
|
||||
* 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 ||
|
||||
!(BIT(port_num) & ds->enabled_port_mask) ||
|
||||
@ -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
|
||||
* 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)
|
||||
port_num -= 1;
|
||||
|
||||
@ -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 */
|
||||
if (nfc->fs.ring_cookie >= 6)
|
||||
nfc->fs.ring_cookie++;
|
||||
nfc->fs.ring_cookie *= 8;
|
||||
nfc->fs.ring_cookie *= SF2_NUM_EGRESS_QUEUES;
|
||||
|
||||
/* Extract the destination queue */
|
||||
queue_num = (reg >> NEW_TC_SHIFT) & NEW_TC_MASK;
|
||||
|
@ -205,16 +205,8 @@ enum bcm_sf2_reg_offs {
|
||||
|
||||
#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_BRCM_HDR_RX_DIS 0x0980
|
||||
#define CORE_BRCM_HDR_TX_DIS 0x0988
|
||||
|
||||
#define CORE_ARLA_VTBL_RWCTRL 0x1600
|
||||
#define ARLA_VTBL_CMD_WRITE 0
|
||||
#define ARLA_VTBL_CMD_READ 1
|
||||
@ -252,9 +244,6 @@ enum bcm_sf2_reg_offs {
|
||||
|
||||
#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 OP_STR_DONE (1 << 0)
|
||||
#define OP_SEL_SHIFT 1
|
||||
|
Loading…
Reference in New Issue
Block a user