In order to have our interrupt descriptor fully setup and in particular the action, ensure that we register a full fledged interrupt handler. This also allow us to set the interrupt polarity and flow through the same call. This is specifically necessary for kernel/irq/pm.c::suspend_device_irq to set the interrupt descriptor to the IRQD_WAKEUP_ARMED state and enable the interrupt for wake-up since it was still in a disabled state. Without an interrupt descriptor we would have ran into cases where the wake-up interrupt is not capable of waking up the system, specifically if we resumed the system ACPI S5 using the Ethernet PHY. In that case the Ethernet PHY interrupt would be pending by the time the kernel booted, which it would acknowledge but then we could never use it as a wake-up source again. Fixes: 8baddaa9d4ba ("net: phy: broadcom: Add support for Wake-on-LAN") Suggested-by: Doug Berger <doug.berger@broadcom.com> Debugged-by: Doug Berger <doug.berger@broadcom.com> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David S. Miller <davem@davemloft.net>
122 lines
4.2 KiB
C
122 lines
4.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2015 Broadcom Corporation
|
|
*/
|
|
|
|
#ifndef _LINUX_BCM_PHY_LIB_H
|
|
#define _LINUX_BCM_PHY_LIB_H
|
|
|
|
#include <linux/brcmphy.h>
|
|
#include <linux/phy.h>
|
|
#include <linux/interrupt.h>
|
|
|
|
struct ethtool_wolinfo;
|
|
|
|
/* 28nm only register definitions */
|
|
#define MISC_ADDR(base, channel) base, channel
|
|
|
|
#define DSP_TAP10 MISC_ADDR(0x0a, 0)
|
|
#define PLL_PLLCTRL_1 MISC_ADDR(0x32, 1)
|
|
#define PLL_PLLCTRL_2 MISC_ADDR(0x32, 2)
|
|
#define PLL_PLLCTRL_4 MISC_ADDR(0x33, 0)
|
|
|
|
#define AFE_RXCONFIG_0 MISC_ADDR(0x38, 0)
|
|
#define AFE_RXCONFIG_1 MISC_ADDR(0x38, 1)
|
|
#define AFE_RXCONFIG_2 MISC_ADDR(0x38, 2)
|
|
#define AFE_RX_LP_COUNTER MISC_ADDR(0x38, 3)
|
|
#define AFE_TX_CONFIG MISC_ADDR(0x39, 0)
|
|
#define AFE_VDCA_ICTRL_0 MISC_ADDR(0x39, 1)
|
|
#define AFE_VDAC_OTHERS_0 MISC_ADDR(0x39, 3)
|
|
#define AFE_HPF_TRIM_OTHERS MISC_ADDR(0x3a, 0)
|
|
|
|
|
|
int __bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
|
|
int __bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
|
|
int __bcm_phy_modify_exp(struct phy_device *phydev, u16 reg, u16 mask, u16 set);
|
|
int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
|
|
int bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
|
|
int bcm_phy_modify_exp(struct phy_device *phydev, u16 reg, u16 mask, u16 set);
|
|
|
|
static inline int bcm_phy_write_exp_sel(struct phy_device *phydev,
|
|
u16 reg, u16 val)
|
|
{
|
|
return bcm_phy_write_exp(phydev, reg | MII_BCM54XX_EXP_SEL_ER, val);
|
|
}
|
|
|
|
static inline int bcm_phy_read_exp_sel(struct phy_device *phydev, u16 reg)
|
|
{
|
|
return bcm_phy_read_exp(phydev, reg | MII_BCM54XX_EXP_SEL_ER);
|
|
}
|
|
|
|
int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val);
|
|
int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum);
|
|
|
|
int bcm_phy_write_misc(struct phy_device *phydev,
|
|
u16 reg, u16 chl, u16 value);
|
|
int bcm_phy_read_misc(struct phy_device *phydev,
|
|
u16 reg, u16 chl);
|
|
|
|
int bcm_phy_write_shadow(struct phy_device *phydev, u16 shadow,
|
|
u16 val);
|
|
int bcm_phy_read_shadow(struct phy_device *phydev, u16 shadow);
|
|
|
|
int __bcm_phy_write_rdb(struct phy_device *phydev, u16 rdb, u16 val);
|
|
int bcm_phy_write_rdb(struct phy_device *phydev, u16 rdb, u16 val);
|
|
int __bcm_phy_read_rdb(struct phy_device *phydev, u16 rdb);
|
|
int bcm_phy_read_rdb(struct phy_device *phydev, u16 rdb);
|
|
int __bcm_phy_modify_rdb(struct phy_device *phydev, u16 rdb, u16 mask,
|
|
u16 set);
|
|
int bcm_phy_modify_rdb(struct phy_device *phydev, u16 rdb, u16 mask,
|
|
u16 set);
|
|
|
|
int bcm_phy_ack_intr(struct phy_device *phydev);
|
|
int bcm_phy_config_intr(struct phy_device *phydev);
|
|
irqreturn_t bcm_phy_handle_interrupt(struct phy_device *phydev);
|
|
|
|
int bcm_phy_enable_apd(struct phy_device *phydev, bool dll_pwr_down);
|
|
|
|
int bcm_phy_set_eee(struct phy_device *phydev, bool enable);
|
|
|
|
int bcm_phy_downshift_get(struct phy_device *phydev, u8 *count);
|
|
|
|
int bcm_phy_downshift_set(struct phy_device *phydev, u8 count);
|
|
|
|
int bcm_phy_get_sset_count(struct phy_device *phydev);
|
|
void bcm_phy_get_strings(struct phy_device *phydev, u8 *data);
|
|
void bcm_phy_get_stats(struct phy_device *phydev, u64 *shadow,
|
|
struct ethtool_stats *stats, u64 *data);
|
|
void bcm_phy_r_rc_cal_reset(struct phy_device *phydev);
|
|
int bcm_phy_28nm_a0b0_afe_config_init(struct phy_device *phydev);
|
|
int bcm_phy_enable_jumbo(struct phy_device *phydev);
|
|
|
|
int bcm_phy_cable_test_get_status_rdb(struct phy_device *phydev,
|
|
bool *finished);
|
|
int bcm_phy_cable_test_start_rdb(struct phy_device *phydev);
|
|
int bcm_phy_cable_test_start(struct phy_device *phydev);
|
|
int bcm_phy_cable_test_get_status(struct phy_device *phydev, bool *finished);
|
|
|
|
#if IS_ENABLED(CONFIG_BCM_NET_PHYPTP)
|
|
struct bcm_ptp_private *bcm_ptp_probe(struct phy_device *phydev);
|
|
void bcm_ptp_config_init(struct phy_device *phydev);
|
|
void bcm_ptp_stop(struct bcm_ptp_private *priv);
|
|
#else
|
|
static inline struct bcm_ptp_private *bcm_ptp_probe(struct phy_device *phydev)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void bcm_ptp_config_init(struct phy_device *phydev)
|
|
{
|
|
}
|
|
|
|
static inline void bcm_ptp_stop(struct bcm_ptp_private *priv)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
int bcm_phy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);
|
|
void bcm_phy_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);
|
|
irqreturn_t bcm_phy_wol_isr(int irq, void *dev_id);
|
|
|
|
#endif /* _LINUX_BCM_PHY_LIB_H */
|