Commit a0cb1aa4 authored by Arun Ramadoss's avatar Arun Ramadoss Committed by David S. Miller
Browse files

net: dsa: microchip: lan937x: add phylink_mac_config support



This patch add support for phylink_mac_config dsa hook. It configures
the mac for MII/RMII modes. The RGMII mode will be added in the future
patches.

Signed-off-by: default avatarArun Ramadoss <arun.ramadoss@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f597d3ad
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ static const struct ksz_dev_ops lan937x_dev_ops = {
	.mirror_add = ksz9477_port_mirror_add,
	.mirror_del = ksz9477_port_mirror_del,
	.get_caps = lan937x_phylink_get_caps,
	.phylink_mac_config = lan937x_phylink_mac_config,
	.phylink_mac_link_up = lan937x_phylink_mac_link_up,
	.fdb_dump = ksz9477_fdb_dump,
	.fdb_add = ksz9477_fdb_add,
@@ -1341,6 +1342,16 @@ static int ksz_max_mtu(struct dsa_switch *ds, int port)
	return dev->dev_ops->max_mtu(dev, port);
}

static void ksz_phylink_mac_config(struct dsa_switch *ds, int port,
				   unsigned int mode,
				   const struct phylink_link_state *state)
{
	struct ksz_device *dev = ds->priv;

	if (dev->dev_ops->phylink_mac_config)
		dev->dev_ops->phylink_mac_config(dev, port, mode, state);
}

static void ksz_phylink_mac_link_up(struct dsa_switch *ds, int port,
				    unsigned int mode,
				    phy_interface_t interface,
@@ -1428,6 +1439,7 @@ static const struct dsa_switch_ops ksz_switch_ops = {
	.phy_read		= ksz_phy_read16,
	.phy_write		= ksz_phy_write16,
	.phylink_get_caps	= ksz_phylink_get_caps,
	.phylink_mac_config	= ksz_phylink_mac_config,
	.phylink_mac_link_up	= ksz_phylink_mac_link_up,
	.phylink_mac_link_down	= ksz_mac_link_down,
	.port_enable		= ksz_enable_port,
+3 −0
Original line number Diff line number Diff line
@@ -271,6 +271,9 @@ struct ksz_dev_ops {
	int (*max_mtu)(struct ksz_device *dev, int port);
	void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze);
	void (*port_init_cnt)(struct ksz_device *dev, int port);
	void (*phylink_mac_config)(struct ksz_device *dev, int port,
				   unsigned int mode,
				   const struct phylink_link_state *state);
	void (*phylink_mac_link_up)(struct ksz_device *dev, int port,
				    unsigned int mode,
				    phy_interface_t interface,
+3 −0
Original line number Diff line number Diff line
@@ -21,4 +21,7 @@ void lan937x_phylink_mac_link_up(struct ksz_device *dev, int port,
				 unsigned int mode, phy_interface_t interface,
				 struct phy_device *phydev, int speed,
				 int duplex, bool tx_pause, bool rx_pause);
void lan937x_phylink_mac_config(struct ksz_device *dev, int port,
				unsigned int mode,
				const struct phylink_link_state *state);
#endif
+56 −2
Original line number Diff line number Diff line
@@ -312,6 +312,44 @@ int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu)
	return 0;
}

static void lan937x_config_gbit(struct ksz_device *dev, bool gbit, u8 *data)
{
	if (gbit)
		*data &= ~PORT_MII_NOT_1GBIT;
	else
		*data |= PORT_MII_NOT_1GBIT;
}

static void lan937x_mac_config(struct ksz_device *dev, int port,
			       phy_interface_t interface)
{
	u8 data8;

	ksz_pread8(dev, port, REG_PORT_XMII_CTRL_1, &data8);

	/* clear MII selection & set it based on interface later */
	data8 &= ~PORT_MII_SEL_M;

	/* configure MAC based on interface */
	switch (interface) {
	case PHY_INTERFACE_MODE_MII:
		lan937x_config_gbit(dev, false, &data8);
		data8 |= PORT_MII_SEL;
		break;
	case PHY_INTERFACE_MODE_RMII:
		lan937x_config_gbit(dev, false, &data8);
		data8 |= PORT_RMII_SEL;
		break;
	default:
		dev_err(dev->dev, "Unsupported interface '%s' for port %d\n",
			phy_modes(interface), port);
		return;
	}

	/* Write the updated value */
	ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8);
}

static void lan937x_config_interface(struct ksz_device *dev, int port,
				     int speed, int duplex,
				     bool tx_pause, bool rx_pause)
@@ -325,9 +363,9 @@ static void lan937x_config_interface(struct ksz_device *dev, int port,
			PORT_MII_TX_FLOW_CTRL | PORT_MII_RX_FLOW_CTRL);

	if (speed == SPEED_1000)
		xmii_ctrl1 &= ~PORT_MII_NOT_1GBIT;
		lan937x_config_gbit(dev, true, &xmii_ctrl1);
	else
		xmii_ctrl1 |= PORT_MII_NOT_1GBIT;
		lan937x_config_gbit(dev, false, &xmii_ctrl1);

	if (speed == SPEED_100)
		xmii_ctrl0 |= PORT_MII_100MBIT;
@@ -370,6 +408,22 @@ void lan937x_phylink_mac_link_up(struct ksz_device *dev, int port,
				 tx_pause, rx_pause);
}

void lan937x_phylink_mac_config(struct ksz_device *dev, int port,
				unsigned int mode,
				const struct phylink_link_state *state)
{
	/* Internal PHYs */
	if (dev->info->internal_phy[port])
		return;

	if (phylink_autoneg_inband(mode)) {
		dev_err(dev->dev, "In-band AN not supported!\n");
		return;
	}

	lan937x_mac_config(dev, port, state->interface);
}

int lan937x_setup(struct dsa_switch *ds)
{
	struct ksz_device *dev = ds->priv;