aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/stmicro
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2013-03-26 00:43:07 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-26 12:53:36 -0400
commit0982a0f6d1be5f03ba62ed1f3deb92e8376b1e43 (patch)
tree12c9d08551c6e6a0efcf4ffd17eeca31ad637d01 /drivers/net/ethernet/stmicro
parentc24602ef86649376e9d71ea808cd877e414d340b (diff)
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: 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>
Diffstat (limited to 'drivers/net/ethernet/stmicro')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h25
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000.h5
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c44
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c4
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c24
6 files changed, 55 insertions, 50 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 8a04b7f23389..479f47914035 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -140,6 +140,10 @@ struct stmmac_extra_stats {
140 unsigned long l3_filter_match; 140 unsigned long l3_filter_match;
141 unsigned long l4_filter_match; 141 unsigned long l4_filter_match;
142 unsigned long l3_l4_filter_no_match; 142 unsigned long l3_l4_filter_no_match;
143 /* PCS */
144 unsigned long irq_pcs_ane_n;
145 unsigned long irq_pcs_link_n;
146 unsigned long irq_rgmii_n;
143}; 147};
144 148
145/* CSR Frequency Access Defines*/ 149/* CSR Frequency Access Defines*/
@@ -217,16 +221,14 @@ enum dma_irq_status {
217 handle_tx = 0x8, 221 handle_tx = 0x8,
218}; 222};
219 223
220enum core_specific_irq_mask { 224#define CORE_IRQ_TX_PATH_IN_LPI_MODE (1 << 1)
221 core_mmc_tx_irq = 1, 225#define CORE_IRQ_TX_PATH_EXIT_LPI_MODE (1 << 2)
222 core_mmc_rx_irq = 2, 226#define CORE_IRQ_RX_PATH_IN_LPI_MODE (1 << 3)
223 core_mmc_rx_csum_offload_irq = 4, 227#define CORE_IRQ_RX_PATH_EXIT_LPI_MODE (1 << 4)
224 core_irq_receive_pmt_irq = 8, 228
225 core_irq_tx_path_in_lpi_mode = 16, 229#define CORE_PCS_ANE_COMPLETE (1 << 5)
226 core_irq_tx_path_exit_lpi_mode = 32, 230#define CORE_PCS_LINK_STATUS (1 << 6)
227 core_irq_rx_path_in_lpi_mode = 64, 231#define CORE_RGMII_IRQ (1 << 7)
228 core_irq_rx_path_exit_lpi_mode = 128,
229};
230 232
231/* DMA HW capabilities */ 233/* DMA HW capabilities */
232struct dma_features { 234struct dma_features {
@@ -355,7 +357,8 @@ struct stmmac_ops {
355 /* Dump MAC registers */ 357 /* Dump MAC registers */
356 void (*dump_regs) (void __iomem *ioaddr); 358 void (*dump_regs) (void __iomem *ioaddr);
357 /* Handle extra events on specific interrupts hw dependent */ 359 /* Handle extra events on specific interrupts hw dependent */
358 int (*host_irq_status) (void __iomem *ioaddr); 360 int (*host_irq_status) (void __iomem *ioaddr,
361 struct stmmac_extra_stats *x);
359 /* Multicast filter setting */ 362 /* Multicast filter setting */
360 void (*set_filter) (struct net_device *dev, int id); 363 void (*set_filter) (struct net_device *dev, int id);
361 /* Flow control setting */ 364 /* Flow control setting */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 85466e5a70b7..6dd689e19f0a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -89,13 +89,14 @@ enum power_event {
89 (reg * 8)) 89 (reg * 8))
90#define GMAC_MAX_PERFECT_ADDRESSES 32 90#define GMAC_MAX_PERFECT_ADDRESSES 32
91 91
92/* PCS registers (AN/TBI/SGMII/RGMII) offset */
92#define GMAC_AN_CTRL 0x000000c0 /* AN control */ 93#define GMAC_AN_CTRL 0x000000c0 /* AN control */
93#define GMAC_AN_STATUS 0x000000c4 /* AN status */ 94#define GMAC_AN_STATUS 0x000000c4 /* AN status */
94#define GMAC_ANE_ADV 0x000000c8 /* Auto-Neg. Advertisement */ 95#define GMAC_ANE_ADV 0x000000c8 /* Auto-Neg. Advertisement */
95#define GMAC_ANE_LINK 0x000000cc /* Auto-Neg. link partener ability */ 96#define GMAC_ANE_LPA 0x000000cc /* Auto-Neg. link partener ability */
96#define GMAC_ANE_EXP 0x000000d0 /* ANE expansion */ 97#define GMAC_ANE_EXP 0x000000d0 /* ANE expansion */
97#define GMAC_TBI 0x000000d4 /* TBI extend status */ 98#define GMAC_TBI 0x000000d4 /* TBI extend status */
98#define GMAC_GMII_STATUS 0x000000d8 /* S/R-GMII status */ 99#define GMAC_S_R_GMII 0x000000d8 /* SGMII RGMII status */
99 100
100/* GMAC Configuration defines */ 101/* GMAC Configuration defines */
101#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */ 102#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index bfe022605498..ff4c79e690f1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -194,58 +194,70 @@ static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
194} 194}
195 195
196 196
197static int dwmac1000_irq_status(void __iomem *ioaddr) 197static int dwmac1000_irq_status(void __iomem *ioaddr,
198 struct stmmac_extra_stats *x)
198{ 199{
199 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS); 200 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
200 int status = 0; 201 int ret = 0;
201 202
202 /* Not used events (e.g. MMC interrupts) are not handled. */ 203 /* Not used events (e.g. MMC interrupts) are not handled. */
203 if ((intr_status & mmc_tx_irq)) { 204 if ((intr_status & mmc_tx_irq)) {
204 CHIP_DBG(KERN_INFO "GMAC: MMC tx interrupt: 0x%08x\n", 205 CHIP_DBG(KERN_INFO "GMAC: MMC tx interrupt: 0x%08x\n",
205 readl(ioaddr + GMAC_MMC_TX_INTR)); 206 readl(ioaddr + GMAC_MMC_TX_INTR));
206 status |= core_mmc_tx_irq; 207 x->mmc_tx_irq_n++;
207 } 208 }
208 if (unlikely(intr_status & mmc_rx_irq)) { 209 if (unlikely(intr_status & mmc_rx_irq)) {
209 CHIP_DBG(KERN_INFO "GMAC: MMC rx interrupt: 0x%08x\n", 210 CHIP_DBG(KERN_INFO "GMAC: MMC rx interrupt: 0x%08x\n",
210 readl(ioaddr + GMAC_MMC_RX_INTR)); 211 readl(ioaddr + GMAC_MMC_RX_INTR));
211 status |= core_mmc_rx_irq; 212 x->mmc_rx_irq_n++;
212 } 213 }
213 if (unlikely(intr_status & mmc_rx_csum_offload_irq)) { 214 if (unlikely(intr_status & mmc_rx_csum_offload_irq)) {
214 CHIP_DBG(KERN_INFO "GMAC: MMC rx csum offload: 0x%08x\n", 215 CHIP_DBG(KERN_INFO "GMAC: MMC rx csum offload: 0x%08x\n",
215 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD)); 216 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
216 status |= core_mmc_rx_csum_offload_irq; 217 x->mmc_rx_csum_offload_irq_n++;
217 } 218 }
218 if (unlikely(intr_status & pmt_irq)) { 219 if (unlikely(intr_status & pmt_irq)) {
219 CHIP_DBG(KERN_INFO "GMAC: received Magic frame\n"); 220 CHIP_DBG(KERN_INFO "GMAC: received Magic frame\n");
220 /* clear the PMT bits 5 and 6 by reading the PMT 221 /* clear the PMT bits 5 and 6 by reading the PMT
221 * status register. */ 222 * status register. */
222 readl(ioaddr + GMAC_PMT); 223 readl(ioaddr + GMAC_PMT);
223 status |= core_irq_receive_pmt_irq; 224 x->irq_receive_pmt_irq_n++;
224 } 225 }
225 /* MAC trx/rx EEE LPI entry/exit interrupts */ 226 /* MAC trx/rx EEE LPI entry/exit interrupts */
226 if (intr_status & lpiis_irq) { 227 if (intr_status & lpiis_irq) {
227 /* Clean LPI interrupt by reading the Reg 12 */ 228 /* Clean LPI interrupt by reading the Reg 12 */
228 u32 lpi_status = readl(ioaddr + LPI_CTRL_STATUS); 229 ret = readl(ioaddr + LPI_CTRL_STATUS);
229 230
230 if (lpi_status & LPI_CTRL_STATUS_TLPIEN) { 231 if (ret & LPI_CTRL_STATUS_TLPIEN) {
231 CHIP_DBG(KERN_INFO "GMAC TX entered in LPI\n"); 232 CHIP_DBG(KERN_INFO "GMAC TX entered in LPI\n");
232 status |= core_irq_tx_path_in_lpi_mode; 233 x->irq_tx_path_in_lpi_mode_n++;
233 } 234 }
234 if (lpi_status & LPI_CTRL_STATUS_TLPIEX) { 235 if (ret & LPI_CTRL_STATUS_TLPIEX) {
235 CHIP_DBG(KERN_INFO "GMAC TX exit from LPI\n"); 236 CHIP_DBG(KERN_INFO "GMAC TX exit from LPI\n");
236 status |= core_irq_tx_path_exit_lpi_mode; 237 x->irq_tx_path_exit_lpi_mode_n++;
237 } 238 }
238 if (lpi_status & LPI_CTRL_STATUS_RLPIEN) { 239 if (ret & LPI_CTRL_STATUS_RLPIEN) {
239 CHIP_DBG(KERN_INFO "GMAC RX entered in LPI\n"); 240 CHIP_DBG(KERN_INFO "GMAC RX entered in LPI\n");
240 status |= core_irq_rx_path_in_lpi_mode; 241 x->irq_rx_path_in_lpi_mode_n++;
241 } 242 }
242 if (lpi_status & LPI_CTRL_STATUS_RLPIEX) { 243 if (ret & LPI_CTRL_STATUS_RLPIEX) {
243 CHIP_DBG(KERN_INFO "GMAC RX exit from LPI\n"); 244 CHIP_DBG(KERN_INFO "GMAC RX exit from LPI\n");
244 status |= core_irq_rx_path_exit_lpi_mode; 245 x->irq_rx_path_exit_lpi_mode_n++;
245 } 246 }
246 } 247 }
247 248
248 return status; 249 if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
250 CHIP_DBG(KERN_INFO "GMAC PCS ANE IRQ\n");
251 readl(ioaddr + GMAC_AN_STATUS);
252 x->irq_pcs_ane_n++;
253 }
254 if (intr_status & rgmii_irq) {
255 CHIP_DBG(KERN_INFO "GMAC RGMII IRQ status\n");
256 readl(ioaddr + GMAC_S_R_GMII);
257 x->irq_rgmii_n++;
258 }
259
260 return ret;
249} 261}
250 262
251static void dwmac1000_set_eee_mode(void __iomem *ioaddr) 263static void dwmac1000_set_eee_mode(void __iomem *ioaddr)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index f83210e7c221..cb86a58c1c5f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -72,7 +72,8 @@ static int dwmac100_rx_ipc_enable(void __iomem *ioaddr)
72 return 0; 72 return 0;
73} 73}
74 74
75static int dwmac100_irq_status(void __iomem *ioaddr) 75static int dwmac100_irq_status(void __iomem *ioaddr,
76 struct stmmac_extra_stats *x)
76{ 77{
77 return 0; 78 return 0;
78} 79}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index f6ad751925e8..179362857096 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -131,6 +131,10 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
131 STMMAC_STAT(l3_filter_match), 131 STMMAC_STAT(l3_filter_match),
132 STMMAC_STAT(l4_filter_match), 132 STMMAC_STAT(l4_filter_match),
133 STMMAC_STAT(l3_l4_filter_no_match), 133 STMMAC_STAT(l3_l4_filter_no_match),
134 /* PCS */
135 STMMAC_STAT(irq_pcs_ane_n),
136 STMMAC_STAT(irq_pcs_link_n),
137 STMMAC_STAT(irq_rgmii_n),
134}; 138};
135#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) 139#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
136 140
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 96fbf86366a9..ca3e95a4b16f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1780,30 +1780,14 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
1780 /* To handle GMAC own interrupts */ 1780 /* To handle GMAC own interrupts */
1781 if (priv->plat->has_gmac) { 1781 if (priv->plat->has_gmac) {
1782 int status = priv->hw->mac->host_irq_status((void __iomem *) 1782 int status = priv->hw->mac->host_irq_status((void __iomem *)
1783 dev->base_addr); 1783 dev->base_addr,
1784 &priv->xstats);
1784 if (unlikely(status)) { 1785 if (unlikely(status)) {
1785 if (status & core_mmc_tx_irq)
1786 priv->xstats.mmc_tx_irq_n++;
1787 if (status & core_mmc_rx_irq)
1788 priv->xstats.mmc_rx_irq_n++;
1789 if (status & core_mmc_rx_csum_offload_irq)
1790 priv->xstats.mmc_rx_csum_offload_irq_n++;
1791 if (status & core_irq_receive_pmt_irq)
1792 priv->xstats.irq_receive_pmt_irq_n++;
1793
1794 /* For LPI we need to save the tx status */ 1786 /* For LPI we need to save the tx status */
1795 if (status & core_irq_tx_path_in_lpi_mode) { 1787 if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE)
1796 priv->xstats.irq_tx_path_in_lpi_mode_n++;
1797 priv->tx_path_in_lpi_mode = true; 1788 priv->tx_path_in_lpi_mode = true;
1798 } 1789 if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE)
1799 if (status & core_irq_tx_path_exit_lpi_mode) {
1800 priv->xstats.irq_tx_path_exit_lpi_mode_n++;
1801 priv->tx_path_in_lpi_mode = false; 1790 priv->tx_path_in_lpi_mode = false;
1802 }
1803 if (status & core_irq_rx_path_in_lpi_mode)
1804 priv->xstats.irq_rx_path_in_lpi_mode_n++;
1805 if (status & core_irq_rx_path_exit_lpi_mode)
1806 priv->xstats.irq_rx_path_exit_lpi_mode_n++;
1807 } 1791 }
1808 } 1792 }
1809 1793