stmmac: start adding pcs and rgmii core irq
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>
Tue, 26 Mar 2013 04:43:07 +0000 (04:43 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 26 Mar 2013 16:53:36 +0000 (12:53 -0400)
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: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Tested-by: Byungho An <bh74.an@samsung.com>
Cc: Udit Kumar <udit-dlh.kumar@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index 8a04b7f23389a208714ec95d42ecde6e6c45b9ff..479f47914035598ebd06f67551cad92707d9dbb9 100644 (file)
@@ -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 */
index 85466e5a70b77ab3da76569ab11a764099bfca56..6dd689e19f0ad48c9b0b1a7148fee4d80a8f347b 100644 (file)
@@ -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 */
index bfe02260549840c17a047670ddf47a28c1ddecf5..ff4c79e690f1aa6c02c17856b13b8c09a3e72ba6 100644 (file)
@@ -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)
index f83210e7c221f22f774127e98d8695452c31086b..cb86a58c1c5f7cf60db4a428dad01b10ee88b024 100644 (file)
@@ -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;
 }
index f6ad751925e8a8040911d4f625ddba72aba10de1..1793628570961ec9befd5583081cc1a601b15f14 100644 (file)
@@ -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)
 
index 96fbf86366a9585ae210d6dc2f72457c9df87138..ca3e95a4b16fa37ea5ef625b860d688fea43f263 100644 (file)
@@ -1780,30 +1780,14 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
        /* To handle GMAC own interrupts */
        if (priv->plat->has_gmac) {
                int status = priv->hw->mac->host_irq_status((void __iomem *)
-                                                           dev->base_addr);
+                                                           dev->base_addr,
+                                                           &priv->xstats);
                if (unlikely(status)) {
-                       if (status & core_mmc_tx_irq)
-                               priv->xstats.mmc_tx_irq_n++;
-                       if (status & core_mmc_rx_irq)
-                               priv->xstats.mmc_rx_irq_n++;
-                       if (status & core_mmc_rx_csum_offload_irq)
-                               priv->xstats.mmc_rx_csum_offload_irq_n++;
-                       if (status & core_irq_receive_pmt_irq)
-                               priv->xstats.irq_receive_pmt_irq_n++;
-
                        /* For LPI we need to save the tx status */
-                       if (status & core_irq_tx_path_in_lpi_mode) {
-                               priv->xstats.irq_tx_path_in_lpi_mode_n++;
+                       if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE)
                                priv->tx_path_in_lpi_mode = true;
-                       }
-                       if (status & core_irq_tx_path_exit_lpi_mode) {
-                               priv->xstats.irq_tx_path_exit_lpi_mode_n++;
+                       if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE)
                                priv->tx_path_in_lpi_mode = false;
-                       }
-                       if (status & core_irq_rx_path_in_lpi_mode)
-                               priv->xstats.irq_rx_path_in_lpi_mode_n++;
-                       if (status & core_irq_rx_path_exit_lpi_mode)
-                               priv->xstats.irq_rx_path_exit_lpi_mode_n++;
                }
        }