sh_eth: factor out sh_eth_emac_interrupt()
The E-MAC interrupt (EESR.ECI) is not always caused by an error condition, so it really shouldn't be handled by sh_eth_error(). Factor out the E-MAC interrupt handler, sh_eth_emac_interrupt(), removing the ECI bit from the EESR's values throughout the driver... Update Cogent Embedded's copyright and clean up the whitespace in Renesas' copyright, while at it... Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1940f24076
commit
9b39f05ce8
|
@ -1,9 +1,9 @@
|
||||||
/* SuperH Ethernet device driver
|
/* SuperH Ethernet device driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Renesas Electronics Corporation
|
* Copyright (C) 2014 Renesas Electronics Corporation
|
||||||
* Copyright (C) 2006-2012 Nobuhiro Iwamatsu
|
* Copyright (C) 2006-2012 Nobuhiro Iwamatsu
|
||||||
* Copyright (C) 2008-2014 Renesas Solutions Corp.
|
* Copyright (C) 2008-2014 Renesas Solutions Corp.
|
||||||
* Copyright (C) 2013-2016 Cogent Embedded, Inc.
|
* Copyright (C) 2013-2017 Cogent Embedded, Inc.
|
||||||
* Copyright (C) 2014 Codethink Limited
|
* Copyright (C) 2014 Codethink Limited
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
@ -523,7 +523,7 @@ static struct sh_eth_cpu_data r7s72100_data = {
|
||||||
.tx_check = EESR_TC1 | EESR_FTC,
|
.tx_check = EESR_TC1 | EESR_FTC,
|
||||||
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
||||||
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
|
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
|
||||||
EESR_TDE | EESR_ECI,
|
EESR_TDE,
|
||||||
.fdr_value = 0x0000070f,
|
.fdr_value = 0x0000070f,
|
||||||
|
|
||||||
.no_psr = 1,
|
.no_psr = 1,
|
||||||
|
@ -562,7 +562,7 @@ static struct sh_eth_cpu_data r8a7740_data = {
|
||||||
.tx_check = EESR_TC1 | EESR_FTC,
|
.tx_check = EESR_TC1 | EESR_FTC,
|
||||||
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
||||||
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
|
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
|
||||||
EESR_TDE | EESR_ECI,
|
EESR_TDE,
|
||||||
.fdr_value = 0x0000070f,
|
.fdr_value = 0x0000070f,
|
||||||
|
|
||||||
.apr = 1,
|
.apr = 1,
|
||||||
|
@ -607,8 +607,7 @@ static struct sh_eth_cpu_data r8a777x_data = {
|
||||||
|
|
||||||
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
|
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
|
||||||
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
|
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
|
||||||
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
|
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE,
|
||||||
EESR_ECI,
|
|
||||||
.fdr_value = 0x00000f0f,
|
.fdr_value = 0x00000f0f,
|
||||||
|
|
||||||
.apr = 1,
|
.apr = 1,
|
||||||
|
@ -630,8 +629,7 @@ static struct sh_eth_cpu_data r8a779x_data = {
|
||||||
|
|
||||||
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
|
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
|
||||||
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
|
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
|
||||||
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
|
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE,
|
||||||
EESR_ECI,
|
|
||||||
.fdr_value = 0x00000f0f,
|
.fdr_value = 0x00000f0f,
|
||||||
|
|
||||||
.trscer_err_mask = DESC_I_RINT8,
|
.trscer_err_mask = DESC_I_RINT8,
|
||||||
|
@ -671,8 +669,7 @@ static struct sh_eth_cpu_data sh7724_data = {
|
||||||
|
|
||||||
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
|
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
|
||||||
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
|
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
|
||||||
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
|
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE,
|
||||||
EESR_ECI,
|
|
||||||
|
|
||||||
.apr = 1,
|
.apr = 1,
|
||||||
.mpr = 1,
|
.mpr = 1,
|
||||||
|
@ -707,8 +704,7 @@ static struct sh_eth_cpu_data sh7757_data = {
|
||||||
|
|
||||||
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
|
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
|
||||||
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
|
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
|
||||||
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
|
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE,
|
||||||
EESR_ECI,
|
|
||||||
|
|
||||||
.irq_flags = IRQF_SHARED,
|
.irq_flags = IRQF_SHARED,
|
||||||
.apr = 1,
|
.apr = 1,
|
||||||
|
@ -776,7 +772,7 @@ static struct sh_eth_cpu_data sh7757_data_giga = {
|
||||||
.tx_check = EESR_TC1 | EESR_FTC,
|
.tx_check = EESR_TC1 | EESR_FTC,
|
||||||
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
||||||
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
|
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
|
||||||
EESR_TDE | EESR_ECI,
|
EESR_TDE,
|
||||||
.fdr_value = 0x0000072f,
|
.fdr_value = 0x0000072f,
|
||||||
|
|
||||||
.irq_flags = IRQF_SHARED,
|
.irq_flags = IRQF_SHARED,
|
||||||
|
@ -807,7 +803,7 @@ static struct sh_eth_cpu_data sh7734_data = {
|
||||||
.tx_check = EESR_TC1 | EESR_FTC,
|
.tx_check = EESR_TC1 | EESR_FTC,
|
||||||
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
||||||
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
|
EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
|
||||||
EESR_TDE | EESR_ECI,
|
EESR_TDE,
|
||||||
|
|
||||||
.apr = 1,
|
.apr = 1,
|
||||||
.mpr = 1,
|
.mpr = 1,
|
||||||
|
@ -835,8 +831,7 @@ static struct sh_eth_cpu_data sh7763_data = {
|
||||||
|
|
||||||
.tx_check = EESR_TC1 | EESR_FTC,
|
.tx_check = EESR_TC1 | EESR_FTC,
|
||||||
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
||||||
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
|
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE,
|
||||||
EESR_ECI,
|
|
||||||
|
|
||||||
.apr = 1,
|
.apr = 1,
|
||||||
.mpr = 1,
|
.mpr = 1,
|
||||||
|
@ -1526,43 +1521,44 @@ static void sh_eth_rcv_snd_enable(struct net_device *ndev)
|
||||||
sh_eth_modify(ndev, ECMR, ECMR_RE | ECMR_TE, ECMR_RE | ECMR_TE);
|
sh_eth_modify(ndev, ECMR, ECMR_RE | ECMR_TE, ECMR_RE | ECMR_TE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error control function */
|
/* E-MAC interrupt handler */
|
||||||
static void sh_eth_error(struct net_device *ndev, u32 intr_status)
|
static void sh_eth_emac_interrupt(struct net_device *ndev)
|
||||||
{
|
{
|
||||||
struct sh_eth_private *mdp = netdev_priv(ndev);
|
struct sh_eth_private *mdp = netdev_priv(ndev);
|
||||||
u32 felic_stat;
|
u32 felic_stat;
|
||||||
u32 link_stat;
|
u32 link_stat;
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
if (intr_status & EESR_ECI) {
|
felic_stat = sh_eth_read(ndev, ECSR) & sh_eth_read(ndev, ECSIPR);
|
||||||
felic_stat = sh_eth_read(ndev, ECSR) &
|
sh_eth_write(ndev, felic_stat, ECSR); /* clear int */
|
||||||
sh_eth_read(ndev, ECSIPR);
|
if (felic_stat & ECSR_ICD)
|
||||||
sh_eth_write(ndev, felic_stat, ECSR); /* clear int */
|
ndev->stats.tx_carrier_errors++;
|
||||||
if (felic_stat & ECSR_ICD)
|
if (felic_stat & ECSR_LCHNG) {
|
||||||
ndev->stats.tx_carrier_errors++;
|
/* Link Changed */
|
||||||
if (felic_stat & ECSR_LCHNG) {
|
if (mdp->cd->no_psr || mdp->no_ether_link)
|
||||||
/* Link Changed */
|
return;
|
||||||
if (mdp->cd->no_psr || mdp->no_ether_link)
|
link_stat = sh_eth_read(ndev, PSR);
|
||||||
goto ignore_link;
|
if (mdp->ether_link_active_low)
|
||||||
link_stat = sh_eth_read(ndev, PSR);
|
link_stat = ~link_stat;
|
||||||
if (mdp->ether_link_active_low)
|
if (!(link_stat & PHY_ST_LINK)) {
|
||||||
link_stat = ~link_stat;
|
sh_eth_rcv_snd_disable(ndev);
|
||||||
if (!(link_stat & PHY_ST_LINK)) {
|
} else {
|
||||||
sh_eth_rcv_snd_disable(ndev);
|
/* Link Up */
|
||||||
} else {
|
sh_eth_modify(ndev, EESIPR, DMAC_M_ECI, 0);
|
||||||
/* Link Up */
|
/* clear int */
|
||||||
sh_eth_modify(ndev, EESIPR, DMAC_M_ECI, 0);
|
sh_eth_modify(ndev, ECSR, 0, 0);
|
||||||
/* clear int */
|
sh_eth_modify(ndev, EESIPR, DMAC_M_ECI, DMAC_M_ECI);
|
||||||
sh_eth_modify(ndev, ECSR, 0, 0);
|
/* enable tx and rx */
|
||||||
sh_eth_modify(ndev, EESIPR, DMAC_M_ECI,
|
sh_eth_rcv_snd_enable(ndev);
|
||||||
DMAC_M_ECI);
|
|
||||||
/* enable tx and rx */
|
|
||||||
sh_eth_rcv_snd_enable(ndev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* error control function */
|
||||||
|
static void sh_eth_error(struct net_device *ndev, u32 intr_status)
|
||||||
|
{
|
||||||
|
struct sh_eth_private *mdp = netdev_priv(ndev);
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
ignore_link:
|
|
||||||
if (intr_status & EESR_TWB) {
|
if (intr_status & EESR_TWB) {
|
||||||
/* Unused write back interrupt */
|
/* Unused write back interrupt */
|
||||||
if (intr_status & EESR_TABT) { /* Transmit Abort int */
|
if (intr_status & EESR_TABT) { /* Transmit Abort int */
|
||||||
|
@ -1643,14 +1639,16 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
|
||||||
|
|
||||||
/* Get interrupt status */
|
/* Get interrupt status */
|
||||||
intr_status = sh_eth_read(ndev, EESR);
|
intr_status = sh_eth_read(ndev, EESR);
|
||||||
/* Mask it with the interrupt mask, forcing ECI interrupt to be always
|
/* Mask it with the interrupt mask, forcing ECI interrupt to be always
|
||||||
* enabled since it's the one that comes thru regardless of the mask,
|
* enabled since it's the one that comes thru regardless of the mask,
|
||||||
* and we need to fully handle it in sh_eth_error() in order to quench
|
* and we need to fully handle it in sh_eth_emac_interrupt() in order
|
||||||
* it as it doesn't get cleared by just writing 1 to the ECI bit...
|
* to quench it as it doesn't get cleared by just writing 1 to the ECI
|
||||||
|
* bit...
|
||||||
*/
|
*/
|
||||||
intr_enable = sh_eth_read(ndev, EESIPR);
|
intr_enable = sh_eth_read(ndev, EESIPR);
|
||||||
intr_status &= intr_enable | DMAC_M_ECI;
|
intr_status &= intr_enable | DMAC_M_ECI;
|
||||||
if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check))
|
if (intr_status & (EESR_RX_CHECK | cd->tx_check | EESR_ECI |
|
||||||
|
cd->eesr_err_check))
|
||||||
ret = IRQ_HANDLED;
|
ret = IRQ_HANDLED;
|
||||||
else
|
else
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1682,6 +1680,10 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
|
||||||
netif_wake_queue(ndev);
|
netif_wake_queue(ndev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* E-MAC interrupt */
|
||||||
|
if (intr_status & EESR_ECI)
|
||||||
|
sh_eth_emac_interrupt(ndev);
|
||||||
|
|
||||||
if (intr_status & cd->eesr_err_check) {
|
if (intr_status & cd->eesr_err_check) {
|
||||||
/* Clear error interrupts */
|
/* Clear error interrupts */
|
||||||
sh_eth_write(ndev, intr_status & cd->eesr_err_check, EESR);
|
sh_eth_write(ndev, intr_status & cd->eesr_err_check, EESR);
|
||||||
|
|
|
@ -265,7 +265,7 @@ enum EESR_BIT {
|
||||||
EESR_RTO)
|
EESR_RTO)
|
||||||
#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | \
|
#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | \
|
||||||
EESR_RDE | EESR_RFRMER | EESR_ADE | \
|
EESR_RDE | EESR_RFRMER | EESR_ADE | \
|
||||||
EESR_TFE | EESR_TDE | EESR_ECI)
|
EESR_TFE | EESR_TDE)
|
||||||
|
|
||||||
/* EESIPR */
|
/* EESIPR */
|
||||||
enum DMAC_IM_BIT {
|
enum DMAC_IM_BIT {
|
||||||
|
|
Loading…
Reference in New Issue