Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08ef55c6 authored by John Crispin's avatar John Crispin Committed by David S. Miller
Browse files

net-next: mediatek: fix gigabit and flow control advertisement



The current code will not setup the PHYs advertisement features correctly.
Fix this and properly advertise Gigabit features and properly handle
asymmetric pause frames.

Signed-off-by: default avatarSean Wang <keyhaede@gmail.com>
Signed-off-by: default avatarJohn Crispin <john@phrozen.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 207bdf18
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -133,6 +133,8 @@ static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
static void mtk_phy_link_adjust(struct net_device *dev)
{
	struct mtk_mac *mac = netdev_priv(dev);
	u16 lcl_adv = 0, rmt_adv = 0;
	u8 flowctrl;
	u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG |
		  MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN |
		  MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN |
@@ -150,11 +152,30 @@ static void mtk_phy_link_adjust(struct net_device *dev)
	if (mac->phy_dev->link)
		mcr |= MAC_MCR_FORCE_LINK;

	if (mac->phy_dev->duplex)
	if (mac->phy_dev->duplex) {
		mcr |= MAC_MCR_FORCE_DPX;

		if (mac->phy_dev->pause)
		mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
			rmt_adv = LPA_PAUSE_CAP;
		if (mac->phy_dev->asym_pause)
			rmt_adv |= LPA_PAUSE_ASYM;

		if (mac->phy_dev->advertising & ADVERTISED_Pause)
			lcl_adv |= ADVERTISE_PAUSE_CAP;
		if (mac->phy_dev->advertising & ADVERTISED_Asym_Pause)
			lcl_adv |= ADVERTISE_PAUSE_ASYM;

		flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);

		if (flowctrl & FLOW_CTRL_TX)
			mcr |= MAC_MCR_FORCE_TX_FC;
		if (flowctrl & FLOW_CTRL_RX)
			mcr |= MAC_MCR_FORCE_RX_FC;

		netif_dbg(mac->hw, link, dev, "rx pause %s, tx pause %s\n",
			  flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
			  flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
	}

	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));

@@ -236,7 +257,8 @@ static int mtk_phy_connect(struct mtk_mac *mac)
	mac->phy_dev->autoneg = AUTONEG_ENABLE;
	mac->phy_dev->speed = 0;
	mac->phy_dev->duplex = 0;
	mac->phy_dev->supported &= PHY_BASIC_FEATURES;
	mac->phy_dev->supported &= PHY_GBIT_FEATURES | SUPPORTED_Pause |
				   SUPPORTED_Asym_Pause;
	mac->phy_dev->advertising = mac->phy_dev->supported |
				    ADVERTISED_Autoneg;
	phy_start_aneg(mac->phy_dev);