cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bcm_sf2.c (41817B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Broadcom Starfighter 2 DSA switch driver
      4 *
      5 * Copyright (C) 2014, Broadcom Corporation
      6 */
      7
      8#include <linux/list.h>
      9#include <linux/module.h>
     10#include <linux/netdevice.h>
     11#include <linux/interrupt.h>
     12#include <linux/platform_device.h>
     13#include <linux/phy.h>
     14#include <linux/phy_fixed.h>
     15#include <linux/phylink.h>
     16#include <linux/mii.h>
     17#include <linux/clk.h>
     18#include <linux/of.h>
     19#include <linux/of_irq.h>
     20#include <linux/of_address.h>
     21#include <linux/of_net.h>
     22#include <linux/of_mdio.h>
     23#include <net/dsa.h>
     24#include <linux/ethtool.h>
     25#include <linux/if_bridge.h>
     26#include <linux/brcmphy.h>
     27#include <linux/etherdevice.h>
     28#include <linux/platform_data/b53.h>
     29
     30#include "bcm_sf2.h"
     31#include "bcm_sf2_regs.h"
     32#include "b53/b53_priv.h"
     33#include "b53/b53_regs.h"
     34
     35static u16 bcm_sf2_reg_rgmii_cntrl(struct bcm_sf2_priv *priv, int port)
     36{
     37	switch (priv->type) {
     38	case BCM4908_DEVICE_ID:
     39		switch (port) {
     40		case 7:
     41			return REG_RGMII_11_CNTRL;
     42		default:
     43			break;
     44		}
     45		break;
     46	default:
     47		switch (port) {
     48		case 0:
     49			return REG_RGMII_0_CNTRL;
     50		case 1:
     51			return REG_RGMII_1_CNTRL;
     52		case 2:
     53			return REG_RGMII_2_CNTRL;
     54		default:
     55			break;
     56		}
     57	}
     58
     59	WARN_ONCE(1, "Unsupported port %d\n", port);
     60
     61	/* RO fallback reg */
     62	return REG_SWITCH_STATUS;
     63}
     64
     65static u16 bcm_sf2_reg_led_base(struct bcm_sf2_priv *priv, int port)
     66{
     67	switch (port) {
     68	case 0:
     69		return REG_LED_0_CNTRL;
     70	case 1:
     71		return REG_LED_1_CNTRL;
     72	case 2:
     73		return REG_LED_2_CNTRL;
     74	}
     75
     76	switch (priv->type) {
     77	case BCM4908_DEVICE_ID:
     78		switch (port) {
     79		case 3:
     80			return REG_LED_3_CNTRL;
     81		case 7:
     82			return REG_LED_4_CNTRL;
     83		default:
     84			break;
     85		}
     86		break;
     87	default:
     88		break;
     89	}
     90
     91	WARN_ONCE(1, "Unsupported port %d\n", port);
     92
     93	/* RO fallback reg */
     94	return REG_SWITCH_STATUS;
     95}
     96
     97/* Return the number of active ports, not counting the IMP (CPU) port */
     98static unsigned int bcm_sf2_num_active_ports(struct dsa_switch *ds)
     99{
    100	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    101	unsigned int port, count = 0;
    102
    103	for (port = 0; port < ds->num_ports; port++) {
    104		if (dsa_is_cpu_port(ds, port))
    105			continue;
    106		if (priv->port_sts[port].enabled)
    107			count++;
    108	}
    109
    110	return count;
    111}
    112
    113static void bcm_sf2_recalc_clock(struct dsa_switch *ds)
    114{
    115	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    116	unsigned long new_rate;
    117	unsigned int ports_active;
    118	/* Frequenty in Mhz */
    119	static const unsigned long rate_table[] = {
    120		59220000,
    121		60820000,
    122		62500000,
    123		62500000,
    124	};
    125
    126	ports_active = bcm_sf2_num_active_ports(ds);
    127	if (ports_active == 0 || !priv->clk_mdiv)
    128		return;
    129
    130	/* If we overflow our table, just use the recommended operational
    131	 * frequency
    132	 */
    133	if (ports_active > ARRAY_SIZE(rate_table))
    134		new_rate = 90000000;
    135	else
    136		new_rate = rate_table[ports_active - 1];
    137	clk_set_rate(priv->clk_mdiv, new_rate);
    138}
    139
    140static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
    141{
    142	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    143	unsigned int i;
    144	u32 reg, offset;
    145
    146	/* Enable the port memories */
    147	reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL);
    148	reg &= ~P_TXQ_PSM_VDD(port);
    149	core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
    150
    151	/* Enable forwarding */
    152	core_writel(priv, SW_FWDG_EN, CORE_SWMODE);
    153
    154	/* Enable IMP port in dumb mode */
    155	reg = core_readl(priv, CORE_SWITCH_CTRL);
    156	reg |= MII_DUMB_FWDG_EN;
    157	core_writel(priv, reg, CORE_SWITCH_CTRL);
    158
    159	/* Configure Traffic Class to QoS mapping, allow each priority to map
    160	 * to a different queue number
    161	 */
    162	reg = core_readl(priv, CORE_PORT_TC2_QOS_MAP_PORT(port));
    163	for (i = 0; i < SF2_NUM_EGRESS_QUEUES; i++)
    164		reg |= i << (PRT_TO_QID_SHIFT * i);
    165	core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port));
    166
    167	b53_brcm_hdr_setup(ds, port);
    168
    169	if (port == 8) {
    170		if (priv->type == BCM4908_DEVICE_ID ||
    171		    priv->type == BCM7445_DEVICE_ID)
    172			offset = CORE_STS_OVERRIDE_IMP;
    173		else
    174			offset = CORE_STS_OVERRIDE_IMP2;
    175
    176		/* Force link status for IMP port */
    177		reg = core_readl(priv, offset);
    178		reg |= (MII_SW_OR | LINK_STS);
    179		if (priv->type == BCM4908_DEVICE_ID)
    180			reg |= GMII_SPEED_UP_2G;
    181		else
    182			reg &= ~GMII_SPEED_UP_2G;
    183		core_writel(priv, reg, offset);
    184
    185		/* Enable Broadcast, Multicast, Unicast forwarding to IMP port */
    186		reg = core_readl(priv, CORE_IMP_CTL);
    187		reg |= (RX_BCST_EN | RX_MCST_EN | RX_UCST_EN);
    188		reg &= ~(RX_DIS | TX_DIS);
    189		core_writel(priv, reg, CORE_IMP_CTL);
    190	} else {
    191		reg = core_readl(priv, CORE_G_PCTL_PORT(port));
    192		reg &= ~(RX_DIS | TX_DIS);
    193		core_writel(priv, reg, CORE_G_PCTL_PORT(port));
    194	}
    195
    196	priv->port_sts[port].enabled = true;
    197}
    198
    199static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable)
    200{
    201	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    202	u32 reg;
    203
    204	reg = reg_readl(priv, REG_SPHY_CNTRL);
    205	if (enable) {
    206		reg |= PHY_RESET;
    207		reg &= ~(EXT_PWR_DOWN | IDDQ_BIAS | IDDQ_GLOBAL_PWR | CK25_DIS);
    208		reg_writel(priv, reg, REG_SPHY_CNTRL);
    209		udelay(21);
    210		reg = reg_readl(priv, REG_SPHY_CNTRL);
    211		reg &= ~PHY_RESET;
    212	} else {
    213		reg |= EXT_PWR_DOWN | IDDQ_BIAS | PHY_RESET;
    214		reg_writel(priv, reg, REG_SPHY_CNTRL);
    215		mdelay(1);
    216		reg |= CK25_DIS;
    217	}
    218	reg_writel(priv, reg, REG_SPHY_CNTRL);
    219
    220	/* Use PHY-driven LED signaling */
    221	if (!enable) {
    222		u16 led_ctrl = bcm_sf2_reg_led_base(priv, 0);
    223
    224		if (priv->type == BCM7278_DEVICE_ID ||
    225		    priv->type == BCM7445_DEVICE_ID) {
    226			reg = reg_led_readl(priv, led_ctrl, 0);
    227			reg |= LED_CNTRL_SPDLNK_SRC_SEL;
    228			reg_led_writel(priv, reg, led_ctrl, 0);
    229		}
    230	}
    231}
    232
    233static inline void bcm_sf2_port_intr_enable(struct bcm_sf2_priv *priv,
    234					    int port)
    235{
    236	unsigned int off;
    237
    238	switch (port) {
    239	case 7:
    240		off = P7_IRQ_OFF;
    241		break;
    242	case 0:
    243		/* Port 0 interrupts are located on the first bank */
    244		intrl2_0_mask_clear(priv, P_IRQ_MASK(P0_IRQ_OFF));
    245		return;
    246	default:
    247		off = P_IRQ_OFF(port);
    248		break;
    249	}
    250
    251	intrl2_1_mask_clear(priv, P_IRQ_MASK(off));
    252}
    253
    254static inline void bcm_sf2_port_intr_disable(struct bcm_sf2_priv *priv,
    255					     int port)
    256{
    257	unsigned int off;
    258
    259	switch (port) {
    260	case 7:
    261		off = P7_IRQ_OFF;
    262		break;
    263	case 0:
    264		/* Port 0 interrupts are located on the first bank */
    265		intrl2_0_mask_set(priv, P_IRQ_MASK(P0_IRQ_OFF));
    266		intrl2_0_writel(priv, P_IRQ_MASK(P0_IRQ_OFF), INTRL2_CPU_CLEAR);
    267		return;
    268	default:
    269		off = P_IRQ_OFF(port);
    270		break;
    271	}
    272
    273	intrl2_1_mask_set(priv, P_IRQ_MASK(off));
    274	intrl2_1_writel(priv, P_IRQ_MASK(off), INTRL2_CPU_CLEAR);
    275}
    276
    277static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
    278			      struct phy_device *phy)
    279{
    280	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    281	unsigned int i;
    282	u32 reg;
    283
    284	if (!dsa_is_user_port(ds, port))
    285		return 0;
    286
    287	priv->port_sts[port].enabled = true;
    288
    289	bcm_sf2_recalc_clock(ds);
    290
    291	/* Clear the memory power down */
    292	reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL);
    293	reg &= ~P_TXQ_PSM_VDD(port);
    294	core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
    295
    296	/* Enable Broadcom tags for that port if requested */
    297	if (priv->brcm_tag_mask & BIT(port))
    298		b53_brcm_hdr_setup(ds, port);
    299
    300	/* Configure Traffic Class to QoS mapping, allow each priority to map
    301	 * to a different queue number
    302	 */
    303	reg = core_readl(priv, CORE_PORT_TC2_QOS_MAP_PORT(port));
    304	for (i = 0; i < SF2_NUM_EGRESS_QUEUES; i++)
    305		reg |= i << (PRT_TO_QID_SHIFT * i);
    306	core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port));
    307
    308	/* Re-enable the GPHY and re-apply workarounds */
    309	if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1) {
    310		bcm_sf2_gphy_enable_set(ds, true);
    311		if (phy) {
    312			/* if phy_stop() has been called before, phy
    313			 * will be in halted state, and phy_start()
    314			 * will call resume.
    315			 *
    316			 * the resume path does not configure back
    317			 * autoneg settings, and since we hard reset
    318			 * the phy manually here, we need to reset the
    319			 * state machine also.
    320			 */
    321			phy->state = PHY_READY;
    322			phy_init_hw(phy);
    323		}
    324	}
    325
    326	/* Enable MoCA port interrupts to get notified */
    327	if (port == priv->moca_port)
    328		bcm_sf2_port_intr_enable(priv, port);
    329
    330	/* Set per-queue pause threshold to 32 */
    331	core_writel(priv, 32, CORE_TXQ_THD_PAUSE_QN_PORT(port));
    332
    333	/* Set ACB threshold to 24 */
    334	for (i = 0; i < SF2_NUM_EGRESS_QUEUES; i++) {
    335		reg = acb_readl(priv, ACB_QUEUE_CFG(port *
    336						    SF2_NUM_EGRESS_QUEUES + i));
    337		reg &= ~XOFF_THRESHOLD_MASK;
    338		reg |= 24;
    339		acb_writel(priv, reg, ACB_QUEUE_CFG(port *
    340						    SF2_NUM_EGRESS_QUEUES + i));
    341	}
    342
    343	return b53_enable_port(ds, port, phy);
    344}
    345
    346static void bcm_sf2_port_disable(struct dsa_switch *ds, int port)
    347{
    348	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    349	u32 reg;
    350
    351	/* Disable learning while in WoL mode */
    352	if (priv->wol_ports_mask & (1 << port)) {
    353		reg = core_readl(priv, CORE_DIS_LEARN);
    354		reg |= BIT(port);
    355		core_writel(priv, reg, CORE_DIS_LEARN);
    356		return;
    357	}
    358
    359	if (port == priv->moca_port)
    360		bcm_sf2_port_intr_disable(priv, port);
    361
    362	if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1)
    363		bcm_sf2_gphy_enable_set(ds, false);
    364
    365	b53_disable_port(ds, port);
    366
    367	/* Power down the port memory */
    368	reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL);
    369	reg |= P_TXQ_PSM_VDD(port);
    370	core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
    371
    372	priv->port_sts[port].enabled = false;
    373
    374	bcm_sf2_recalc_clock(ds);
    375}
    376
    377
    378static int bcm_sf2_sw_indir_rw(struct bcm_sf2_priv *priv, int op, int addr,
    379			       int regnum, u16 val)
    380{
    381	int ret = 0;
    382	u32 reg;
    383
    384	reg = reg_readl(priv, REG_SWITCH_CNTRL);
    385	reg |= MDIO_MASTER_SEL;
    386	reg_writel(priv, reg, REG_SWITCH_CNTRL);
    387
    388	/* Page << 8 | offset */
    389	reg = 0x70;
    390	reg <<= 2;
    391	core_writel(priv, addr, reg);
    392
    393	/* Page << 8 | offset */
    394	reg = 0x80 << 8 | regnum << 1;
    395	reg <<= 2;
    396
    397	if (op)
    398		ret = core_readl(priv, reg);
    399	else
    400		core_writel(priv, val, reg);
    401
    402	reg = reg_readl(priv, REG_SWITCH_CNTRL);
    403	reg &= ~MDIO_MASTER_SEL;
    404	reg_writel(priv, reg, REG_SWITCH_CNTRL);
    405
    406	return ret & 0xffff;
    407}
    408
    409static int bcm_sf2_sw_mdio_read(struct mii_bus *bus, int addr, int regnum)
    410{
    411	struct bcm_sf2_priv *priv = bus->priv;
    412
    413	/* Intercept reads from Broadcom pseudo-PHY address, else, send
    414	 * them to our master MDIO bus controller
    415	 */
    416	if (addr == BRCM_PSEUDO_PHY_ADDR && priv->indir_phy_mask & BIT(addr))
    417		return bcm_sf2_sw_indir_rw(priv, 1, addr, regnum, 0);
    418	else
    419		return mdiobus_read_nested(priv->master_mii_bus, addr, regnum);
    420}
    421
    422static int bcm_sf2_sw_mdio_write(struct mii_bus *bus, int addr, int regnum,
    423				 u16 val)
    424{
    425	struct bcm_sf2_priv *priv = bus->priv;
    426
    427	/* Intercept writes to the Broadcom pseudo-PHY address, else,
    428	 * send them to our master MDIO bus controller
    429	 */
    430	if (addr == BRCM_PSEUDO_PHY_ADDR && priv->indir_phy_mask & BIT(addr))
    431		return bcm_sf2_sw_indir_rw(priv, 0, addr, regnum, val);
    432	else
    433		return mdiobus_write_nested(priv->master_mii_bus, addr,
    434				regnum, val);
    435}
    436
    437static irqreturn_t bcm_sf2_switch_0_isr(int irq, void *dev_id)
    438{
    439	struct dsa_switch *ds = dev_id;
    440	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    441
    442	priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) &
    443				~priv->irq0_mask;
    444	intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR);
    445
    446	return IRQ_HANDLED;
    447}
    448
    449static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id)
    450{
    451	struct dsa_switch *ds = dev_id;
    452	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    453
    454	priv->irq1_stat = intrl2_1_readl(priv, INTRL2_CPU_STATUS) &
    455				~priv->irq1_mask;
    456	intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR);
    457
    458	if (priv->irq1_stat & P_LINK_UP_IRQ(P7_IRQ_OFF)) {
    459		priv->port_sts[7].link = true;
    460		dsa_port_phylink_mac_change(ds, 7, true);
    461	}
    462	if (priv->irq1_stat & P_LINK_DOWN_IRQ(P7_IRQ_OFF)) {
    463		priv->port_sts[7].link = false;
    464		dsa_port_phylink_mac_change(ds, 7, false);
    465	}
    466
    467	return IRQ_HANDLED;
    468}
    469
    470static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv)
    471{
    472	unsigned int timeout = 1000;
    473	u32 reg;
    474	int ret;
    475
    476	/* The watchdog reset does not work on 7278, we need to hit the
    477	 * "external" reset line through the reset controller.
    478	 */
    479	if (priv->type == BCM7278_DEVICE_ID) {
    480		ret = reset_control_assert(priv->rcdev);
    481		if (ret)
    482			return ret;
    483
    484		return reset_control_deassert(priv->rcdev);
    485	}
    486
    487	reg = core_readl(priv, CORE_WATCHDOG_CTRL);
    488	reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET;
    489	core_writel(priv, reg, CORE_WATCHDOG_CTRL);
    490
    491	do {
    492		reg = core_readl(priv, CORE_WATCHDOG_CTRL);
    493		if (!(reg & SOFTWARE_RESET))
    494			break;
    495
    496		usleep_range(1000, 2000);
    497	} while (timeout-- > 0);
    498
    499	if (timeout == 0)
    500		return -ETIMEDOUT;
    501
    502	return 0;
    503}
    504
    505static void bcm_sf2_crossbar_setup(struct bcm_sf2_priv *priv)
    506{
    507	struct device *dev = priv->dev->ds->dev;
    508	int shift;
    509	u32 mask;
    510	u32 reg;
    511	int i;
    512
    513	mask = BIT(priv->num_crossbar_int_ports) - 1;
    514
    515	reg = reg_readl(priv, REG_CROSSBAR);
    516	switch (priv->type) {
    517	case BCM4908_DEVICE_ID:
    518		shift = CROSSBAR_BCM4908_INT_P7 * priv->num_crossbar_int_ports;
    519		reg &= ~(mask << shift);
    520		if (0) /* FIXME */
    521			reg |= CROSSBAR_BCM4908_EXT_SERDES << shift;
    522		else if (priv->int_phy_mask & BIT(7))
    523			reg |= CROSSBAR_BCM4908_EXT_GPHY4 << shift;
    524		else if (phy_interface_mode_is_rgmii(priv->port_sts[7].mode))
    525			reg |= CROSSBAR_BCM4908_EXT_RGMII << shift;
    526		else if (WARN(1, "Invalid port mode\n"))
    527			return;
    528		break;
    529	default:
    530		return;
    531	}
    532	reg_writel(priv, reg, REG_CROSSBAR);
    533
    534	reg = reg_readl(priv, REG_CROSSBAR);
    535	for (i = 0; i < priv->num_crossbar_int_ports; i++) {
    536		shift = i * priv->num_crossbar_int_ports;
    537
    538		dev_dbg(dev, "crossbar int port #%d - ext port #%d\n", i,
    539			(reg >> shift) & mask);
    540	}
    541}
    542
    543static void bcm_sf2_intr_disable(struct bcm_sf2_priv *priv)
    544{
    545	intrl2_0_mask_set(priv, 0xffffffff);
    546	intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
    547	intrl2_1_mask_set(priv, 0xffffffff);
    548	intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
    549}
    550
    551static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv,
    552				   struct device_node *dn)
    553{
    554	struct device *dev = priv->dev->ds->dev;
    555	struct bcm_sf2_port_status *port_st;
    556	struct device_node *port;
    557	unsigned int port_num;
    558	struct property *prop;
    559	int err;
    560
    561	priv->moca_port = -1;
    562
    563	for_each_available_child_of_node(dn, port) {
    564		if (of_property_read_u32(port, "reg", &port_num))
    565			continue;
    566
    567		if (port_num >= DSA_MAX_PORTS) {
    568			dev_err(dev, "Invalid port number %d\n", port_num);
    569			continue;
    570		}
    571
    572		port_st = &priv->port_sts[port_num];
    573
    574		/* Internal PHYs get assigned a specific 'phy-mode' property
    575		 * value: "internal" to help flag them before MDIO probing
    576		 * has completed, since they might be turned off at that
    577		 * time
    578		 */
    579		err = of_get_phy_mode(port, &port_st->mode);
    580		if (err)
    581			continue;
    582
    583		if (port_st->mode == PHY_INTERFACE_MODE_INTERNAL)
    584			priv->int_phy_mask |= 1 << port_num;
    585
    586		if (port_st->mode == PHY_INTERFACE_MODE_MOCA)
    587			priv->moca_port = port_num;
    588
    589		if (of_property_read_bool(port, "brcm,use-bcm-hdr"))
    590			priv->brcm_tag_mask |= 1 << port_num;
    591
    592		/* Ensure that port 5 is not picked up as a DSA CPU port
    593		 * flavour but a regular port instead. We should be using
    594		 * devlink to be able to set the port flavour.
    595		 */
    596		if (port_num == 5 && priv->type == BCM7278_DEVICE_ID) {
    597			prop = of_find_property(port, "ethernet", NULL);
    598			if (prop)
    599				of_remove_property(port, prop);
    600		}
    601	}
    602}
    603
    604static int bcm_sf2_mdio_register(struct dsa_switch *ds)
    605{
    606	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    607	struct device_node *dn, *child;
    608	struct phy_device *phydev;
    609	struct property *prop;
    610	static int index;
    611	int err, reg;
    612
    613	/* Find our integrated MDIO bus node */
    614	dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio");
    615	priv->master_mii_bus = of_mdio_find_bus(dn);
    616	if (!priv->master_mii_bus) {
    617		of_node_put(dn);
    618		return -EPROBE_DEFER;
    619	}
    620
    621	get_device(&priv->master_mii_bus->dev);
    622	priv->master_mii_dn = dn;
    623
    624	priv->slave_mii_bus = mdiobus_alloc();
    625	if (!priv->slave_mii_bus) {
    626		of_node_put(dn);
    627		return -ENOMEM;
    628	}
    629
    630	priv->slave_mii_bus->priv = priv;
    631	priv->slave_mii_bus->name = "sf2 slave mii";
    632	priv->slave_mii_bus->read = bcm_sf2_sw_mdio_read;
    633	priv->slave_mii_bus->write = bcm_sf2_sw_mdio_write;
    634	snprintf(priv->slave_mii_bus->id, MII_BUS_ID_SIZE, "sf2-%d",
    635		 index++);
    636	priv->slave_mii_bus->dev.of_node = dn;
    637
    638	/* Include the pseudo-PHY address to divert reads towards our
    639	 * workaround. This is only required for 7445D0, since 7445E0
    640	 * disconnects the internal switch pseudo-PHY such that we can use the
    641	 * regular SWITCH_MDIO master controller instead.
    642	 *
    643	 * Here we flag the pseudo PHY as needing special treatment and would
    644	 * otherwise make all other PHY read/writes go to the master MDIO bus
    645	 * controller that comes with this switch backed by the "mdio-unimac"
    646	 * driver.
    647	 */
    648	if (of_machine_is_compatible("brcm,bcm7445d0"))
    649		priv->indir_phy_mask |= (1 << BRCM_PSEUDO_PHY_ADDR) | (1 << 0);
    650	else
    651		priv->indir_phy_mask = 0;
    652
    653	ds->phys_mii_mask = priv->indir_phy_mask;
    654	ds->slave_mii_bus = priv->slave_mii_bus;
    655	priv->slave_mii_bus->parent = ds->dev->parent;
    656	priv->slave_mii_bus->phy_mask = ~priv->indir_phy_mask;
    657
    658	/* We need to make sure that of_phy_connect() will not work by
    659	 * removing the 'phandle' and 'linux,phandle' properties and
    660	 * unregister the existing PHY device that was already registered.
    661	 */
    662	for_each_available_child_of_node(dn, child) {
    663		if (of_property_read_u32(child, "reg", &reg) ||
    664		    reg >= PHY_MAX_ADDR)
    665			continue;
    666
    667		if (!(priv->indir_phy_mask & BIT(reg)))
    668			continue;
    669
    670		prop = of_find_property(child, "phandle", NULL);
    671		if (prop)
    672			of_remove_property(child, prop);
    673
    674		prop = of_find_property(child, "linux,phandle", NULL);
    675		if (prop)
    676			of_remove_property(child, prop);
    677
    678		phydev = of_phy_find_device(child);
    679		if (phydev)
    680			phy_device_remove(phydev);
    681	}
    682
    683	err = mdiobus_register(priv->slave_mii_bus);
    684	if (err && dn) {
    685		mdiobus_free(priv->slave_mii_bus);
    686		of_node_put(dn);
    687	}
    688
    689	return err;
    690}
    691
    692static void bcm_sf2_mdio_unregister(struct bcm_sf2_priv *priv)
    693{
    694	mdiobus_unregister(priv->slave_mii_bus);
    695	mdiobus_free(priv->slave_mii_bus);
    696	of_node_put(priv->master_mii_dn);
    697}
    698
    699static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port)
    700{
    701	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    702
    703	/* The BCM7xxx PHY driver expects to find the integrated PHY revision
    704	 * in bits 15:8 and the patch level in bits 7:0 which is exactly what
    705	 * the REG_PHY_REVISION register layout is.
    706	 */
    707	if (priv->int_phy_mask & BIT(port))
    708		return priv->hw_params.gphy_rev;
    709	else
    710		return PHY_BRCM_AUTO_PWRDWN_ENABLE |
    711		       PHY_BRCM_DIS_TXCRXC_NOENRGY |
    712		       PHY_BRCM_IDDQ_SUSPEND;
    713}
    714
    715static void bcm_sf2_sw_get_caps(struct dsa_switch *ds, int port,
    716				struct phylink_config *config)
    717{
    718	unsigned long *interfaces = config->supported_interfaces;
    719	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    720
    721	if (priv->int_phy_mask & BIT(port)) {
    722		__set_bit(PHY_INTERFACE_MODE_INTERNAL, interfaces);
    723	} else if (priv->moca_port == port) {
    724		__set_bit(PHY_INTERFACE_MODE_MOCA, interfaces);
    725	} else {
    726		__set_bit(PHY_INTERFACE_MODE_MII, interfaces);
    727		__set_bit(PHY_INTERFACE_MODE_REVMII, interfaces);
    728		__set_bit(PHY_INTERFACE_MODE_GMII, interfaces);
    729		phy_interface_set_rgmii(interfaces);
    730	}
    731
    732	config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
    733		MAC_10 | MAC_100 | MAC_1000;
    734}
    735
    736static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
    737				  unsigned int mode,
    738				  const struct phylink_link_state *state)
    739{
    740	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    741	u32 id_mode_dis = 0, port_mode;
    742	u32 reg_rgmii_ctrl;
    743	u32 reg;
    744
    745	if (port == core_readl(priv, CORE_IMP0_PRT_ID))
    746		return;
    747
    748	switch (state->interface) {
    749	case PHY_INTERFACE_MODE_RGMII:
    750		id_mode_dis = 1;
    751		fallthrough;
    752	case PHY_INTERFACE_MODE_RGMII_TXID:
    753		port_mode = EXT_GPHY;
    754		break;
    755	case PHY_INTERFACE_MODE_MII:
    756		port_mode = EXT_EPHY;
    757		break;
    758	case PHY_INTERFACE_MODE_REVMII:
    759		port_mode = EXT_REVMII;
    760		break;
    761	default:
    762		/* Nothing required for all other PHYs: internal and MoCA */
    763		return;
    764	}
    765
    766	reg_rgmii_ctrl = bcm_sf2_reg_rgmii_cntrl(priv, port);
    767
    768	/* Clear id_mode_dis bit, and the existing port mode, let
    769	 * RGMII_MODE_EN bet set by mac_link_{up,down}
    770	 */
    771	reg = reg_readl(priv, reg_rgmii_ctrl);
    772	reg &= ~ID_MODE_DIS;
    773	reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
    774
    775	reg |= port_mode;
    776	if (id_mode_dis)
    777		reg |= ID_MODE_DIS;
    778
    779	reg_writel(priv, reg, reg_rgmii_ctrl);
    780}
    781
    782static void bcm_sf2_sw_mac_link_set(struct dsa_switch *ds, int port,
    783				    phy_interface_t interface, bool link)
    784{
    785	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    786	u32 reg_rgmii_ctrl;
    787	u32 reg;
    788
    789	if (!phy_interface_mode_is_rgmii(interface) &&
    790	    interface != PHY_INTERFACE_MODE_MII &&
    791	    interface != PHY_INTERFACE_MODE_REVMII)
    792		return;
    793
    794	reg_rgmii_ctrl = bcm_sf2_reg_rgmii_cntrl(priv, port);
    795
    796	/* If the link is down, just disable the interface to conserve power */
    797	reg = reg_readl(priv, reg_rgmii_ctrl);
    798	if (link)
    799		reg |= RGMII_MODE_EN;
    800	else
    801		reg &= ~RGMII_MODE_EN;
    802	reg_writel(priv, reg, reg_rgmii_ctrl);
    803}
    804
    805static void bcm_sf2_sw_mac_link_down(struct dsa_switch *ds, int port,
    806				     unsigned int mode,
    807				     phy_interface_t interface)
    808{
    809	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    810	u32 reg, offset;
    811
    812	if (priv->wol_ports_mask & BIT(port))
    813		return;
    814
    815	if (port != core_readl(priv, CORE_IMP0_PRT_ID)) {
    816		if (priv->type == BCM4908_DEVICE_ID ||
    817		    priv->type == BCM7445_DEVICE_ID)
    818			offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
    819		else
    820			offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
    821
    822		reg = core_readl(priv, offset);
    823		reg &= ~LINK_STS;
    824		core_writel(priv, reg, offset);
    825	}
    826
    827	bcm_sf2_sw_mac_link_set(ds, port, interface, false);
    828}
    829
    830static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
    831				   unsigned int mode,
    832				   phy_interface_t interface,
    833				   struct phy_device *phydev,
    834				   int speed, int duplex,
    835				   bool tx_pause, bool rx_pause)
    836{
    837	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    838	struct ethtool_eee *p = &priv->dev->ports[port].eee;
    839
    840	bcm_sf2_sw_mac_link_set(ds, port, interface, true);
    841
    842	if (port != core_readl(priv, CORE_IMP0_PRT_ID)) {
    843		u32 reg_rgmii_ctrl = 0;
    844		u32 reg, offset;
    845
    846		if (priv->type == BCM4908_DEVICE_ID ||
    847		    priv->type == BCM7445_DEVICE_ID)
    848			offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
    849		else
    850			offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
    851
    852		if (interface == PHY_INTERFACE_MODE_RGMII ||
    853		    interface == PHY_INTERFACE_MODE_RGMII_TXID ||
    854		    interface == PHY_INTERFACE_MODE_MII ||
    855		    interface == PHY_INTERFACE_MODE_REVMII) {
    856			reg_rgmii_ctrl = bcm_sf2_reg_rgmii_cntrl(priv, port);
    857			reg = reg_readl(priv, reg_rgmii_ctrl);
    858			reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
    859
    860			if (tx_pause)
    861				reg |= TX_PAUSE_EN;
    862			if (rx_pause)
    863				reg |= RX_PAUSE_EN;
    864
    865			reg_writel(priv, reg, reg_rgmii_ctrl);
    866		}
    867
    868		reg = SW_OVERRIDE | LINK_STS;
    869		switch (speed) {
    870		case SPEED_1000:
    871			reg |= SPDSTS_1000 << SPEED_SHIFT;
    872			break;
    873		case SPEED_100:
    874			reg |= SPDSTS_100 << SPEED_SHIFT;
    875			break;
    876		}
    877
    878		if (duplex == DUPLEX_FULL)
    879			reg |= DUPLX_MODE;
    880
    881		if (tx_pause)
    882			reg |= TXFLOW_CNTL;
    883		if (rx_pause)
    884			reg |= RXFLOW_CNTL;
    885
    886		core_writel(priv, reg, offset);
    887	}
    888
    889	if (mode == MLO_AN_PHY && phydev)
    890		p->eee_enabled = b53_eee_init(ds, port, phydev);
    891}
    892
    893static void bcm_sf2_sw_fixed_state(struct dsa_switch *ds, int port,
    894				   struct phylink_link_state *status)
    895{
    896	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    897
    898	status->link = false;
    899
    900	/* MoCA port is special as we do not get link status from CORE_LNKSTS,
    901	 * which means that we need to force the link at the port override
    902	 * level to get the data to flow. We do use what the interrupt handler
    903	 * did determine before.
    904	 *
    905	 * For the other ports, we just force the link status, since this is
    906	 * a fixed PHY device.
    907	 */
    908	if (port == priv->moca_port) {
    909		status->link = priv->port_sts[port].link;
    910		/* For MoCA interfaces, also force a link down notification
    911		 * since some version of the user-space daemon (mocad) use
    912		 * cmd->autoneg to force the link, which messes up the PHY
    913		 * state machine and make it go in PHY_FORCING state instead.
    914		 */
    915		if (!status->link)
    916			netif_carrier_off(dsa_to_port(ds, port)->slave);
    917		status->duplex = DUPLEX_FULL;
    918	} else {
    919		status->link = true;
    920	}
    921}
    922
    923static void bcm_sf2_enable_acb(struct dsa_switch *ds)
    924{
    925	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    926	u32 reg;
    927
    928	/* Enable ACB globally */
    929	reg = acb_readl(priv, ACB_CONTROL);
    930	reg |= (ACB_FLUSH_MASK << ACB_FLUSH_SHIFT);
    931	acb_writel(priv, reg, ACB_CONTROL);
    932	reg &= ~(ACB_FLUSH_MASK << ACB_FLUSH_SHIFT);
    933	reg |= ACB_EN | ACB_ALGORITHM;
    934	acb_writel(priv, reg, ACB_CONTROL);
    935}
    936
    937static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
    938{
    939	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    940	unsigned int port;
    941
    942	bcm_sf2_intr_disable(priv);
    943
    944	/* Disable all ports physically present including the IMP
    945	 * port, the other ones have already been disabled during
    946	 * bcm_sf2_sw_setup
    947	 */
    948	for (port = 0; port < ds->num_ports; port++) {
    949		if (dsa_is_user_port(ds, port) || dsa_is_cpu_port(ds, port))
    950			bcm_sf2_port_disable(ds, port);
    951	}
    952
    953	if (!priv->wol_ports_mask)
    954		clk_disable_unprepare(priv->clk);
    955
    956	return 0;
    957}
    958
    959static int bcm_sf2_sw_resume(struct dsa_switch *ds)
    960{
    961	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    962	int ret;
    963
    964	if (!priv->wol_ports_mask)
    965		clk_prepare_enable(priv->clk);
    966
    967	ret = bcm_sf2_sw_rst(priv);
    968	if (ret) {
    969		pr_err("%s: failed to software reset switch\n", __func__);
    970		return ret;
    971	}
    972
    973	bcm_sf2_crossbar_setup(priv);
    974
    975	ret = bcm_sf2_cfp_resume(ds);
    976	if (ret)
    977		return ret;
    978
    979	if (priv->hw_params.num_gphy == 1)
    980		bcm_sf2_gphy_enable_set(ds, true);
    981
    982	ds->ops->setup(ds);
    983
    984	return 0;
    985}
    986
    987static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port,
    988			       struct ethtool_wolinfo *wol)
    989{
    990	struct net_device *p = dsa_to_port(ds, port)->cpu_dp->master;
    991	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
    992	struct ethtool_wolinfo pwol = { };
    993
    994	/* Get the parent device WoL settings */
    995	if (p->ethtool_ops->get_wol)
    996		p->ethtool_ops->get_wol(p, &pwol);
    997
    998	/* Advertise the parent device supported settings */
    999	wol->supported = pwol.supported;
   1000	memset(&wol->sopass, 0, sizeof(wol->sopass));
   1001
   1002	if (pwol.wolopts & WAKE_MAGICSECURE)
   1003		memcpy(&wol->sopass, pwol.sopass, sizeof(wol->sopass));
   1004
   1005	if (priv->wol_ports_mask & (1 << port))
   1006		wol->wolopts = pwol.wolopts;
   1007	else
   1008		wol->wolopts = 0;
   1009}
   1010
   1011static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,
   1012			      struct ethtool_wolinfo *wol)
   1013{
   1014	struct net_device *p = dsa_to_port(ds, port)->cpu_dp->master;
   1015	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
   1016	s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
   1017	struct ethtool_wolinfo pwol =  { };
   1018
   1019	if (p->ethtool_ops->get_wol)
   1020		p->ethtool_ops->get_wol(p, &pwol);
   1021	if (wol->wolopts & ~pwol.supported)
   1022		return -EINVAL;
   1023
   1024	if (wol->wolopts)
   1025		priv->wol_ports_mask |= (1 << port);
   1026	else
   1027		priv->wol_ports_mask &= ~(1 << port);
   1028
   1029	/* If we have at least one port enabled, make sure the CPU port
   1030	 * is also enabled. If the CPU port is the last one enabled, we disable
   1031	 * it since this configuration does not make sense.
   1032	 */
   1033	if (priv->wol_ports_mask && priv->wol_ports_mask != (1 << cpu_port))
   1034		priv->wol_ports_mask |= (1 << cpu_port);
   1035	else
   1036		priv->wol_ports_mask &= ~(1 << cpu_port);
   1037
   1038	return p->ethtool_ops->set_wol(p, wol);
   1039}
   1040
   1041static int bcm_sf2_sw_setup(struct dsa_switch *ds)
   1042{
   1043	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
   1044	unsigned int port;
   1045
   1046	/* Enable all valid ports and disable those unused */
   1047	for (port = 0; port < priv->hw_params.num_ports; port++) {
   1048		/* IMP port receives special treatment */
   1049		if (dsa_is_user_port(ds, port))
   1050			bcm_sf2_port_setup(ds, port, NULL);
   1051		else if (dsa_is_cpu_port(ds, port))
   1052			bcm_sf2_imp_setup(ds, port);
   1053		else
   1054			bcm_sf2_port_disable(ds, port);
   1055	}
   1056
   1057	b53_configure_vlan(ds);
   1058	bcm_sf2_enable_acb(ds);
   1059
   1060	return b53_setup_devlink_resources(ds);
   1061}
   1062
   1063static void bcm_sf2_sw_teardown(struct dsa_switch *ds)
   1064{
   1065	dsa_devlink_resources_unregister(ds);
   1066}
   1067
   1068/* The SWITCH_CORE register space is managed by b53 but operates on a page +
   1069 * register basis so we need to translate that into an address that the
   1070 * bus-glue understands.
   1071 */
   1072#define SF2_PAGE_REG_MKADDR(page, reg)	((page) << 10 | (reg) << 2)
   1073
   1074static int bcm_sf2_core_read8(struct b53_device *dev, u8 page, u8 reg,
   1075			      u8 *val)
   1076{
   1077	struct bcm_sf2_priv *priv = dev->priv;
   1078
   1079	*val = core_readl(priv, SF2_PAGE_REG_MKADDR(page, reg));
   1080
   1081	return 0;
   1082}
   1083
   1084static int bcm_sf2_core_read16(struct b53_device *dev, u8 page, u8 reg,
   1085			       u16 *val)
   1086{
   1087	struct bcm_sf2_priv *priv = dev->priv;
   1088
   1089	*val = core_readl(priv, SF2_PAGE_REG_MKADDR(page, reg));
   1090
   1091	return 0;
   1092}
   1093
   1094static int bcm_sf2_core_read32(struct b53_device *dev, u8 page, u8 reg,
   1095			       u32 *val)
   1096{
   1097	struct bcm_sf2_priv *priv = dev->priv;
   1098
   1099	*val = core_readl(priv, SF2_PAGE_REG_MKADDR(page, reg));
   1100
   1101	return 0;
   1102}
   1103
   1104static int bcm_sf2_core_read64(struct b53_device *dev, u8 page, u8 reg,
   1105			       u64 *val)
   1106{
   1107	struct bcm_sf2_priv *priv = dev->priv;
   1108
   1109	*val = core_readq(priv, SF2_PAGE_REG_MKADDR(page, reg));
   1110
   1111	return 0;
   1112}
   1113
   1114static int bcm_sf2_core_write8(struct b53_device *dev, u8 page, u8 reg,
   1115			       u8 value)
   1116{
   1117	struct bcm_sf2_priv *priv = dev->priv;
   1118
   1119	core_writel(priv, value, SF2_PAGE_REG_MKADDR(page, reg));
   1120
   1121	return 0;
   1122}
   1123
   1124static int bcm_sf2_core_write16(struct b53_device *dev, u8 page, u8 reg,
   1125				u16 value)
   1126{
   1127	struct bcm_sf2_priv *priv = dev->priv;
   1128
   1129	core_writel(priv, value, SF2_PAGE_REG_MKADDR(page, reg));
   1130
   1131	return 0;
   1132}
   1133
   1134static int bcm_sf2_core_write32(struct b53_device *dev, u8 page, u8 reg,
   1135				u32 value)
   1136{
   1137	struct bcm_sf2_priv *priv = dev->priv;
   1138
   1139	core_writel(priv, value, SF2_PAGE_REG_MKADDR(page, reg));
   1140
   1141	return 0;
   1142}
   1143
   1144static int bcm_sf2_core_write64(struct b53_device *dev, u8 page, u8 reg,
   1145				u64 value)
   1146{
   1147	struct bcm_sf2_priv *priv = dev->priv;
   1148
   1149	core_writeq(priv, value, SF2_PAGE_REG_MKADDR(page, reg));
   1150
   1151	return 0;
   1152}
   1153
   1154static const struct b53_io_ops bcm_sf2_io_ops = {
   1155	.read8	= bcm_sf2_core_read8,
   1156	.read16	= bcm_sf2_core_read16,
   1157	.read32	= bcm_sf2_core_read32,
   1158	.read48	= bcm_sf2_core_read64,
   1159	.read64	= bcm_sf2_core_read64,
   1160	.write8	= bcm_sf2_core_write8,
   1161	.write16 = bcm_sf2_core_write16,
   1162	.write32 = bcm_sf2_core_write32,
   1163	.write48 = bcm_sf2_core_write64,
   1164	.write64 = bcm_sf2_core_write64,
   1165};
   1166
   1167static void bcm_sf2_sw_get_strings(struct dsa_switch *ds, int port,
   1168				   u32 stringset, uint8_t *data)
   1169{
   1170	int cnt = b53_get_sset_count(ds, port, stringset);
   1171
   1172	b53_get_strings(ds, port, stringset, data);
   1173	bcm_sf2_cfp_get_strings(ds, port, stringset,
   1174				data + cnt * ETH_GSTRING_LEN);
   1175}
   1176
   1177static void bcm_sf2_sw_get_ethtool_stats(struct dsa_switch *ds, int port,
   1178					 uint64_t *data)
   1179{
   1180	int cnt = b53_get_sset_count(ds, port, ETH_SS_STATS);
   1181
   1182	b53_get_ethtool_stats(ds, port, data);
   1183	bcm_sf2_cfp_get_ethtool_stats(ds, port, data + cnt);
   1184}
   1185
   1186static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds, int port,
   1187				     int sset)
   1188{
   1189	int cnt = b53_get_sset_count(ds, port, sset);
   1190
   1191	if (cnt < 0)
   1192		return cnt;
   1193
   1194	cnt += bcm_sf2_cfp_get_sset_count(ds, port, sset);
   1195
   1196	return cnt;
   1197}
   1198
   1199static const struct dsa_switch_ops bcm_sf2_ops = {
   1200	.get_tag_protocol	= b53_get_tag_protocol,
   1201	.setup			= bcm_sf2_sw_setup,
   1202	.teardown		= bcm_sf2_sw_teardown,
   1203	.get_strings		= bcm_sf2_sw_get_strings,
   1204	.get_ethtool_stats	= bcm_sf2_sw_get_ethtool_stats,
   1205	.get_sset_count		= bcm_sf2_sw_get_sset_count,
   1206	.get_ethtool_phy_stats	= b53_get_ethtool_phy_stats,
   1207	.get_phy_flags		= bcm_sf2_sw_get_phy_flags,
   1208	.phylink_get_caps	= bcm_sf2_sw_get_caps,
   1209	.phylink_mac_config	= bcm_sf2_sw_mac_config,
   1210	.phylink_mac_link_down	= bcm_sf2_sw_mac_link_down,
   1211	.phylink_mac_link_up	= bcm_sf2_sw_mac_link_up,
   1212	.phylink_fixed_state	= bcm_sf2_sw_fixed_state,
   1213	.suspend		= bcm_sf2_sw_suspend,
   1214	.resume			= bcm_sf2_sw_resume,
   1215	.get_wol		= bcm_sf2_sw_get_wol,
   1216	.set_wol		= bcm_sf2_sw_set_wol,
   1217	.port_enable		= bcm_sf2_port_setup,
   1218	.port_disable		= bcm_sf2_port_disable,
   1219	.get_mac_eee		= b53_get_mac_eee,
   1220	.set_mac_eee		= b53_set_mac_eee,
   1221	.port_bridge_join	= b53_br_join,
   1222	.port_bridge_leave	= b53_br_leave,
   1223	.port_pre_bridge_flags	= b53_br_flags_pre,
   1224	.port_bridge_flags	= b53_br_flags,
   1225	.port_stp_state_set	= b53_br_set_stp_state,
   1226	.port_fast_age		= b53_br_fast_age,
   1227	.port_vlan_filtering	= b53_vlan_filtering,
   1228	.port_vlan_add		= b53_vlan_add,
   1229	.port_vlan_del		= b53_vlan_del,
   1230	.port_fdb_dump		= b53_fdb_dump,
   1231	.port_fdb_add		= b53_fdb_add,
   1232	.port_fdb_del		= b53_fdb_del,
   1233	.get_rxnfc		= bcm_sf2_get_rxnfc,
   1234	.set_rxnfc		= bcm_sf2_set_rxnfc,
   1235	.port_mirror_add	= b53_mirror_add,
   1236	.port_mirror_del	= b53_mirror_del,
   1237	.port_mdb_add		= b53_mdb_add,
   1238	.port_mdb_del		= b53_mdb_del,
   1239};
   1240
   1241struct bcm_sf2_of_data {
   1242	u32 type;
   1243	const u16 *reg_offsets;
   1244	unsigned int core_reg_align;
   1245	unsigned int num_cfp_rules;
   1246	unsigned int num_crossbar_int_ports;
   1247};
   1248
   1249static const u16 bcm_sf2_4908_reg_offsets[] = {
   1250	[REG_SWITCH_CNTRL]	= 0x00,
   1251	[REG_SWITCH_STATUS]	= 0x04,
   1252	[REG_DIR_DATA_WRITE]	= 0x08,
   1253	[REG_DIR_DATA_READ]	= 0x0c,
   1254	[REG_SWITCH_REVISION]	= 0x10,
   1255	[REG_PHY_REVISION]	= 0x14,
   1256	[REG_SPHY_CNTRL]	= 0x24,
   1257	[REG_CROSSBAR]		= 0xc8,
   1258	[REG_RGMII_11_CNTRL]	= 0x014c,
   1259	[REG_LED_0_CNTRL]		= 0x40,
   1260	[REG_LED_1_CNTRL]		= 0x4c,
   1261	[REG_LED_2_CNTRL]		= 0x58,
   1262	[REG_LED_3_CNTRL]		= 0x64,
   1263	[REG_LED_4_CNTRL]		= 0x88,
   1264	[REG_LED_5_CNTRL]		= 0xa0,
   1265	[REG_LED_AGGREGATE_CTRL]	= 0xb8,
   1266
   1267};
   1268
   1269static const struct bcm_sf2_of_data bcm_sf2_4908_data = {
   1270	.type		= BCM4908_DEVICE_ID,
   1271	.core_reg_align	= 0,
   1272	.reg_offsets	= bcm_sf2_4908_reg_offsets,
   1273	.num_cfp_rules	= 256,
   1274	.num_crossbar_int_ports = 2,
   1275};
   1276
   1277/* Register offsets for the SWITCH_REG_* block */
   1278static const u16 bcm_sf2_7445_reg_offsets[] = {
   1279	[REG_SWITCH_CNTRL]	= 0x00,
   1280	[REG_SWITCH_STATUS]	= 0x04,
   1281	[REG_DIR_DATA_WRITE]	= 0x08,
   1282	[REG_DIR_DATA_READ]	= 0x0C,
   1283	[REG_SWITCH_REVISION]	= 0x18,
   1284	[REG_PHY_REVISION]	= 0x1C,
   1285	[REG_SPHY_CNTRL]	= 0x2C,
   1286	[REG_RGMII_0_CNTRL]	= 0x34,
   1287	[REG_RGMII_1_CNTRL]	= 0x40,
   1288	[REG_RGMII_2_CNTRL]	= 0x4c,
   1289	[REG_LED_0_CNTRL]	= 0x90,
   1290	[REG_LED_1_CNTRL]	= 0x94,
   1291	[REG_LED_2_CNTRL]	= 0x98,
   1292};
   1293
   1294static const struct bcm_sf2_of_data bcm_sf2_7445_data = {
   1295	.type		= BCM7445_DEVICE_ID,
   1296	.core_reg_align	= 0,
   1297	.reg_offsets	= bcm_sf2_7445_reg_offsets,
   1298	.num_cfp_rules	= 256,
   1299};
   1300
   1301static const u16 bcm_sf2_7278_reg_offsets[] = {
   1302	[REG_SWITCH_CNTRL]	= 0x00,
   1303	[REG_SWITCH_STATUS]	= 0x04,
   1304	[REG_DIR_DATA_WRITE]	= 0x08,
   1305	[REG_DIR_DATA_READ]	= 0x0c,
   1306	[REG_SWITCH_REVISION]	= 0x10,
   1307	[REG_PHY_REVISION]	= 0x14,
   1308	[REG_SPHY_CNTRL]	= 0x24,
   1309	[REG_RGMII_0_CNTRL]	= 0xe0,
   1310	[REG_RGMII_1_CNTRL]	= 0xec,
   1311	[REG_RGMII_2_CNTRL]	= 0xf8,
   1312	[REG_LED_0_CNTRL]	= 0x40,
   1313	[REG_LED_1_CNTRL]	= 0x4c,
   1314	[REG_LED_2_CNTRL]	= 0x58,
   1315};
   1316
   1317static const struct bcm_sf2_of_data bcm_sf2_7278_data = {
   1318	.type		= BCM7278_DEVICE_ID,
   1319	.core_reg_align	= 1,
   1320	.reg_offsets	= bcm_sf2_7278_reg_offsets,
   1321	.num_cfp_rules	= 128,
   1322};
   1323
   1324static const struct of_device_id bcm_sf2_of_match[] = {
   1325	{ .compatible = "brcm,bcm4908-switch",
   1326	  .data = &bcm_sf2_4908_data
   1327	},
   1328	{ .compatible = "brcm,bcm7445-switch-v4.0",
   1329	  .data = &bcm_sf2_7445_data
   1330	},
   1331	{ .compatible = "brcm,bcm7278-switch-v4.0",
   1332	  .data = &bcm_sf2_7278_data
   1333	},
   1334	{ .compatible = "brcm,bcm7278-switch-v4.8",
   1335	  .data = &bcm_sf2_7278_data
   1336	},
   1337	{ /* sentinel */ },
   1338};
   1339MODULE_DEVICE_TABLE(of, bcm_sf2_of_match);
   1340
   1341static int bcm_sf2_sw_probe(struct platform_device *pdev)
   1342{
   1343	const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
   1344	struct device_node *dn = pdev->dev.of_node;
   1345	const struct of_device_id *of_id = NULL;
   1346	const struct bcm_sf2_of_data *data;
   1347	struct b53_platform_data *pdata;
   1348	struct dsa_switch_ops *ops;
   1349	struct device_node *ports;
   1350	struct bcm_sf2_priv *priv;
   1351	struct b53_device *dev;
   1352	struct dsa_switch *ds;
   1353	void __iomem **base;
   1354	unsigned int i;
   1355	u32 reg, rev;
   1356	int ret;
   1357
   1358	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
   1359	if (!priv)
   1360		return -ENOMEM;
   1361
   1362	ops = devm_kzalloc(&pdev->dev, sizeof(*ops), GFP_KERNEL);
   1363	if (!ops)
   1364		return -ENOMEM;
   1365
   1366	dev = b53_switch_alloc(&pdev->dev, &bcm_sf2_io_ops, priv);
   1367	if (!dev)
   1368		return -ENOMEM;
   1369
   1370	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
   1371	if (!pdata)
   1372		return -ENOMEM;
   1373
   1374	of_id = of_match_node(bcm_sf2_of_match, dn);
   1375	if (!of_id || !of_id->data)
   1376		return -EINVAL;
   1377
   1378	data = of_id->data;
   1379
   1380	/* Set SWITCH_REG register offsets and SWITCH_CORE align factor */
   1381	priv->type = data->type;
   1382	priv->reg_offsets = data->reg_offsets;
   1383	priv->core_reg_align = data->core_reg_align;
   1384	priv->num_cfp_rules = data->num_cfp_rules;
   1385	priv->num_crossbar_int_ports = data->num_crossbar_int_ports;
   1386
   1387	priv->rcdev = devm_reset_control_get_optional_exclusive(&pdev->dev,
   1388								"switch");
   1389	if (IS_ERR(priv->rcdev))
   1390		return PTR_ERR(priv->rcdev);
   1391
   1392	/* Auto-detection using standard registers will not work, so
   1393	 * provide an indication of what kind of device we are for
   1394	 * b53_common to work with
   1395	 */
   1396	pdata->chip_id = priv->type;
   1397	dev->pdata = pdata;
   1398
   1399	priv->dev = dev;
   1400	ds = dev->ds;
   1401	ds->ops = &bcm_sf2_ops;
   1402
   1403	/* Advertise the 8 egress queues */
   1404	ds->num_tx_queues = SF2_NUM_EGRESS_QUEUES;
   1405
   1406	dev_set_drvdata(&pdev->dev, priv);
   1407
   1408	spin_lock_init(&priv->indir_lock);
   1409	mutex_init(&priv->cfp.lock);
   1410	INIT_LIST_HEAD(&priv->cfp.rules_list);
   1411
   1412	/* CFP rule #0 cannot be used for specific classifications, flag it as
   1413	 * permanently used
   1414	 */
   1415	set_bit(0, priv->cfp.used);
   1416	set_bit(0, priv->cfp.unique);
   1417
   1418	/* Balance of_node_put() done by of_find_node_by_name() */
   1419	of_node_get(dn);
   1420	ports = of_find_node_by_name(dn, "ports");
   1421	if (ports) {
   1422		bcm_sf2_identify_ports(priv, ports);
   1423		of_node_put(ports);
   1424	}
   1425
   1426	priv->irq0 = irq_of_parse_and_map(dn, 0);
   1427	priv->irq1 = irq_of_parse_and_map(dn, 1);
   1428
   1429	base = &priv->core;
   1430	for (i = 0; i < BCM_SF2_REGS_NUM; i++) {
   1431		*base = devm_platform_ioremap_resource(pdev, i);
   1432		if (IS_ERR(*base)) {
   1433			pr_err("unable to find register: %s\n", reg_names[i]);
   1434			return PTR_ERR(*base);
   1435		}
   1436		base++;
   1437	}
   1438
   1439	priv->clk = devm_clk_get_optional(&pdev->dev, "sw_switch");
   1440	if (IS_ERR(priv->clk))
   1441		return PTR_ERR(priv->clk);
   1442
   1443	clk_prepare_enable(priv->clk);
   1444
   1445	priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv");
   1446	if (IS_ERR(priv->clk_mdiv)) {
   1447		ret = PTR_ERR(priv->clk_mdiv);
   1448		goto out_clk;
   1449	}
   1450
   1451	clk_prepare_enable(priv->clk_mdiv);
   1452
   1453	ret = bcm_sf2_sw_rst(priv);
   1454	if (ret) {
   1455		pr_err("unable to software reset switch: %d\n", ret);
   1456		goto out_clk_mdiv;
   1457	}
   1458
   1459	bcm_sf2_crossbar_setup(priv);
   1460
   1461	bcm_sf2_gphy_enable_set(priv->dev->ds, true);
   1462
   1463	ret = bcm_sf2_mdio_register(ds);
   1464	if (ret) {
   1465		pr_err("failed to register MDIO bus\n");
   1466		goto out_clk_mdiv;
   1467	}
   1468
   1469	bcm_sf2_gphy_enable_set(priv->dev->ds, false);
   1470
   1471	ret = bcm_sf2_cfp_rst(priv);
   1472	if (ret) {
   1473		pr_err("failed to reset CFP\n");
   1474		goto out_mdio;
   1475	}
   1476
   1477	/* Disable all interrupts and request them */
   1478	bcm_sf2_intr_disable(priv);
   1479
   1480	ret = devm_request_irq(&pdev->dev, priv->irq0, bcm_sf2_switch_0_isr, 0,
   1481			       "switch_0", ds);
   1482	if (ret < 0) {
   1483		pr_err("failed to request switch_0 IRQ\n");
   1484		goto out_mdio;
   1485	}
   1486
   1487	ret = devm_request_irq(&pdev->dev, priv->irq1, bcm_sf2_switch_1_isr, 0,
   1488			       "switch_1", ds);
   1489	if (ret < 0) {
   1490		pr_err("failed to request switch_1 IRQ\n");
   1491		goto out_mdio;
   1492	}
   1493
   1494	/* Reset the MIB counters */
   1495	reg = core_readl(priv, CORE_GMNCFGCFG);
   1496	reg |= RST_MIB_CNT;
   1497	core_writel(priv, reg, CORE_GMNCFGCFG);
   1498	reg &= ~RST_MIB_CNT;
   1499	core_writel(priv, reg, CORE_GMNCFGCFG);
   1500
   1501	/* Get the maximum number of ports for this switch */
   1502	priv->hw_params.num_ports = core_readl(priv, CORE_IMP0_PRT_ID) + 1;
   1503	if (priv->hw_params.num_ports > DSA_MAX_PORTS)
   1504		priv->hw_params.num_ports = DSA_MAX_PORTS;
   1505
   1506	/* Assume a single GPHY setup if we can't read that property */
   1507	if (of_property_read_u32(dn, "brcm,num-gphy",
   1508				 &priv->hw_params.num_gphy))
   1509		priv->hw_params.num_gphy = 1;
   1510
   1511	rev = reg_readl(priv, REG_SWITCH_REVISION);
   1512	priv->hw_params.top_rev = (rev >> SWITCH_TOP_REV_SHIFT) &
   1513					SWITCH_TOP_REV_MASK;
   1514	priv->hw_params.core_rev = (rev & SF2_REV_MASK);
   1515
   1516	rev = reg_readl(priv, REG_PHY_REVISION);
   1517	priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
   1518
   1519	ret = b53_switch_register(dev);
   1520	if (ret)
   1521		goto out_mdio;
   1522
   1523	dev_info(&pdev->dev,
   1524		 "Starfighter 2 top: %x.%02x, core: %x.%02x, IRQs: %d, %d\n",
   1525		 priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff,
   1526		 priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
   1527		 priv->irq0, priv->irq1);
   1528
   1529	return 0;
   1530
   1531out_mdio:
   1532	bcm_sf2_mdio_unregister(priv);
   1533out_clk_mdiv:
   1534	clk_disable_unprepare(priv->clk_mdiv);
   1535out_clk:
   1536	clk_disable_unprepare(priv->clk);
   1537	return ret;
   1538}
   1539
   1540static int bcm_sf2_sw_remove(struct platform_device *pdev)
   1541{
   1542	struct bcm_sf2_priv *priv = platform_get_drvdata(pdev);
   1543
   1544	if (!priv)
   1545		return 0;
   1546
   1547	priv->wol_ports_mask = 0;
   1548	/* Disable interrupts */
   1549	bcm_sf2_intr_disable(priv);
   1550	dsa_unregister_switch(priv->dev->ds);
   1551	bcm_sf2_cfp_exit(priv->dev->ds);
   1552	bcm_sf2_mdio_unregister(priv);
   1553	clk_disable_unprepare(priv->clk_mdiv);
   1554	clk_disable_unprepare(priv->clk);
   1555	if (priv->type == BCM7278_DEVICE_ID)
   1556		reset_control_assert(priv->rcdev);
   1557
   1558	platform_set_drvdata(pdev, NULL);
   1559
   1560	return 0;
   1561}
   1562
   1563static void bcm_sf2_sw_shutdown(struct platform_device *pdev)
   1564{
   1565	struct bcm_sf2_priv *priv = platform_get_drvdata(pdev);
   1566
   1567	if (!priv)
   1568		return;
   1569
   1570	/* For a kernel about to be kexec'd we want to keep the GPHY on for a
   1571	 * successful MDIO bus scan to occur. If we did turn off the GPHY
   1572	 * before (e.g: port_disable), this will also power it back on.
   1573	 *
   1574	 * Do not rely on kexec_in_progress, just power the PHY on.
   1575	 */
   1576	if (priv->hw_params.num_gphy == 1)
   1577		bcm_sf2_gphy_enable_set(priv->dev->ds, true);
   1578
   1579	dsa_switch_shutdown(priv->dev->ds);
   1580
   1581	platform_set_drvdata(pdev, NULL);
   1582}
   1583
   1584#ifdef CONFIG_PM_SLEEP
   1585static int bcm_sf2_suspend(struct device *dev)
   1586{
   1587	struct bcm_sf2_priv *priv = dev_get_drvdata(dev);
   1588
   1589	return dsa_switch_suspend(priv->dev->ds);
   1590}
   1591
   1592static int bcm_sf2_resume(struct device *dev)
   1593{
   1594	struct bcm_sf2_priv *priv = dev_get_drvdata(dev);
   1595
   1596	return dsa_switch_resume(priv->dev->ds);
   1597}
   1598#endif /* CONFIG_PM_SLEEP */
   1599
   1600static SIMPLE_DEV_PM_OPS(bcm_sf2_pm_ops,
   1601			 bcm_sf2_suspend, bcm_sf2_resume);
   1602
   1603
   1604static struct platform_driver bcm_sf2_driver = {
   1605	.probe	= bcm_sf2_sw_probe,
   1606	.remove	= bcm_sf2_sw_remove,
   1607	.shutdown = bcm_sf2_sw_shutdown,
   1608	.driver = {
   1609		.name = "brcm-sf2",
   1610		.of_match_table = bcm_sf2_of_match,
   1611		.pm = &bcm_sf2_pm_ops,
   1612	},
   1613};
   1614module_platform_driver(bcm_sf2_driver);
   1615
   1616MODULE_AUTHOR("Broadcom Corporation");
   1617MODULE_DESCRIPTION("Driver for Broadcom Starfighter 2 ethernet switch chip");
   1618MODULE_LICENSE("GPL");
   1619MODULE_ALIAS("platform:brcm-sf2");