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

Commit e8c1d713 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: stmmac: Add support for Micrel PHY interrupt"

parents 24df3529 2b4accc6
Loading
Loading
Loading
Loading
+51 −9
Original line number Original line Diff line number Diff line
@@ -17,7 +17,7 @@
#include <linux/debugfs.h>
#include <linux/debugfs.h>
#include <asm/dma-iommu.h>
#include <asm/dma-iommu.h>
#include <linux/iommu.h>
#include <linux/iommu.h>

#include <linux/micrel_phy.h>


#include "stmmac.h"
#include "stmmac.h"
#include "stmmac_platform.h"
#include "stmmac_platform.h"
@@ -100,6 +100,15 @@
#define LINK_DOWN_STATE 0x800
#define LINK_DOWN_STATE 0x800
#define LINK_UP_STATE 0x400
#define LINK_UP_STATE 0x400


#define MICREL_PHY_ID PHY_ID_KSZ9031
#define DWC_ETH_QOS_MICREL_PHY_INTCS 0x1b
#define DWC_ETH_QOS_MICREL_PHY_CTL 0x1f
#define DWC_ETH_QOS_MICREL_INTR_LEVEL 0x4000
#define DWC_ETH_QOS_BASIC_STATUS     0x0001
#define LINK_STATE_MASK 0x4
#define AUTONEG_STATE_MASK 0x20
#define MICREL_LINK_UP_INTR_STATUS BIT(0)

bool phy_intr_en;
bool phy_intr_en;


struct qcom_ethqos *pethqos;
struct qcom_ethqos *pethqos;
@@ -546,15 +555,48 @@ static void ethqos_handle_phy_interrupt(struct qcom_ethqos *ethqos)


	struct net_device *dev = platform_get_drvdata(pdev);
	struct net_device *dev = platform_get_drvdata(pdev);
	struct stmmac_priv *priv = netdev_priv(dev);
	struct stmmac_priv *priv = netdev_priv(dev);

	int micrel_intr_status = 0;
	phy_intr_status = ethqos_mdio_read(priv, priv->plat->phy_addr,

					   DWC_ETH_QOS_PHY_INTR_STATUS);
	if ((dev->phydev->phy_id & dev->phydev->drv->phy_id_mask)
		== MICREL_PHY_ID) {
		phy_intr_status = ethqos_mdio_read(
			priv, priv->plat->phy_addr, DWC_ETH_QOS_BASIC_STATUS);
		ETHQOSDBG(
			"Basic Status Reg (%#x) = %#x\n",
			DWC_ETH_QOS_BASIC_STATUS, phy_intr_status);
		micrel_intr_status = ethqos_mdio_read(
			priv, priv->plat->phy_addr,
			DWC_ETH_QOS_MICREL_PHY_INTCS);
		ETHQOSDBG(
			"MICREL PHY Intr EN Reg (%#x) = %#x\n",
			DWC_ETH_QOS_MICREL_PHY_INTCS, micrel_intr_status);

		/* Call ack interrupt to clear the WOL status fields */
		if (dev->phydev->drv->ack_interrupt)
			dev->phydev->drv->ack_interrupt(dev->phydev);

		/* Interrupt received for link state change */
		if (phy_intr_status & LINK_STATE_MASK) {
			if (micrel_intr_status & MICREL_LINK_UP_INTR_STATUS)
				ETHQOSDBG("Intr for link UP state\n");
			phy_mac_interrupt(dev->phydev, LINK_UP);
		} else if (!(phy_intr_status & LINK_STATE_MASK)) {
			ETHQOSDBG("Intr for link DOWN state\n");
			phy_mac_interrupt(dev->phydev, LINK_DOWN);
		} else if (!(phy_intr_status & AUTONEG_STATE_MASK)) {
			ETHQOSDBG("Intr for link down with auto-neg err\n");
		}
	} else {
		phy_intr_status =
		 ethqos_mdio_read(
		    priv, priv->plat->phy_addr, DWC_ETH_QOS_PHY_INTR_STATUS);


		if (phy_intr_status & LINK_UP_STATE)
		if (phy_intr_status & LINK_UP_STATE)
			phy_mac_interrupt(dev->phydev, LINK_UP);
			phy_mac_interrupt(dev->phydev, LINK_UP);
		else if (phy_intr_status & LINK_DOWN_STATE)
		else if (phy_intr_status & LINK_DOWN_STATE)
			phy_mac_interrupt(dev->phydev, LINK_DOWN);
			phy_mac_interrupt(dev->phydev, LINK_DOWN);
	}
	}
}


static void ethqos_defer_phy_isr_work(struct work_struct *work)
static void ethqos_defer_phy_isr_work(struct work_struct *work)
{
{