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

Commit 0982a0f6 authored by Giuseppe CAVALLARO's avatar Giuseppe CAVALLARO Committed by David S. Miller
Browse files

stmmac: start adding pcs and rgmii core irq



This patch starts adding in the main ISR the management of the PCS and
RGMII/SGMII core interrupts. This is to help further development
on this area. Currently the core irq handler only clears the
PCS and S-R_MII interrupts and reports the event in the ethtool stats.

Signed-off-by: default avatarGiuseppe Cavallaro <peppe.cavallaro@st.com>
Tested-by: default avatarByungho An <bh74.an@samsung.com>
Cc: Udit Kumar <udit-dlh.kumar@st.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c24602ef
Loading
Loading
Loading
Loading
+14 −11
Original line number Diff line number Diff line
@@ -140,6 +140,10 @@ struct stmmac_extra_stats {
	unsigned long l3_filter_match;
	unsigned long l4_filter_match;
	unsigned long l3_l4_filter_no_match;
	/* PCS */
	unsigned long irq_pcs_ane_n;
	unsigned long irq_pcs_link_n;
	unsigned long irq_rgmii_n;
};

/* CSR Frequency Access Defines*/
@@ -217,16 +221,14 @@ enum dma_irq_status {
	handle_tx = 0x8,
};

enum core_specific_irq_mask {
	core_mmc_tx_irq = 1,
	core_mmc_rx_irq = 2,
	core_mmc_rx_csum_offload_irq = 4,
	core_irq_receive_pmt_irq = 8,
	core_irq_tx_path_in_lpi_mode = 16,
	core_irq_tx_path_exit_lpi_mode = 32,
	core_irq_rx_path_in_lpi_mode = 64,
	core_irq_rx_path_exit_lpi_mode = 128,
};
#define	CORE_IRQ_TX_PATH_IN_LPI_MODE	(1 << 1)
#define	CORE_IRQ_TX_PATH_EXIT_LPI_MODE	(1 << 2)
#define	CORE_IRQ_RX_PATH_IN_LPI_MODE	(1 << 3)
#define	CORE_IRQ_RX_PATH_EXIT_LPI_MODE	(1 << 4)

#define	CORE_PCS_ANE_COMPLETE		(1 << 5)
#define	CORE_PCS_LINK_STATUS		(1 << 6)
#define	CORE_RGMII_IRQ			(1 << 7)

/* DMA HW capabilities */
struct dma_features {
@@ -355,7 +357,8 @@ struct stmmac_ops {
	/* Dump MAC registers */
	void (*dump_regs) (void __iomem *ioaddr);
	/* Handle extra events on specific interrupts hw dependent */
	int (*host_irq_status) (void __iomem *ioaddr);
	int (*host_irq_status) (void __iomem *ioaddr,
				struct stmmac_extra_stats *x);
	/* Multicast filter setting */
	void (*set_filter) (struct net_device *dev, int id);
	/* Flow control setting */
+3 −2
Original line number Diff line number Diff line
@@ -89,13 +89,14 @@ enum power_event {
				(reg * 8))
#define GMAC_MAX_PERFECT_ADDRESSES	32

/* PCS registers (AN/TBI/SGMII/RGMII) offset */
#define GMAC_AN_CTRL	0x000000c0	/* AN control */
#define GMAC_AN_STATUS	0x000000c4	/* AN status */
#define GMAC_ANE_ADV	0x000000c8	/* Auto-Neg. Advertisement */
#define GMAC_ANE_LINK	0x000000cc	/* Auto-Neg. link partener ability */
#define GMAC_ANE_LPA	0x000000cc	/* Auto-Neg. link partener ability */
#define GMAC_ANE_EXP	0x000000d0	/* ANE expansion */
#define GMAC_TBI	0x000000d4	/* TBI extend status */
#define GMAC_GMII_STATUS 0x000000d8	/* S/R-GMII status */
#define GMAC_S_R_GMII	0x000000d8	/* SGMII RGMII status */

/* GMAC Configuration defines */
#define GMAC_CONTROL_TC	0x01000000	/* Transmit Conf. in RGMII/SGMII */
+28 −16
Original line number Diff line number Diff line
@@ -194,58 +194,70 @@ static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
}


static int dwmac1000_irq_status(void __iomem *ioaddr)
static int dwmac1000_irq_status(void __iomem *ioaddr,
				struct stmmac_extra_stats *x)
{
	u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
	int status = 0;
	int ret = 0;

