[net-next,v3,3/3] net: stmmac: Add driver support for DWMAC5 safety IRQ Support
Commit Message
Add IRQ support to listen HW safety IRQ like ECC,DPP,FSM
fault and print the fault information in the kernel
log.
Signed-off-by: Suraj Jaiswal <quic_jsuraj@quicinc.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 ++
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 18 ++++++++++++++++++
.../ethernet/stmicro/stmmac/stmmac_platform.c | 9 +++++++++
4 files changed, 30 insertions(+)
Comments
On Mon, Dec 04, 2023 at 06:56:17PM +0530, Suraj Jaiswal wrote:
> Add IRQ support to listen HW safety IRQ like ECC,DPP,FSM
> fault and print the fault information in the kernel
> log.
>
> Signed-off-by: Suraj Jaiswal <quic_jsuraj@quicinc.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/common.h | 1 +
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 ++
> .../net/ethernet/stmicro/stmmac/stmmac_main.c | 18 ++++++++++++++++++
> .../ethernet/stmicro/stmmac/stmmac_platform.c | 9 +++++++++
> 4 files changed, 30 insertions(+)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 6b935922054d..c4821c7ab674 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -347,6 +347,7 @@ enum request_irq_err {
> REQ_IRQ_ERR_SFTY_UE,
> REQ_IRQ_ERR_SFTY_CE,
> REQ_IRQ_ERR_LPI,
> + REQ_IRQ_ERR_SAFETY,
> REQ_IRQ_ERR_WOL,
> REQ_IRQ_ERR_MAC,
> REQ_IRQ_ERR_NO,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index 686c94c2e8a7..8eac37ff002d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -33,6 +33,7 @@ struct stmmac_resources {
> int irq;
> int sfty_ce_irq;
> int sfty_ue_irq;
> + int safety_common_irq;
> int rx_irq[MTL_MAX_RX_QUEUES];
> int tx_irq[MTL_MAX_TX_QUEUES];
> };
> @@ -343,6 +344,7 @@ struct stmmac_priv {
> /* XDP BPF Program */
> unsigned long *af_xdp_zc_qps;
> struct bpf_prog *xdp_prog;
> + int safety_common_irq;
This probably belongs with the other IRQs instead of the "XDP BPF Program"
section for readability.
> };
>
> enum stmmac_state {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index c2ac88aaffed..46a5cb20e4b4 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -3591,6 +3591,10 @@ static void stmmac_free_irq(struct net_device *dev,
> if (priv->wol_irq > 0 && priv->wol_irq != dev->irq)
> free_irq(priv->wol_irq, dev);
> fallthrough;
> + case REQ_IRQ_ERR_SAFETY:
> + if (priv->safety_common_irq > 0 && priv->safety_common_irq != dev->irq)
> + free_irq(priv->safety_common_irq, dev);
> + fallthrough;
> case REQ_IRQ_ERR_WOL:
> free_irq(dev->irq, dev);
> fallthrough;
> @@ -3797,6 +3801,18 @@ static int stmmac_request_irq_single(struct net_device *dev)
> }
> }
>
> + if (priv->safety_common_irq > 0 && priv->safety_common_irq != dev->irq) {
> + ret = request_irq(priv->safety_common_irq, stmmac_safety_interrupt,
> + 0, "safety", dev);
> + if (unlikely(ret < 0)) {
> + netdev_err(priv->dev,
> + "%s: alloc safety failed %d (error: %d)\n",
> + __func__, priv->safety_common_irq, ret);
> + irq_err = REQ_IRQ_ERR_SAFETY;
> + goto irq_error;
> + }
> + }
> +
> return 0;
>
> irq_error:
> @@ -7459,6 +7475,8 @@ int stmmac_dvr_probe(struct device *device,
> priv->lpi_irq = res->lpi_irq;
> priv->sfty_ce_irq = res->sfty_ce_irq;
> priv->sfty_ue_irq = res->sfty_ue_irq;
> + priv->safety_common_irq = res->safety_common_irq;
> +
> for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
> priv->rx_irq[i] = res->rx_irq[i];
> for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 1ffde555da47..41a4a253d75b 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -726,6 +726,15 @@ int stmmac_get_platform_resources(struct platform_device *pdev,
> dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
> }
>
> + stmmac_res->safety_common_irq =
> + platform_get_irq_byname_optional(pdev, "safety");
> +
> + if (stmmac_res->safety_common_irq < 0) {
> + if (stmmac_res->safety_common_irq == -EPROBE_DEFER)
> + return -EPROBE_DEFER;
> + dev_info(&pdev->dev, "IRQ safety IRQ not found\n");
> + }
> +
> stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0);
>
> return PTR_ERR_OR_ZERO(stmmac_res->addr);
> --
> 2.25.1
>
@@ -347,6 +347,7 @@ enum request_irq_err {
REQ_IRQ_ERR_SFTY_UE,
REQ_IRQ_ERR_SFTY_CE,
REQ_IRQ_ERR_LPI,
+ REQ_IRQ_ERR_SAFETY,
REQ_IRQ_ERR_WOL,
REQ_IRQ_ERR_MAC,
REQ_IRQ_ERR_NO,
@@ -33,6 +33,7 @@ struct stmmac_resources {
int irq;
int sfty_ce_irq;
int sfty_ue_irq;
+ int safety_common_irq;
int rx_irq[MTL_MAX_RX_QUEUES];
int tx_irq[MTL_MAX_TX_QUEUES];
};
@@ -343,6 +344,7 @@ struct stmmac_priv {
/* XDP BPF Program */
unsigned long *af_xdp_zc_qps;
struct bpf_prog *xdp_prog;
+ int safety_common_irq;
};
enum stmmac_state {
@@ -3591,6 +3591,10 @@ static void stmmac_free_irq(struct net_device *dev,
if (priv->wol_irq > 0 && priv->wol_irq != dev->irq)
free_irq(priv->wol_irq, dev);
fallthrough;
+ case REQ_IRQ_ERR_SAFETY:
+ if (priv->safety_common_irq > 0 && priv->safety_common_irq != dev->irq)
+ free_irq(priv->safety_common_irq, dev);
+ fallthrough;
case REQ_IRQ_ERR_WOL:
free_irq(dev->irq, dev);
fallthrough;
@@ -3797,6 +3801,18 @@ static int stmmac_request_irq_single(struct net_device *dev)
}
}
+ if (priv->safety_common_irq > 0 && priv->safety_common_irq != dev->irq) {
+ ret = request_irq(priv->safety_common_irq, stmmac_safety_interrupt,
+ 0, "safety", dev);
+ if (unlikely(ret < 0)) {
+ netdev_err(priv->dev,
+ "%s: alloc safety failed %d (error: %d)\n",
+ __func__, priv->safety_common_irq, ret);
+ irq_err = REQ_IRQ_ERR_SAFETY;
+ goto irq_error;
+ }
+ }
+
return 0;
irq_error:
@@ -7459,6 +7475,8 @@ int stmmac_dvr_probe(struct device *device,
priv->lpi_irq = res->lpi_irq;
priv->sfty_ce_irq = res->sfty_ce_irq;
priv->sfty_ue_irq = res->sfty_ue_irq;
+ priv->safety_common_irq = res->safety_common_irq;
+
for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
priv->rx_irq[i] = res->rx_irq[i];
for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
@@ -726,6 +726,15 @@ int stmmac_get_platform_resources(struct platform_device *pdev,
dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
}
+ stmmac_res->safety_common_irq =
+ platform_get_irq_byname_optional(pdev, "safety");
+
+ if (stmmac_res->safety_common_irq < 0) {
+ if (stmmac_res->safety_common_irq == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_info(&pdev->dev, "IRQ safety IRQ not found\n");
+ }
+
stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0);
return PTR_ERR_OR_ZERO(stmmac_res->addr);