stmmac registers a 32-bit. u32 is unsigned int. The use of BIT() and GENMASK() leads to integer promotion to unsigned long in expressions such as: u32 old = foo; dev_info(dev, "%08x %08x\n", old, old & BIT(1)); resulting in arg2 being accepted as compatible with the format string and arg3 warning that the argument does not match (because the former is unsigned int, and the latter is unsigned long.) Fix this by defining 32-bit register bits using BIT_U32() and GENMASK_U32() macros. Signed-off-by: Russell King (Oracle) --- .../net/ethernet/stmicro/stmmac/stmmac_pcs.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h index cda93894168e..fd2e2d7d5bd4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h @@ -25,27 +25,27 @@ #define GMAC_TBI(x) (x + 0x14) /* TBI extend status */ /* AN Configuration defines */ -#define GMAC_AN_CTRL_RAN BIT(9) /* Restart Auto-Negotiation */ -#define GMAC_AN_CTRL_ANE BIT(12) /* Auto-Negotiation Enable */ -#define GMAC_AN_CTRL_ELE BIT(14) /* External Loopback Enable */ -#define GMAC_AN_CTRL_ECD BIT(16) /* Enable Comma Detect */ -#define GMAC_AN_CTRL_LR BIT(17) /* Lock to Reference */ -#define GMAC_AN_CTRL_SGMRAL BIT(18) /* SGMII RAL Control */ +#define GMAC_AN_CTRL_RAN BIT_U32(9) /* Restart Auto-Negotiation */ +#define GMAC_AN_CTRL_ANE BIT_U32(12) /* Auto-Negotiation Enable */ +#define GMAC_AN_CTRL_ELE BIT_U32(14) /* External Loopback Enable */ +#define GMAC_AN_CTRL_ECD BIT_U32(16) /* Enable Comma Detect */ +#define GMAC_AN_CTRL_LR BIT_U32(17) /* Lock to Reference */ +#define GMAC_AN_CTRL_SGMRAL BIT_U32(18) /* SGMII RAL Control */ /* AN Status defines */ -#define GMAC_AN_STATUS_LS BIT(2) /* Link Status 0:down 1:up */ -#define GMAC_AN_STATUS_ANA BIT(3) /* Auto-Negotiation Ability */ -#define GMAC_AN_STATUS_ANC BIT(5) /* Auto-Negotiation Complete */ -#define GMAC_AN_STATUS_ES BIT(8) /* Extended Status */ +#define GMAC_AN_STATUS_LS BIT_U32(2) /* Link Status 0:down 1:up */ +#define GMAC_AN_STATUS_ANA BIT_U32(3) /* Auto-Negotiation Ability */ +#define GMAC_AN_STATUS_ANC BIT_U32(5) /* Auto-Negotiation Complete */ +#define GMAC_AN_STATUS_ES BIT_U32(8) /* Extended Status */ /* ADV and LPA defines */ -#define GMAC_ANE_FD BIT(5) -#define GMAC_ANE_HD BIT(6) -#define GMAC_ANE_PSE GENMASK(8, 7) +#define GMAC_ANE_FD BIT_U32(5) +#define GMAC_ANE_HD BIT_U32(6) +#define GMAC_ANE_PSE GENMASK_U32(8, 7) #define GMAC_ANE_PSE_SHIFT 7 -#define GMAC_ANE_RFE GENMASK(13, 12) +#define GMAC_ANE_RFE GENMASK_U32(13, 12) #define GMAC_ANE_RFE_SHIFT 12 -#define GMAC_ANE_ACK BIT(14) +#define GMAC_ANE_ACK BIT_U32(14) struct stmmac_priv; -- 2.47.3 dwmac_pcs_isr() doesn't need to be inlined into the MAC's host_irq_status method, as handling PCS interrupts isn't performance critical. However, there is little point calling this function unless an interrupt is pending for the PCS. Rename it to stmmac_integrated_pcs_irq() while moving it. Signed-off-by: Russell King (Oracle) --- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 4 ++- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 4 ++- .../net/ethernet/stmicro/stmmac/stmmac_pcs.c | 30 +++++++++++++++++ .../net/ethernet/stmicro/stmmac/stmmac_pcs.h | 33 ++----------------- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index a2ae136d2c0e..9cc8f38e7e45 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -304,7 +304,9 @@ static int dwmac1000_irq_status(struct mac_device_info *hw, x->irq_rx_path_exit_lpi_mode_n++; } - dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x); + if (intr_status & (PCS_ANE_IRQ | PCS_LINK_IRQ)) + stmmac_integrated_pcs_irq(ioaddr, GMAC_PCS_BASE, intr_status, + x); return ret; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index a4282fd7c3c7..2a531c3c2e14 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -658,7 +658,9 @@ static int dwmac4_irq_status(struct mac_device_info *hw, x->irq_rx_path_exit_lpi_mode_n++; } - dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x); + if (intr_status & (PCS_ANE_IRQ | PCS_LINK_IRQ)) + stmmac_integrated_pcs_irq(ioaddr, GMAC_PCS_BASE, intr_status, + x); return ret; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c index e2f531c11986..90cdff30520b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c @@ -45,6 +45,36 @@ static const struct phylink_pcs_ops dwmac_integrated_pcs_ops = { .pcs_config = dwmac_integrated_pcs_config, }; +/** + * stmmac_integrated_pcs_irq - TBI, RTBI, or SGMII PHY ISR + * @ioaddr: IO registers pointer + * @reg: Base address of the AN Control Register. + * @intr_status: GMAC core interrupt status + * @x: pointer to log these events as stats + * Description: it is the ISR for PCS events: Auto-Negotiation Completed and + * Link status. + */ +void stmmac_integrated_pcs_irq(void __iomem *ioaddr, u32 reg, + unsigned int intr_status, + struct stmmac_extra_stats *x) +{ + u32 val = readl(ioaddr + GMAC_AN_STATUS(reg)); + + if (intr_status & PCS_ANE_IRQ) { + x->irq_pcs_ane_n++; + if (val & GMAC_AN_STATUS_ANC) + pr_info("stmmac_pcs: ANE process completed\n"); + } + + if (intr_status & PCS_LINK_IRQ) { + x->irq_pcs_link_n++; + if (val & GMAC_AN_STATUS_LS) + pr_info("stmmac_pcs: Link Up\n"); + else + pr_info("stmmac_pcs: Link Down\n"); + } +} + int stmmac_integrated_pcs_init(struct stmmac_priv *priv, unsigned int offset, u32 int_mask) { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h index fd2e2d7d5bd4..bfc3d665265c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h @@ -62,39 +62,12 @@ phylink_pcs_to_stmmac_pcs(struct phylink_pcs *pcs) return container_of(pcs, struct stmmac_pcs, pcs); } +void stmmac_integrated_pcs_irq(void __iomem *ioaddr, u32 reg, + unsigned int intr_status, + struct stmmac_extra_stats *x); int stmmac_integrated_pcs_init(struct stmmac_priv *priv, unsigned int offset, u32 int_mask); -/** - * dwmac_pcs_isr - TBI, RTBI, or SGMII PHY ISR - * @ioaddr: IO registers pointer - * @reg: Base address of the AN Control Register. - * @intr_status: GMAC core interrupt status - * @x: pointer to log these events as stats - * Description: it is the ISR for PCS events: Auto-Negotiation Completed and - * Link status. - */ -static inline void dwmac_pcs_isr(void __iomem *ioaddr, u32 reg, - unsigned int intr_status, - struct stmmac_extra_stats *x) -{ - u32 val = readl(ioaddr + GMAC_AN_STATUS(reg)); - - if (intr_status & PCS_ANE_IRQ) { - x->irq_pcs_ane_n++; - if (val & GMAC_AN_STATUS_ANC) - pr_info("stmmac_pcs: ANE process completed\n"); - } - - if (intr_status & PCS_LINK_IRQ) { - x->irq_pcs_link_n++; - if (val & GMAC_AN_STATUS_LS) - pr_info("stmmac_pcs: Link Up\n"); - else - pr_info("stmmac_pcs: Link Down\n"); - } -} - /** * dwmac_ctrl_ane - To program the AN Control Register. * @ioaddr: IO registers pointer -- 2.47.3 Rather than passing struct mac_device_info to the host_irq_status() method, pass struct stmmac_priv so that we can pass the integrated PCS to the PCS interrupt handler. Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 4 ++-- drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 4 ++-- drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 4 ++-- drivers/net/ethernet/stmicro/stmmac/hwif.h | 4 ++-- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 9cc8f38e7e45..b01815a28280 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -265,10 +265,10 @@ static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode) writel(pmt, ioaddr + GMAC_PMT); } -static int dwmac1000_irq_status(struct mac_device_info *hw, +static int dwmac1000_irq_status(struct stmmac_priv *priv, struct stmmac_extra_stats *x) { - void __iomem *ioaddr = hw->pcsr; + void __iomem *ioaddr = priv->hw->pcsr; u32 intr_status = readl(ioaddr + GMAC_INT_STATUS); u32 intr_mask = readl(ioaddr + GMAC_INT_MASK); int ret = 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index 14e847c0e1a9..cd2928c05550 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -53,7 +53,7 @@ static int dwmac100_rx_ipc_enable(struct mac_device_info *hw) return 0; } -static int dwmac100_irq_status(struct mac_device_info *hw, +static int dwmac100_irq_status(struct stmmac_priv *priv, struct stmmac_extra_stats *x) { return 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 2a531c3c2e14..e7ca181e8e76 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -615,10 +615,10 @@ static int dwmac4_irq_mtl_status(struct stmmac_priv *priv, return ret; } -static int dwmac4_irq_status(struct mac_device_info *hw, +static int dwmac4_irq_status(struct stmmac_priv *priv, struct stmmac_extra_stats *x) { - void __iomem *ioaddr = hw->pcsr; + void __iomem *ioaddr = priv->hw->pcsr; u32 intr_status = readl(ioaddr + GMAC_INT_STATUS); u32 intr_enable = readl(ioaddr + GMAC_INT_EN); int ret = 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c index b40b3ea50e25..6724a3f866fe 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c @@ -298,10 +298,10 @@ static void dwxgmac2_dump_regs(struct mac_device_info *hw, u32 *reg_space) reg_space[i] = readl(ioaddr + i * 4); } -static int dwxgmac2_host_irq_status(struct mac_device_info *hw, +static int dwxgmac2_host_irq_status(struct stmmac_priv *priv, struct stmmac_extra_stats *x) { - void __iomem *ioaddr = hw->pcsr; + void __iomem *ioaddr = priv->hw->pcsr; u32 stat, en; int ret = 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h index df6e8a567b1f..0db96a387259 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h @@ -354,7 +354,7 @@ struct stmmac_ops { /* Dump MAC registers */ void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space); /* Handle extra events on specific interrupts hw dependent */ - int (*host_irq_status)(struct mac_device_info *hw, + int (*host_irq_status)(struct stmmac_priv *priv, struct stmmac_extra_stats *x); /* Handle MTL interrupts */ int (*host_mtl_irq_status)(struct stmmac_priv *priv, @@ -453,7 +453,7 @@ struct stmmac_ops { #define stmmac_dump_mac_regs(__priv, __args...) \ stmmac_do_void_callback(__priv, mac, dump_regs, __args) #define stmmac_host_irq_status(__priv, __args...) \ - stmmac_do_callback(__priv, mac, host_irq_status, __args) + stmmac_do_callback(__priv, mac, host_irq_status, __priv, __args) #define stmmac_host_mtl_irq_status(__priv, __args...) \ stmmac_do_callback(__priv, mac, host_mtl_irq_status, __priv, __args) #define stmmac_set_filter(__priv, __args...) \ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index b3730312aeed..c2589f02ff7e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -6137,7 +6137,7 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv) /* To handle GMAC own interrupts */ if (priv->plat->core_type == DWMAC_CORE_GMAC || xmac) { - int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats); + int status = stmmac_host_irq_status(priv, &priv->xstats); if (unlikely(status)) { /* For LPI we need to save the tx status */ -- 2.47.3 Change the arguments to the PCS handler so that it can access the struct device pointer and integrated PCS pointers. This allows us to use the PCS register offset stored in struct stmmac_pcs rather than passing it into the function, and also allows the messages to be printed using dev_info() rather than pr_info(), thereby allowing the stmmac instance to be identified. Finally, as dev_info() identifies the driver/device, prefixing with "stmmac_pcs: " is now redundant, so replace this with just "PCS ". Signed-off-by: Russell King (Oracle) --- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 3 +- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 3 +- .../net/ethernet/stmicro/stmmac/stmmac_pcs.c | 28 ++++++------------- .../net/ethernet/stmicro/stmmac/stmmac_pcs.h | 3 +- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index b01815a28280..3756d3c4ee15 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -305,8 +305,7 @@ static int dwmac1000_irq_status(struct stmmac_priv *priv, } if (intr_status & (PCS_ANE_IRQ | PCS_LINK_IRQ)) - stmmac_integrated_pcs_irq(ioaddr, GMAC_PCS_BASE, intr_status, - x); + stmmac_integrated_pcs_irq(priv, intr_status, x); return ret; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index e7ca181e8e76..a9ec9a34ebca 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -659,8 +659,7 @@ static int dwmac4_irq_status(struct stmmac_priv *priv, } if (intr_status & (PCS_ANE_IRQ | PCS_LINK_IRQ)) - stmmac_integrated_pcs_irq(ioaddr, GMAC_PCS_BASE, intr_status, - x); + stmmac_integrated_pcs_irq(priv, intr_status, x); return ret; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c index 90cdff30520b..28748e7ef7dd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c @@ -45,33 +45,23 @@ static const struct phylink_pcs_ops dwmac_integrated_pcs_ops = { .pcs_config = dwmac_integrated_pcs_config, }; -/** - * stmmac_integrated_pcs_irq - TBI, RTBI, or SGMII PHY ISR - * @ioaddr: IO registers pointer - * @reg: Base address of the AN Control Register. - * @intr_status: GMAC core interrupt status - * @x: pointer to log these events as stats - * Description: it is the ISR for PCS events: Auto-Negotiation Completed and - * Link status. - */ -void stmmac_integrated_pcs_irq(void __iomem *ioaddr, u32 reg, - unsigned int intr_status, +void stmmac_integrated_pcs_irq(struct stmmac_priv *priv, u32 status, struct stmmac_extra_stats *x) { - u32 val = readl(ioaddr + GMAC_AN_STATUS(reg)); + struct stmmac_pcs *spcs = priv->integrated_pcs; + u32 val = readl(spcs->base + GMAC_AN_STATUS(0)); - if (intr_status & PCS_ANE_IRQ) { + if (status & PCS_ANE_IRQ) { x->irq_pcs_ane_n++; if (val & GMAC_AN_STATUS_ANC) - pr_info("stmmac_pcs: ANE process completed\n"); + dev_info(priv->device, + "PCS ANE process completed\n"); } - if (intr_status & PCS_LINK_IRQ) { + if (status & PCS_LINK_IRQ) { x->irq_pcs_link_n++; - if (val & GMAC_AN_STATUS_LS) - pr_info("stmmac_pcs: Link Up\n"); - else - pr_info("stmmac_pcs: Link Down\n"); + dev_info(priv->device, "PCS Link %s\n", + val & GMAC_AN_STATUS_LS ? "Up" : "Down"); } } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h index bfc3d665265c..c4e6b242d390 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h @@ -62,8 +62,7 @@ phylink_pcs_to_stmmac_pcs(struct phylink_pcs *pcs) return container_of(pcs, struct stmmac_pcs, pcs); } -void stmmac_integrated_pcs_irq(void __iomem *ioaddr, u32 reg, - unsigned int intr_status, +void stmmac_integrated_pcs_irq(struct stmmac_priv *priv, u32 status, struct stmmac_extra_stats *x); int stmmac_integrated_pcs_init(struct stmmac_priv *priv, unsigned int offset, u32 int_mask); -- 2.47.3 Report PCS link changes to phylink, which will allow phylink's inband support to respoind to link events once the PCS is appropriately configured. An expected behavioural change is that should the PCS report that its link has failed, but phylink is operating in outband mode and the PHY reports that link is up, this event will cause the netdev's link to momentarily drop, making the event more noticable, rather than just producing a "stmmac_pcs: Link Down" message. Signed-off-by: Russell King (Oracle) --- drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c index 28748e7ef7dd..2f826fe7229b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c @@ -62,6 +62,8 @@ void stmmac_integrated_pcs_irq(struct stmmac_priv *priv, u32 status, x->irq_pcs_link_n++; dev_info(priv->device, "PCS Link %s\n", val & GMAC_AN_STATUS_LS ? "Up" : "Down"); + + phylink_pcs_change(&spcs->pcs, val & GMAC_AN_STATUS_LS); } } -- 2.47.3