	/* Not used events (e.g. MMC interrupts) are not handled. */
	if ((intr_status & mmc_tx_irq)) {
		CHIP_DBG(KERN_INFO "GMAC: MMC tx interrupt: 0x%08x\n",
		    readl(ioaddr + GMAC_MMC_TX_INTR));
		status |= core_mmc_tx_irq;
		x->mmc_tx_irq_n++;
	}
	if (unlikely(intr_status & mmc_rx_irq)) {
		CHIP_DBG(KERN_INFO "GMAC: MMC rx interrupt: 0x%08x\n",
		    readl(ioaddr + GMAC_MMC_RX_INTR));
		status |= core_mmc_rx_irq;
		x->mmc_rx_irq_n++;
	}
	if (unlikely(intr_status & mmc_rx_csum_offload_irq)) {
		CHIP_DBG(KERN_INFO "GMAC: MMC rx csum offload: 0x%08x\n",
		    readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
		status |= core_mmc_rx_csum_offload_irq;
		x->mmc_rx_csum_offload_irq_n++;
	}
	if (unlikely(intr_status & pmt_irq)) {
		CHIP_DBG(KERN_INFO "GMAC: received Magic frame\n");
		/* clear the PMT bits 5 and 6 by reading the PMT
		 * status register. */
		readl(ioaddr + GMAC_PMT);
		status |= core_irq_receive_pmt_irq;
		x->irq_receive_pmt_irq_n++;
	}
	/* MAC trx/rx EEE LPI entry/exit interrupts */
	if (intr_status & lpiis_irq) {
		/* Clean LPI interrupt by reading the Reg 12 */
		u32 lpi_status = readl(ioaddr + LPI_CTRL_STATUS);
		ret = readl(ioaddr + LPI_CTRL_STATUS);

		if (lpi_status & LPI_CTRL_STATUS_TLPIEN) {
		if (ret & LPI_CTRL_STATUS_TLPIEN) {
			CHIP_DBG(KERN_INFO "GMAC TX entered in LPI\n");
			status |= core_irq_tx_path_in_lpi_mode;
			x->irq_tx_path_in_lpi_mode_n++;
		}
		if (lpi_status & LPI_CTRL_STATUS_TLPIEX) {
		if (ret & LPI_CTRL_STATUS_TLPIEX) {
			CHIP_DBG(KERN_INFO "GMAC TX exit from LPI\n");
			status |= core_irq_tx_path_exit_lpi_mode;
			x->irq_tx_path_exit_lpi_mode_n++;
		}
		if (lpi_status & LPI_CTRL_STATUS_RLPIEN) {
		if (ret & LPI_CTRL_STATUS_RLPIEN) {
			CHIP_DBG(KERN_INFO "GMAC RX entered in LPI\n");
			status |= core_irq_rx_path_in_lpi_mode;
			x->irq_rx_path_in_lpi_mode_n++;
		}
		if (lpi_status & LPI_CTRL_STATUS_RLPIEX) {
		if (ret & LPI_CTRL_STATUS_RLPIEX) {
			CHIP_DBG(KERN_INFO "GMAC RX exit from LPI\n");
			status |= core_irq_rx_path_exit_lpi_mode;
			x->irq_rx_path_exit_lpi_mode_n++;
		}
	}

	return status;
	if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
		CHIP_DBG(KERN_INFO "GMAC PCS ANE IRQ\n");
		readl(ioaddr + GMAC_AN_STATUS);
		x->irq_pcs_ane_n++;
	}
	if (intr_status & rgmii_irq) {
		CHIP_DBG(KERN_INFO "GMAC RGMII IRQ status\n");
		readl(ioaddr + GMAC_S_R_GMII);
		x->irq_rgmii_n++;
	}

	return ret;
}

static void  dwmac1000_set_eee_mode(void __iomem *ioaddr)
+2 −1
Original line number Diff line number Diff line
@@ -72,7 +72,8 @@ static int dwmac100_rx_ipc_enable(void __iomem *ioaddr)
	return 0;
}

static int dwmac100_irq_status(void __iomem *ioaddr)
static int dwmac100_irq_status(void __iomem *ioaddr,
			       struct stmmac_extra_stats *x)
{
	return 0;
}
+4 −0
Original line number Diff line number Diff line
@@ -131,6 +131,10 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
	STMMAC_STAT(l3_filter_match),
	STMMAC_STAT(l4_filter_match),
	STMMAC_STAT(l3_l4_filter_no_match),
	/* PCS */
	STMMAC_STAT(irq_pcs_ane_n),
	STMMAC_STAT(irq_pcs_link_n),
	STMMAC_STAT(irq_rgmii_n),
};
#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)

Loading