diff options
Diffstat (limited to 'drivers/net/phy/micrel.c')
-rw-r--r-- | drivers/net/phy/micrel.c | 1004 |
1 files changed, 763 insertions, 241 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 605b0315b4cb..79ce3eb6752b 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -107,6 +107,7 @@ #define LAN8814_INTC 0x18 #define LAN8814_INTS 0x1B +#define LAN8814_INT_FLF BIT(15) #define LAN8814_INT_LINK_DOWN BIT(2) #define LAN8814_INT_LINK_UP BIT(0) #define LAN8814_INT_LINK (LAN8814_INT_LINK_UP |\ @@ -266,6 +267,8 @@ #define LAN8814_LED_CTRL_1 0x0 #define LAN8814_LED_CTRL_1_KSZ9031_LED_MODE_ BIT(6) +#define LAN8814_LED_CTRL_2 0x1 +#define LAN8814_LED_CTRL_2_LED1_COM_DIS BIT(8) /* PHY Control 1 */ #define MII_KSZPHY_CTRL_1 0x1e @@ -362,6 +365,8 @@ /* Delay used to get the second part from the LTC */ #define LAN8841_GET_SEC_LTC_DELAY (500 * NSEC_PER_MSEC) +#define LAN8842_REV_8832 0x8832 + struct kszphy_hw_stat { const char *string; u8 reg; @@ -448,6 +453,19 @@ struct kszphy_priv { struct kszphy_phy_stats phy_stats; }; +struct lan8842_phy_stats { + u64 rx_packets; + u64 rx_errors; + u64 tx_packets; + u64 tx_errors; +}; + +struct lan8842_priv { + struct lan8842_phy_stats phy_stats; + struct kszphy_ptp_priv ptp_priv; + u16 rev; +}; + static const struct kszphy_type lan8814_type = { .led_mode_reg = ~LAN8814_LED_CTRL_1, .cable_diag_reg = LAN8814_CABLE_DIAG, @@ -2790,6 +2808,60 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev, return ret; } +/** + * LAN8814_PAGE_PCS - Selects Extended Page 0. + * + * This page contains timers used for auto-negotiation, debug registers and + * register to configure fast link failure. + */ +#define LAN8814_PAGE_PCS 0 + +/** + * LAN8814_PAGE_AFE_PMA - Selects Extended Page 1. + * + * This page appears to control the Analog Front-End (AFE) and Physical + * Medium Attachment (PMA) layers. It is used to access registers like + * LAN8814_PD_CONTROLS and LAN8814_LINK_QUALITY. + */ +#define LAN8814_PAGE_AFE_PMA 1 + +/** + * LAN8814_PAGE_PCS_DIGITAL - Selects Extended Page 2. + * + * This page seems dedicated to the Physical Coding Sublayer (PCS) and other + * digital logic. It is used for MDI-X alignment (LAN8814_ALIGN_SWAP) and EEE + * state (LAN8814_EEE_STATE) in the LAN8814, and is repurposed for statistics + * and self-test counters in the LAN8842. + */ +#define LAN8814_PAGE_PCS_DIGITAL 2 + +/** + * LAN8814_PAGE_COMMON_REGS - Selects Extended Page 4. + * + * This page contains device-common registers that affect the entire chip. + * It includes controls for chip-level resets, strap status, GPIO, + * QSGMII, the shared 1588 PTP block, and the PVT monitor. + */ +#define LAN8814_PAGE_COMMON_REGS 4 + +/** + * LAN8814_PAGE_PORT_REGS - Selects Extended Page 5. + * + * This page contains port-specific registers that must be accessed + * on a per-port basis. It includes controls for port LEDs, QSGMII PCS, + * rate adaptation FIFOs, and the per-port 1588 TSU block. + */ +#define LAN8814_PAGE_PORT_REGS 5 + +/** + * LAN8814_PAGE_SYSTEM_CTRL - Selects Extended Page 31. + * + * This page appears to hold fundamental system or global controls. In the + * driver, it is used by the related LAN8804 to access the + * LAN8814_CLOCK_MANAGEMENT register. + */ +#define LAN8814_PAGE_SYSTEM_CTRL 31 + #define LAN_EXT_PAGE_ACCESS_CONTROL 0x16 #define LAN_EXT_PAGE_ACCESS_ADDRESS_DATA 0x17 #define LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC 0x4000 @@ -2840,6 +2912,27 @@ static int lanphy_write_page_reg(struct phy_device *phydev, int page, u16 addr, return val; } +static int lanphy_modify_page_reg(struct phy_device *phydev, int page, u16 addr, + u16 mask, u16 set) +{ + int ret; + + phy_lock_mdio_bus(phydev); + __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page); + __phy_write(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, addr); + __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, + (page | LAN_EXT_PAGE_ACCESS_CTRL_EP_FUNC)); + ret = __phy_modify_changed(phydev, LAN_EXT_PAGE_ACCESS_ADDRESS_DATA, + mask, set); + phy_unlock_mdio_bus(phydev); + + if (ret < 0) + phydev_err(phydev, "__phy_modify_changed() failed: %pe\n", + ERR_PTR(ret)); + + return ret; +} + static int lan8814_config_ts_intr(struct phy_device *phydev, bool enable) { u16 val = 0; @@ -2850,35 +2943,46 @@ static int lan8814_config_ts_intr(struct phy_device *phydev, bool enable) PTP_TSU_INT_EN_PTP_RX_TS_EN_ | PTP_TSU_INT_EN_PTP_RX_TS_OVRFL_EN_; - return lanphy_write_page_reg(phydev, 5, PTP_TSU_INT_EN, val); + return lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TSU_INT_EN, val); } static void lan8814_ptp_rx_ts_get(struct phy_device *phydev, u32 *seconds, u32 *nano_seconds, u16 *seq_id) { - *seconds = lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_SEC_HI); + *seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_INGRESS_SEC_HI); *seconds = (*seconds << 16) | - lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_SEC_LO); + lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_INGRESS_SEC_LO); - *nano_seconds = lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_NS_HI); + *nano_seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_INGRESS_NS_HI); *nano_seconds = ((*nano_seconds & 0x3fff) << 16) | - lanphy_read_page_reg(phydev, 5, PTP_RX_INGRESS_NS_LO); + lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_INGRESS_NS_LO); - *seq_id = lanphy_read_page_reg(phydev, 5, PTP_RX_MSG_HEADER2); + *seq_id = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_MSG_HEADER2); } static void lan8814_ptp_tx_ts_get(struct phy_device *phydev, u32 *seconds, u32 *nano_seconds, u16 *seq_id) { - *seconds = lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_SEC_HI); + *seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_EGRESS_SEC_HI); *seconds = *seconds << 16 | - lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_SEC_LO); + lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_EGRESS_SEC_LO); - *nano_seconds = lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_NS_HI); + *nano_seconds = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_EGRESS_NS_HI); *nano_seconds = ((*nano_seconds & 0x3fff) << 16) | - lanphy_read_page_reg(phydev, 5, PTP_TX_EGRESS_NS_LO); + lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_EGRESS_NS_LO); - *seq_id = lanphy_read_page_reg(phydev, 5, PTP_TX_MSG_HEADER2); + *seq_id = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_MSG_HEADER2); } static int lan8814_ts_info(struct mii_timestamper *mii_ts, struct kernel_ethtool_ts_info *info) @@ -2912,11 +3016,11 @@ static void lan8814_flush_fifo(struct phy_device *phydev, bool egress) int i; for (i = 0; i < FIFO_SIZE; ++i) - lanphy_read_page_reg(phydev, 5, + lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, egress ? PTP_TX_MSG_HEADER2 : PTP_RX_MSG_HEADER2); /* Read to clear overflow status bit */ - lanphy_read_page_reg(phydev, 5, PTP_TSU_INT_STS); + lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TSU_INT_STS); } static int lan8814_hwtstamp(struct mii_timestamper *mii_ts, @@ -2928,7 +3032,6 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts, struct lan8814_ptp_rx_ts *rx_ts, *tmp; int txcfg = 0, rxcfg = 0; int pkt_ts_enable; - int tx_mod; ptp_priv->hwts_tx_type = config->tx_type; ptp_priv->rx_filter = config->rx_filter; @@ -2967,21 +3070,28 @@ static int lan8814_hwtstamp(struct mii_timestamper *mii_ts, rxcfg |= PTP_RX_PARSE_CONFIG_IPV4_EN_ | PTP_RX_PARSE_CONFIG_IPV6_EN_; txcfg |= PTP_TX_PARSE_CONFIG_IPV4_EN_ | PTP_TX_PARSE_CONFIG_IPV6_EN_; } - lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_PARSE_CONFIG, rxcfg); - lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_PARSE_CONFIG, txcfg); + lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_PARSE_CONFIG, rxcfg); + lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_PARSE_CONFIG, txcfg); pkt_ts_enable = PTP_TIMESTAMP_EN_SYNC_ | PTP_TIMESTAMP_EN_DREQ_ | PTP_TIMESTAMP_EN_PDREQ_ | PTP_TIMESTAMP_EN_PDRES_; - lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_TIMESTAMP_EN, pkt_ts_enable); - lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_TIMESTAMP_EN, pkt_ts_enable); + lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_TIMESTAMP_EN, pkt_ts_enable); + lanphy_write_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_TIMESTAMP_EN, pkt_ts_enable); - tx_mod = lanphy_read_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD); if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ONESTEP_SYNC) { - lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD, - tx_mod | PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_); + lanphy_modify_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_MOD, + PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_, + PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_); } else if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ON) { - lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD, - tx_mod & ~PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_); + lanphy_modify_page_reg(ptp_priv->phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_MOD, + PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_, + 0); } if (config->rx_filter != HWTSTAMP_FILTER_NONE) @@ -3103,29 +3213,41 @@ static bool lan8814_rxtstamp(struct mii_timestamper *mii_ts, struct sk_buff *skb static void lan8814_ptp_clock_set(struct phy_device *phydev, time64_t sec, u32 nsec) { - lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_LO, lower_16_bits(sec)); - lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_MID, upper_16_bits(sec)); - lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_SEC_HI, upper_32_bits(sec)); - lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_NS_LO, lower_16_bits(nsec)); - lanphy_write_page_reg(phydev, 4, PTP_CLOCK_SET_NS_HI, upper_16_bits(nsec)); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_SET_SEC_LO, lower_16_bits(sec)); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_SET_SEC_MID, upper_16_bits(sec)); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_SET_SEC_HI, upper_32_bits(sec)); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_SET_NS_LO, lower_16_bits(nsec)); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_SET_NS_HI, upper_16_bits(nsec)); - lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_CLOCK_LOAD_); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL, + PTP_CMD_CTL_PTP_CLOCK_LOAD_); } static void lan8814_ptp_clock_get(struct phy_device *phydev, time64_t *sec, u32 *nsec) { - lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_CLOCK_READ_); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL, + PTP_CMD_CTL_PTP_CLOCK_READ_); - *sec = lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_HI); + *sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_READ_SEC_HI); *sec <<= 16; - *sec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_MID); + *sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_READ_SEC_MID); *sec <<= 16; - *sec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_SEC_LO); + *sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_READ_SEC_LO); - *nsec = lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_NS_HI); + *nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_READ_NS_HI); *nsec <<= 16; - *nsec |= lanphy_read_page_reg(phydev, 4, PTP_CLOCK_READ_NS_LO); + *nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CLOCK_READ_NS_LO); } static int lan8814_ptpci_gettime64(struct ptp_clock_info *ptpci, @@ -3164,14 +3286,18 @@ static void lan8814_ptp_set_target(struct phy_device *phydev, int event, s64 start_sec, u32 start_nsec) { /* Set the start time */ - lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_SEC_LO(event), + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_PTP_CLOCK_TARGET_SEC_LO(event), lower_16_bits(start_sec)); - lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_SEC_HI(event), + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_PTP_CLOCK_TARGET_SEC_HI(event), upper_16_bits(start_sec)); - lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_NS_LO(event), + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_PTP_CLOCK_TARGET_NS_LO(event), lower_16_bits(start_nsec)); - lanphy_write_page_reg(phydev, 4, LAN8814_PTP_CLOCK_TARGET_NS_HI(event), + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_PTP_CLOCK_TARGET_NS_HI(event), upper_16_bits(start_nsec) & 0x3fff); } @@ -3269,9 +3395,11 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev, adjustment_value_lo = adjustment_value & 0xffff; adjustment_value_hi = (adjustment_value >> 16) & 0x3fff; - lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_LTC_STEP_ADJ_LO, adjustment_value_lo); - lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_LTC_STEP_ADJ_HI, PTP_LTC_STEP_ADJ_DIR_ | adjustment_value_hi); seconds -= ((s32)adjustment_value); @@ -3289,9 +3417,11 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev, adjustment_value_lo = adjustment_value & 0xffff; adjustment_value_hi = (adjustment_value >> 16) & 0x3fff; - lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_LTC_STEP_ADJ_LO, adjustment_value_lo); - lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_LTC_STEP_ADJ_HI, adjustment_value_hi); seconds += ((s32)adjustment_value); @@ -3299,8 +3429,8 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev, set_seconds += adjustment_value; lan8814_ptp_update_target(phydev, set_seconds); } - lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, - PTP_CMD_CTL_PTP_LTC_STEP_SEC_); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_CMD_CTL, PTP_CMD_CTL_PTP_LTC_STEP_SEC_); } if (nano_seconds) { u16 nano_seconds_lo; @@ -3309,12 +3439,14 @@ static void lan8814_ptp_clock_step(struct phy_device *phydev, nano_seconds_lo = nano_seconds & 0xffff; nano_seconds_hi = (nano_seconds >> 16) & 0x3fff; - lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_LO, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_LTC_STEP_ADJ_LO, nano_seconds_lo); - lanphy_write_page_reg(phydev, 4, PTP_LTC_STEP_ADJ_HI, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_LTC_STEP_ADJ_HI, PTP_LTC_STEP_ADJ_DIR_ | nano_seconds_hi); - lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL, PTP_CMD_CTL_PTP_LTC_STEP_NSEC_); } } @@ -3356,8 +3488,10 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm) kszphy_rate_adj_hi |= PTP_CLOCK_RATE_ADJ_DIR_; mutex_lock(&shared->shared_lock); - lanphy_write_page_reg(phydev, 4, PTP_CLOCK_RATE_ADJ_HI, kszphy_rate_adj_hi); - lanphy_write_page_reg(phydev, 4, PTP_CLOCK_RATE_ADJ_LO, kszphy_rate_adj_lo); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CLOCK_RATE_ADJ_HI, + kszphy_rate_adj_hi); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CLOCK_RATE_ADJ_LO, + kszphy_rate_adj_lo); mutex_unlock(&shared->shared_lock); return 0; @@ -3366,17 +3500,17 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm) static void lan8814_ptp_set_reload(struct phy_device *phydev, int event, s64 period_sec, u32 period_nsec) { - lanphy_write_page_reg(phydev, 4, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_LO(event), lower_16_bits(period_sec)); - lanphy_write_page_reg(phydev, 4, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_CLOCK_TARGET_RELOAD_SEC_HI(event), upper_16_bits(period_sec)); - lanphy_write_page_reg(phydev, 4, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_LO(event), lower_16_bits(period_nsec)); - lanphy_write_page_reg(phydev, 4, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_CLOCK_TARGET_RELOAD_NS_HI(event), upper_16_bits(period_nsec) & 0x3fff); } @@ -3384,73 +3518,72 @@ static void lan8814_ptp_set_reload(struct phy_device *phydev, int event, static void lan8814_ptp_enable_event(struct phy_device *phydev, int event, int pulse_width) { - u16 val; - - val = lanphy_read_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG); - /* Set the pulse width of the event */ - val &= ~(LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_MASK(event)); - /* Make sure that the target clock will be incremented each time when + /* Set the pulse width of the event, + * Make sure that the target clock will be incremented each time when * local time reaches or pass it + * Set the polarity high */ - val |= LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width); - val &= ~(LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event)); - /* Set the polarity high */ - val |= LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event); - lanphy_write_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG, val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_GENERAL_CONFIG, + LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_MASK(event) | + LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width) | + LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event) | + LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event), + LAN8814_PTP_GENERAL_CONFIG_LTC_EVENT_SET(event, pulse_width) | + LAN8814_PTP_GENERAL_CONFIG_POLARITY_X(event)); } static void lan8814_ptp_disable_event(struct phy_device *phydev, int event) { - u16 val; - /* Set target to too far in the future, effectively disabling it */ lan8814_ptp_set_target(phydev, event, 0xFFFFFFFF, 0); /* And then reload once it recheas the target */ - val = lanphy_read_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG); - val |= LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event); - lanphy_write_page_reg(phydev, 4, LAN8814_PTP_GENERAL_CONFIG, val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_PTP_GENERAL_CONFIG, + LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event), + LAN8814_PTP_GENERAL_CONFIG_RELOAD_ADD_X(event)); } static void lan8814_ptp_perout_off(struct phy_device *phydev, int pin) { - u16 val; - /* Disable gpio alternate function, * 1: select as gpio, * 0: select alt func */ - val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin)); - val |= LAN8814_GPIO_EN_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_EN_ADDR(pin), + LAN8814_GPIO_EN_BIT(pin), + LAN8814_GPIO_EN_BIT(pin)); - val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin)); - val &= ~LAN8814_GPIO_DIR_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_DIR_ADDR(pin), + LAN8814_GPIO_DIR_BIT(pin), + 0); - val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin)); - val &= ~LAN8814_GPIO_BUF_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin), val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_BUF_ADDR(pin), + LAN8814_GPIO_BUF_BIT(pin), + 0); } static void lan8814_ptp_perout_on(struct phy_device *phydev, int pin) { - int val; - /* Set as gpio output */ - val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin)); - val |= LAN8814_GPIO_DIR_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_DIR_ADDR(pin), + LAN8814_GPIO_DIR_BIT(pin), + LAN8814_GPIO_DIR_BIT(pin)); /* Enable gpio 0:for alternate function, 1:gpio */ - val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin)); - val &= ~LAN8814_GPIO_EN_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_EN_ADDR(pin), + LAN8814_GPIO_EN_BIT(pin), + 0); /* Set buffer type to push pull */ - val = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin)); - val |= LAN8814_GPIO_BUF_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_BUF_ADDR(pin), val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_BUF_ADDR(pin), + LAN8814_GPIO_BUF_BIT(pin), + LAN8814_GPIO_BUF_BIT(pin)); } static int lan8814_ptp_perout(struct ptp_clock_info *ptpci, @@ -3565,61 +3698,64 @@ static int lan8814_ptp_perout(struct ptp_clock_info *ptpci, static void lan8814_ptp_extts_on(struct phy_device *phydev, int pin, u32 flags) { - u16 tmp; - /* Set as gpio input */ - tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin)); - tmp &= ~LAN8814_GPIO_DIR_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_DIR_ADDR(pin), + LAN8814_GPIO_DIR_BIT(pin), + 0); /* Map the pin to ltc pin 0 of the capture map registers */ - tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO); - tmp |= pin; - lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO, tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_CAP_MAP_LO, pin, pin); /* Enable capture on the edges of the ltc pin */ - tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_EN); if (flags & PTP_RISING_EDGE) - tmp |= PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_CAP_EN, + PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0), + PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(0)); if (flags & PTP_FALLING_EDGE) - tmp |= PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0); - lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_EN, tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_CAP_EN, + PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0), + PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(0)); /* Enable interrupt top interrupt */ - tmp = lanphy_read_page_reg(phydev, 4, PTP_COMMON_INT_ENA); - tmp |= PTP_COMMON_INT_ENA_GPIO_CAP_EN; - lanphy_write_page_reg(phydev, 4, PTP_COMMON_INT_ENA, tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_COMMON_INT_ENA, + PTP_COMMON_INT_ENA_GPIO_CAP_EN, + PTP_COMMON_INT_ENA_GPIO_CAP_EN); } static void lan8814_ptp_extts_off(struct phy_device *phydev, int pin) { - u16 tmp; - /* Set as gpio out */ - tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin)); - tmp |= LAN8814_GPIO_DIR_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_DIR_ADDR(pin), tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_DIR_ADDR(pin), + LAN8814_GPIO_DIR_BIT(pin), + LAN8814_GPIO_DIR_BIT(pin)); /* Enable alternate, 0:for alternate function, 1:gpio */ - tmp = lanphy_read_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin)); - tmp &= ~LAN8814_GPIO_EN_BIT(pin); - lanphy_write_page_reg(phydev, 4, LAN8814_GPIO_EN_ADDR(pin), tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_EN_ADDR(pin), + LAN8814_GPIO_EN_BIT(pin), + 0); /* Clear the mapping of pin to registers 0 of the capture registers */ - tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO); - tmp &= ~GENMASK(3, 0); - lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_MAP_LO, tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_CAP_MAP_LO, + GENMASK(3, 0), + 0); /* Disable capture on both of the edges */ - tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_EN); - tmp &= ~PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin); - tmp &= ~PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin); - lanphy_write_page_reg(phydev, 4, PTP_GPIO_CAP_EN, tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_GPIO_CAP_EN, + PTP_GPIO_CAP_EN_GPIO_RE_CAPTURE_ENABLE(pin) | + PTP_GPIO_CAP_EN_GPIO_FE_CAPTURE_ENABLE(pin), + 0); /* Disable interrupt top interrupt */ - tmp = lanphy_read_page_reg(phydev, 4, PTP_COMMON_INT_ENA); - tmp &= ~PTP_COMMON_INT_ENA_GPIO_CAP_EN; - lanphy_write_page_reg(phydev, 4, PTP_COMMON_INT_ENA, tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_COMMON_INT_ENA, + PTP_COMMON_INT_ENA_GPIO_CAP_EN, + 0); } static int lan8814_ptp_extts(struct ptp_clock_info *ptpci, @@ -3749,7 +3885,8 @@ static void lan8814_get_tx_ts(struct kszphy_ptp_priv *ptp_priv) /* If other timestamps are available in the FIFO, * process them. */ - reg = lanphy_read_page_reg(phydev, 5, PTP_CAP_INFO); + reg = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_CAP_INFO); } while (PTP_CAP_INFO_TX_TS_CNT_GET_(reg) > 0); } @@ -3822,7 +3959,8 @@ static void lan8814_get_rx_ts(struct kszphy_ptp_priv *ptp_priv) /* If other timestamps are available in the FIFO, * process them. */ - reg = lanphy_read_page_reg(phydev, 5, PTP_CAP_INFO); + reg = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_CAP_INFO); } while (PTP_CAP_INFO_RX_TS_CNT_GET_(reg) > 0); } @@ -3859,31 +3997,40 @@ static int lan8814_gpio_process_cap(struct lan8814_shared_priv *shared) /* This is 0 because whatever was the input pin it was mapped it to * ltc gpio pin 0 */ - tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_SEL); - tmp |= PTP_GPIO_SEL_GPIO_SEL(0); - lanphy_write_page_reg(phydev, 4, PTP_GPIO_SEL, tmp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_GPIO_SEL, + PTP_GPIO_SEL_GPIO_SEL(0), + PTP_GPIO_SEL_GPIO_SEL(0)); - tmp = lanphy_read_page_reg(phydev, 4, PTP_GPIO_CAP_STS); + tmp = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_CAP_STS); if (!(tmp & PTP_GPIO_CAP_STS_PTP_GPIO_RE_STS(0)) && !(tmp & PTP_GPIO_CAP_STS_PTP_GPIO_FE_STS(0))) return -1; if (tmp & BIT(0)) { - sec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_SEC_HI_CAP); + sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_RE_LTC_SEC_HI_CAP); sec <<= 16; - sec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_SEC_LO_CAP); + sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_RE_LTC_SEC_LO_CAP); - nsec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_HI_CAP) & 0x3fff; + nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_RE_LTC_NS_HI_CAP) & 0x3fff; nsec <<= 16; - nsec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_LO_CAP); + nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_RE_LTC_NS_LO_CAP); } else { - sec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_SEC_HI_CAP); + sec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_FE_LTC_SEC_HI_CAP); sec <<= 16; - sec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_SEC_LO_CAP); + sec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_FE_LTC_SEC_LO_CAP); - nsec = lanphy_read_page_reg(phydev, 4, PTP_GPIO_FE_LTC_NS_HI_CAP) & 0x3fff; + nsec = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_FE_LTC_NS_HI_CAP) & 0x3fff; nsec <<= 16; - nsec |= lanphy_read_page_reg(phydev, 4, PTP_GPIO_RE_LTC_NS_LO_CAP); + nsec |= lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + PTP_GPIO_RE_LTC_NS_LO_CAP); } ptp_event.index = 0; @@ -3908,19 +4055,17 @@ static int lan8814_handle_gpio_interrupt(struct phy_device *phydev, u16 status) static int lan8804_config_init(struct phy_device *phydev) { - int val; - /* MDI-X setting for swap A,B transmit */ - val = lanphy_read_page_reg(phydev, 2, LAN8804_ALIGN_SWAP); - val &= ~LAN8804_ALIGN_TX_A_B_SWAP_MASK; - val |= LAN8804_ALIGN_TX_A_B_SWAP; - lanphy_write_page_reg(phydev, 2, LAN8804_ALIGN_SWAP, val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8804_ALIGN_SWAP, + LAN8804_ALIGN_TX_A_B_SWAP_MASK, + LAN8804_ALIGN_TX_A_B_SWAP); /* Make sure that the PHY will not stop generating the clock when the * link partner goes down */ - lanphy_write_page_reg(phydev, 31, LAN8814_CLOCK_MANAGEMENT, 0x27e); - lanphy_read_page_reg(phydev, 1, LAN8814_LINK_QUALITY); + lanphy_write_page_reg(phydev, LAN8814_PAGE_SYSTEM_CTRL, + LAN8814_CLOCK_MANAGEMENT, 0x27e); + lanphy_read_page_reg(phydev, LAN8814_PAGE_AFE_PMA, LAN8814_LINK_QUALITY); return 0; } @@ -4002,7 +4147,8 @@ static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev) } while (true) { - irq_status = lanphy_read_page_reg(phydev, 5, PTP_TSU_INT_STS); + irq_status = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TSU_INT_STS); if (!irq_status) break; @@ -4030,7 +4176,7 @@ static int lan8814_config_intr(struct phy_device *phydev) { int err; - lanphy_write_page_reg(phydev, 4, LAN8814_INTR_CTRL_REG, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, LAN8814_INTR_CTRL_REG, LAN8814_INTR_CTRL_REG_POLARITY | LAN8814_INTR_CTRL_REG_INTR_ENABLE); @@ -4056,35 +4202,41 @@ static void lan8814_ptp_init(struct phy_device *phydev) { struct kszphy_priv *priv = phydev->priv; struct kszphy_ptp_priv *ptp_priv = &priv->ptp_priv; - u32 temp; if (!IS_ENABLED(CONFIG_PTP_1588_CLOCK) || !IS_ENABLED(CONFIG_NETWORK_PHY_TIMESTAMPING)) return; - lanphy_write_page_reg(phydev, 5, TSU_HARD_RESET, TSU_HARD_RESET_); + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + TSU_HARD_RESET, TSU_HARD_RESET_); - temp = lanphy_read_page_reg(phydev, 5, PTP_TX_MOD); - temp |= PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_; - lanphy_write_page_reg(phydev, 5, PTP_TX_MOD, temp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TX_MOD, + PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_, + PTP_TX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_); - temp = lanphy_read_page_reg(phydev, 5, PTP_RX_MOD); - temp |= PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_; - lanphy_write_page_reg(phydev, 5, PTP_RX_MOD, temp); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_RX_MOD, + PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_, + PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_); - lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_CONFIG, 0); - lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_CONFIG, 0); + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_PARSE_CONFIG, 0); + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_PARSE_CONFIG, 0); /* Removing default registers configs related to L2 and IP */ - lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_L2_ADDR_EN, 0); - lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_L2_ADDR_EN, 0); - lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_IP_ADDR_EN, 0); - lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_IP_ADDR_EN, 0); + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_PARSE_L2_ADDR_EN, 0); + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_PARSE_L2_ADDR_EN, 0); + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TX_PARSE_IP_ADDR_EN, 0); + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_RX_PARSE_IP_ADDR_EN, 0); /* Disable checking for minorVersionPTP field */ - lanphy_write_page_reg(phydev, 5, PTP_RX_VERSION, + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_RX_VERSION, PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0)); - lanphy_write_page_reg(phydev, 5, PTP_TX_VERSION, + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, PTP_TX_VERSION, PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0)); skb_queue_head_init(&ptp_priv->tx_queue); @@ -4105,7 +4257,8 @@ static void lan8814_ptp_init(struct phy_device *phydev) phydev->default_timestamp = true; } -static int lan8814_ptp_probe_once(struct phy_device *phydev) +static int __lan8814_ptp_probe_once(struct phy_device *phydev, char *pin_name, + int gpios) { struct lan8814_shared_priv *shared = phy_package_get_priv(phydev); @@ -4113,18 +4266,18 @@ static int lan8814_ptp_probe_once(struct phy_device *phydev) mutex_init(&shared->shared_lock); shared->pin_config = devm_kmalloc_array(&phydev->mdio.dev, - LAN8814_PTP_GPIO_NUM, + gpios, sizeof(*shared->pin_config), GFP_KERNEL); if (!shared->pin_config) return -ENOMEM; - for (int i = 0; i < LAN8814_PTP_GPIO_NUM; i++) { + for (int i = 0; i < gpios; i++) { struct ptp_pin_desc *ptp_pin = &shared->pin_config[i]; memset(ptp_pin, 0, sizeof(*ptp_pin)); snprintf(ptp_pin->name, - sizeof(ptp_pin->name), "lan8814_ptp_pin_%02d", i); + sizeof(ptp_pin->name), "%s_%02d", pin_name, i); ptp_pin->index = i; ptp_pin->func = PTP_PF_NONE; } @@ -4134,7 +4287,7 @@ static int lan8814_ptp_probe_once(struct phy_device *phydev) shared->ptp_clock_info.max_adj = 31249999; shared->ptp_clock_info.n_alarm = 0; shared->ptp_clock_info.n_ext_ts = LAN8814_PTP_EXTTS_NUM; - shared->ptp_clock_info.n_pins = LAN8814_PTP_GPIO_NUM; + shared->ptp_clock_info.n_pins = gpios; shared->ptp_clock_info.pps = 0; shared->ptp_clock_info.supported_extts_flags = PTP_RISING_EDGE | PTP_FALLING_EDGE | @@ -4153,8 +4306,8 @@ static int lan8814_ptp_probe_once(struct phy_device *phydev) shared->ptp_clock = ptp_clock_register(&shared->ptp_clock_info, &phydev->mdio.dev); if (IS_ERR(shared->ptp_clock)) { - phydev_err(phydev, "ptp_clock_register failed %lu\n", - PTR_ERR(shared->ptp_clock)); + phydev_err(phydev, "ptp_clock_register failed %pe\n", + shared->ptp_clock); return -EINVAL; } @@ -4169,50 +4322,60 @@ static int lan8814_ptp_probe_once(struct phy_device *phydev) /* The EP.4 is shared between all the PHYs in the package and also it * can be accessed by any of the PHYs */ - lanphy_write_page_reg(phydev, 4, LTC_HARD_RESET, LTC_HARD_RESET_); - lanphy_write_page_reg(phydev, 4, PTP_OPERATING_MODE, + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LTC_HARD_RESET, LTC_HARD_RESET_); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_OPERATING_MODE, PTP_OPERATING_MODE_STANDALONE_); /* Enable ptp to run LTC clock for ptp and gpio 1PPS operation */ - lanphy_write_page_reg(phydev, 4, PTP_CMD_CTL, PTP_CMD_CTL_PTP_ENABLE_); + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, PTP_CMD_CTL, + PTP_CMD_CTL_PTP_ENABLE_); return 0; } +static int lan8814_ptp_probe_once(struct phy_device *phydev) +{ + return __lan8814_ptp_probe_once(phydev, "lan8814_ptp_pin", + LAN8814_PTP_GPIO_NUM); +} + static void lan8814_setup_led(struct phy_device *phydev, int val) { int temp; - temp = lanphy_read_page_reg(phydev, 5, LAN8814_LED_CTRL_1); + temp = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + LAN8814_LED_CTRL_1); if (val) temp |= LAN8814_LED_CTRL_1_KSZ9031_LED_MODE_; else temp &= ~LAN8814_LED_CTRL_1_KSZ9031_LED_MODE_; - lanphy_write_page_reg(phydev, 5, LAN8814_LED_CTRL_1, temp); + lanphy_write_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + LAN8814_LED_CTRL_1, temp); } static int lan8814_config_init(struct phy_device *phydev) { struct kszphy_priv *lan8814 = phydev->priv; - int val; /* Reset the PHY */ - val = lanphy_read_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET); - val |= LAN8814_QSGMII_SOFT_RESET_BIT; - lanphy_write_page_reg(phydev, 4, LAN8814_QSGMII_SOFT_RESET, val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_QSGMII_SOFT_RESET, + LAN8814_QSGMII_SOFT_RESET_BIT, + LAN8814_QSGMII_SOFT_RESET_BIT); /* Disable ANEG with QSGMII PCS Host side */ - val = lanphy_read_page_reg(phydev, 5, LAN8814_QSGMII_PCS1G_ANEG_CONFIG); - val &= ~LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA; - lanphy_write_page_reg(phydev, 5, LAN8814_QSGMII_PCS1G_ANEG_CONFIG, val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + LAN8814_QSGMII_PCS1G_ANEG_CONFIG, + LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA, + 0); /* MDI-X setting for swap A,B transmit */ - val = lanphy_read_page_reg(phydev, 2, LAN8814_ALIGN_SWAP); - val &= ~LAN8814_ALIGN_TX_A_B_SWAP_MASK; - val |= LAN8814_ALIGN_TX_A_B_SWAP; - lanphy_write_page_reg(phydev, 2, LAN8814_ALIGN_SWAP, val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8814_ALIGN_SWAP, + LAN8814_ALIGN_TX_A_B_SWAP_MASK, + LAN8814_ALIGN_TX_A_B_SWAP); if (lan8814->led_mode >= 0) lan8814_setup_led(phydev, lan8814->led_mode); @@ -4243,29 +4406,24 @@ static int lan8814_release_coma_mode(struct phy_device *phydev) static void lan8814_clear_2psp_bit(struct phy_device *phydev) { - u16 val; - /* It was noticed that when traffic is passing through the PHY and the * cable is removed then the LED was still one even though there is no * link */ - val = lanphy_read_page_reg(phydev, 2, LAN8814_EEE_STATE); - val &= ~LAN8814_EEE_STATE_MASK2P5P; - lanphy_write_page_reg(phydev, 2, LAN8814_EEE_STATE, val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, LAN8814_EEE_STATE, + LAN8814_EEE_STATE_MASK2P5P, + 0); } static void lan8814_update_meas_time(struct phy_device *phydev) { - u16 val; - /* By setting the measure time to a value of 0xb this will allow cables * longer than 100m to be used. This configuration can be used * regardless of the mode of operation of the PHY */ - val = lanphy_read_page_reg(phydev, 1, LAN8814_PD_CONTROLS); - val &= ~LAN8814_PD_CONTROLS_PD_MEAS_TIME_MASK; - val |= LAN8814_PD_CONTROLS_PD_MEAS_TIME_VAL; - lanphy_write_page_reg(phydev, 1, LAN8814_PD_CONTROLS, val); + lanphy_modify_page_reg(phydev, LAN8814_PAGE_AFE_PMA, LAN8814_PD_CONTROLS, + LAN8814_PD_CONTROLS_PD_MEAS_TIME_MASK, + LAN8814_PD_CONTROLS_PD_MEAS_TIME_VAL); } static int lan8814_probe(struct phy_device *phydev) @@ -4288,7 +4446,7 @@ static int lan8814_probe(struct phy_device *phydev) /* Strap-in value for PHY address, below register read gives starting * phy address value */ - addr = lanphy_read_page_reg(phydev, 4, 0) & 0x1F; + addr = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, 0) & 0x1F; devm_phy_package_join(&phydev->mdio.dev, phydev, addr, sizeof(struct lan8814_shared_priv)); @@ -5582,8 +5740,8 @@ static int lan8841_probe(struct phy_device *phydev) ptp_priv->ptp_clock = ptp_clock_register(&ptp_priv->ptp_clock_info, &phydev->mdio.dev); if (IS_ERR(ptp_priv->ptp_clock)) { - phydev_err(phydev, "ptp_clock_register failed: %lu\n", - PTR_ERR(ptp_priv->ptp_clock)); + phydev_err(phydev, "ptp_clock_register failed: %pe\n", + ptp_priv->ptp_clock); return -EINVAL; } @@ -5643,10 +5801,367 @@ static int ksz9131_resume(struct phy_device *phydev) return kszphy_resume(phydev); } +#define LAN8842_PTP_GPIO_NUM 16 + +static int lan8842_ptp_probe_once(struct phy_device *phydev) +{ + return __lan8814_ptp_probe_once(phydev, "lan8842_ptp_pin", + LAN8842_PTP_GPIO_NUM); +} + +#define LAN8842_STRAP_REG 0 /* 0x0 */ +#define LAN8842_STRAP_REG_PHYADDR_MASK GENMASK(4, 0) +#define LAN8842_SKU_REG 11 /* 0x0b */ +#define LAN8842_SELF_TEST 14 /* 0x0e */ +#define LAN8842_SELF_TEST_RX_CNT_ENA BIT(8) +#define LAN8842_SELF_TEST_TX_CNT_ENA BIT(4) + +static int lan8842_probe(struct phy_device *phydev) +{ + struct lan8842_priv *priv; + int addr; + int ret; + + priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + phydev->priv = priv; + + /* Similar to lan8814 this PHY has a pin which needs to be pulled down + * to enable to pass any traffic through it. Therefore use the same + * function as lan8814 + */ + ret = lan8814_release_coma_mode(phydev); + if (ret) + return ret; + + /* Enable to count the RX and TX packets */ + ret = lanphy_write_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, + LAN8842_SELF_TEST, + LAN8842_SELF_TEST_RX_CNT_ENA | + LAN8842_SELF_TEST_TX_CNT_ENA); + if (ret < 0) + return ret; + + /* Revision lan8832 doesn't have support for PTP, therefore don't add + * any PTP clocks + */ + ret = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8842_SKU_REG); + if (ret < 0) + return ret; + + priv->rev = ret; + if (priv->rev == LAN8842_REV_8832) + return 0; + + /* As the lan8814 and lan8842 has the same IP for the PTP block, the + * only difference is the number of the GPIOs, then make sure that the + * lan8842 initialized also the shared data pointer as this is used in + * all the PTP functions for lan8814. The lan8842 doesn't have multiple + * PHYs in the same package. + */ + addr = lanphy_read_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8842_STRAP_REG); + if (addr < 0) + return addr; + addr &= LAN8842_STRAP_REG_PHYADDR_MASK; + + ret = devm_phy_package_join(&phydev->mdio.dev, phydev, addr, + sizeof(struct lan8814_shared_priv)); + if (ret) + return ret; + + if (phy_package_init_once(phydev)) { + ret = lan8842_ptp_probe_once(phydev); + if (ret) + return ret; + } + + lan8814_ptp_init(phydev); + + return 0; +} + +static int lan8842_config_init(struct phy_device *phydev) +{ + int ret; + + /* Reset the PHY */ + ret = lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_QSGMII_SOFT_RESET, + LAN8814_QSGMII_SOFT_RESET_BIT, + LAN8814_QSGMII_SOFT_RESET_BIT); + if (ret < 0) + return ret; + + /* Even if the GPIOs are set to control the LEDs the behaviour of the + * LEDs is wrong, they are not blinking when there is traffic. + * To fix this it is required to set extended LED mode + */ + ret = lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + LAN8814_LED_CTRL_1, + LAN8814_LED_CTRL_1_KSZ9031_LED_MODE_, 0); + if (ret < 0) + return ret; + + ret = lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + LAN8814_LED_CTRL_2, + LAN8814_LED_CTRL_2_LED1_COM_DIS, + LAN8814_LED_CTRL_2_LED1_COM_DIS); + if (ret < 0) + return ret; + + /* To allow the PHY to control the LEDs the GPIOs of the PHY should have + * a function mode and not the GPIO. Apparently by default the value is + * GPIO and not function even though the datasheet it says that it is + * function. Therefore set this value. + */ + return lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8814_GPIO_EN2, 0); +} + +#define LAN8842_INTR_CTRL_REG 52 /* 0x34 */ + +static int lan8842_config_intr(struct phy_device *phydev) +{ + int err; + + lanphy_write_page_reg(phydev, LAN8814_PAGE_COMMON_REGS, + LAN8842_INTR_CTRL_REG, + LAN8814_INTR_CTRL_REG_INTR_ENABLE); + + /* enable / disable interrupts */ + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { + err = lan8814_ack_interrupt(phydev); + if (err) + return err; + + err = phy_write(phydev, LAN8814_INTC, + LAN8814_INT_LINK | LAN8814_INT_FLF); + } else { + err = phy_write(phydev, LAN8814_INTC, 0); + if (err) + return err; + + err = lan8814_ack_interrupt(phydev); + } + + return err; +} + +static unsigned int lan8842_inband_caps(struct phy_device *phydev, + phy_interface_t interface) +{ + /* Inband configuration can be enabled or disabled using the registers + * PCS1G_ANEG_CONFIG. + */ + return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; +} + +static int lan8842_config_inband(struct phy_device *phydev, unsigned int modes) +{ + bool enable; + + if (modes == LINK_INBAND_DISABLE) + enable = false; + else + enable = true; + + /* Disable or enable in-band autoneg with PCS Host side + * It has the same address as lan8814 + */ + return lanphy_modify_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + LAN8814_QSGMII_PCS1G_ANEG_CONFIG, + LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA, + enable ? LAN8814_QSGMII_PCS1G_ANEG_CONFIG_ANEG_ENA : 0); +} + +static void lan8842_handle_ptp_interrupt(struct phy_device *phydev, u16 status) +{ + struct kszphy_ptp_priv *ptp_priv; + struct lan8842_priv *priv; + + priv = phydev->priv; + ptp_priv = &priv->ptp_priv; + + if (status & PTP_TSU_INT_STS_PTP_TX_TS_EN_) + lan8814_get_tx_ts(ptp_priv); + + if (status & PTP_TSU_INT_STS_PTP_RX_TS_EN_) + lan8814_get_rx_ts(ptp_priv); + + if (status & PTP_TSU_INT_STS_PTP_TX_TS_OVRFL_INT_) { + lan8814_flush_fifo(phydev, true); + skb_queue_purge(&ptp_priv->tx_queue); + } + + if (status & PTP_TSU_INT_STS_PTP_RX_TS_OVRFL_INT_) { + lan8814_flush_fifo(phydev, false); + skb_queue_purge(&ptp_priv->rx_queue); + } +} + +static irqreturn_t lan8842_handle_interrupt(struct phy_device *phydev) +{ + struct lan8842_priv *priv = phydev->priv; + int ret = IRQ_NONE; + int irq_status; + + irq_status = phy_read(phydev, LAN8814_INTS); + if (irq_status < 0) { + phy_error(phydev); + return IRQ_NONE; + } + + if (irq_status & (LAN8814_INT_LINK | LAN8814_INT_FLF)) { + phy_trigger_machine(phydev); + ret = IRQ_HANDLED; + } + + /* Phy revision lan8832 doesn't have support for PTP therefore there is + * not need to check the PTP and GPIO interrupts + */ + if (priv->rev == LAN8842_REV_8832) + goto out; + + while (true) { + irq_status = lanphy_read_page_reg(phydev, LAN8814_PAGE_PORT_REGS, + PTP_TSU_INT_STS); + if (!irq_status) + break; + + lan8842_handle_ptp_interrupt(phydev, irq_status); + ret = IRQ_HANDLED; + } + + if (!lan8814_handle_gpio_interrupt(phydev, irq_status)) + ret = IRQ_HANDLED; + +out: + return ret; +} + +static u64 lan8842_get_stat(struct phy_device *phydev, int count, int *regs) +{ + u64 ret = 0; + int val; + + for (int j = 0; j < count; ++j) { + val = lanphy_read_page_reg(phydev, LAN8814_PAGE_PCS_DIGITAL, + regs[j]); + if (val < 0) + return U64_MAX; + + ret <<= 16; + ret += val; + } + return ret; +} + +static int lan8842_update_stats(struct phy_device *phydev) +{ + struct lan8842_priv *priv = phydev->priv; + int rx_packets_regs[] = {88, 61, 60}; + int rx_errors_regs[] = {63, 62}; + int tx_packets_regs[] = {89, 85, 84}; + int tx_errors_regs[] = {87, 86}; + + priv->phy_stats.rx_packets = lan8842_get_stat(phydev, + ARRAY_SIZE(rx_packets_regs), + rx_packets_regs); + priv->phy_stats.rx_errors = lan8842_get_stat(phydev, + ARRAY_SIZE(rx_errors_regs), + rx_errors_regs); + priv->phy_stats.tx_packets = lan8842_get_stat(phydev, + ARRAY_SIZE(tx_packets_regs), + tx_packets_regs); + priv->phy_stats.tx_errors = lan8842_get_stat(phydev, + ARRAY_SIZE(tx_errors_regs), + tx_errors_regs); + + return 0; +} + +#define LAN8842_FLF 15 /* 0x0e */ +#define LAN8842_FLF_ENA BIT(1) +#define LAN8842_FLF_ENA_LINK_DOWN BIT(0) + +static int lan8842_get_fast_down(struct phy_device *phydev, u8 *msecs) +{ + int ret; + + ret = lanphy_read_page_reg(phydev, LAN8814_PAGE_PCS, LAN8842_FLF); + if (ret < 0) + return ret; + + if (ret & LAN8842_FLF_ENA) + *msecs = ETHTOOL_PHY_FAST_LINK_DOWN_ON; + else + *msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF; + + return 0; +} + +static int lan8842_set_fast_down(struct phy_device *phydev, const u8 *msecs) +{ + u16 flf; + + switch (*msecs) { + case ETHTOOL_PHY_FAST_LINK_DOWN_OFF: + flf = 0; + break; + case ETHTOOL_PHY_FAST_LINK_DOWN_ON: + flf = LAN8842_FLF_ENA | LAN8842_FLF_ENA_LINK_DOWN; + break; + default: + return -EINVAL; + } + + return lanphy_modify_page_reg(phydev, LAN8814_PAGE_PCS, + LAN8842_FLF, + LAN8842_FLF_ENA | + LAN8842_FLF_ENA_LINK_DOWN, flf); +} + +static int lan8842_get_tunable(struct phy_device *phydev, + struct ethtool_tunable *tuna, void *data) +{ + switch (tuna->id) { + case ETHTOOL_PHY_FAST_LINK_DOWN: + return lan8842_get_fast_down(phydev, data); + default: + return -EOPNOTSUPP; + } +} + +static int lan8842_set_tunable(struct phy_device *phydev, + struct ethtool_tunable *tuna, const void *data) +{ + switch (tuna->id) { + case ETHTOOL_PHY_FAST_LINK_DOWN: + return lan8842_set_fast_down(phydev, data); + default: + return -EOPNOTSUPP; + } +} + +static void lan8842_get_phy_stats(struct phy_device *phydev, + struct ethtool_eth_phy_stats *eth_stats, + struct ethtool_phy_stats *stats) +{ + struct lan8842_priv *priv = phydev->priv; + + stats->rx_packets = priv->phy_stats.rx_packets; + stats->rx_errors = priv->phy_stats.rx_errors; + stats->tx_packets = priv->phy_stats.tx_packets; + stats->tx_errors = priv->phy_stats.tx_errors; +} + static struct phy_driver ksphy_driver[] = { { - .phy_id = PHY_ID_KS8737, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_KS8737), .name = "Micrel KS8737", /* PHY_BASIC_FEATURES */ .driver_data = &ks8737_type, @@ -5687,8 +6202,7 @@ static struct phy_driver ksphy_driver[] = { .suspend = kszphy_suspend, .resume = kszphy_resume, }, { - .phy_id = PHY_ID_KSZ8041, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_KSZ8041), .name = "Micrel KSZ8041", /* PHY_BASIC_FEATURES */ .driver_data = &ksz8041_type, @@ -5703,8 +6217,7 @@ static struct phy_driver ksphy_driver[] = { .suspend = ksz8041_suspend, .resume = ksz8041_resume, }, { - .phy_id = PHY_ID_KSZ8041RNLI, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_KSZ8041RNLI), .name = "Micrel KSZ8041RNLI", /* PHY_BASIC_FEATURES */ .driver_data = &ksz8041_type, @@ -5747,9 +6260,8 @@ static struct phy_driver ksphy_driver[] = { .suspend = kszphy_suspend, .resume = kszphy_resume, }, { - .phy_id = PHY_ID_KSZ8081, + PHY_ID_MATCH_MODEL(PHY_ID_KSZ8081), .name = "Micrel KSZ8081 or KSZ8091", - .phy_id_mask = MICREL_PHY_ID_MASK, .flags = PHY_POLL_CABLE_TEST, /* PHY_BASIC_FEATURES */ .driver_data = &ksz8081_type, @@ -5768,9 +6280,8 @@ static struct phy_driver ksphy_driver[] = { .cable_test_start = ksz886x_cable_test_start, .cable_test_get_status = ksz886x_cable_test_get_status, }, { - .phy_id = PHY_ID_KSZ8061, + PHY_ID_MATCH_MODEL(PHY_ID_KSZ8061), .name = "Micrel KSZ8061", - .phy_id_mask = MICREL_PHY_ID_MASK, /* PHY_BASIC_FEATURES */ .probe = kszphy_probe, .config_init = ksz8061_config_init, @@ -5798,8 +6309,7 @@ static struct phy_driver ksphy_driver[] = { .read_mmd = genphy_read_mmd_unsupported, .write_mmd = genphy_write_mmd_unsupported, }, { - .phy_id = PHY_ID_KSZ9031, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_KSZ9031), .name = "Micrel KSZ9031 Gigabit PHY", .flags = PHY_POLL_CABLE_TEST, .driver_data = &ksz9021_type, @@ -5819,8 +6329,7 @@ static struct phy_driver ksphy_driver[] = { .cable_test_get_status = ksz9x31_cable_test_get_status, .set_loopback = ksz9031_set_loopback, }, { - .phy_id = PHY_ID_LAN8814, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_LAN8814), .name = "Microchip INDY Gigabit Quad PHY", .flags = PHY_POLL_CABLE_TEST, .config_init = lan8814_config_init, @@ -5838,8 +6347,7 @@ static struct phy_driver ksphy_driver[] = { .cable_test_start = lan8814_cable_test_start, .cable_test_get_status = ksz886x_cable_test_get_status, }, { - .phy_id = PHY_ID_LAN8804, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_LAN8804), .name = "Microchip LAN966X Gigabit PHY", .config_init = lan8804_config_init, .driver_data = &ksz9021_type, @@ -5854,8 +6362,7 @@ static struct phy_driver ksphy_driver[] = { .config_intr = lan8804_config_intr, .handle_interrupt = lan8804_handle_interrupt, }, { - .phy_id = PHY_ID_LAN8841, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_LAN8841), .name = "Microchip LAN8841 Gigabit PHY", .flags = PHY_POLL_CABLE_TEST, .driver_data = &lan8841_type, @@ -5872,8 +6379,24 @@ static struct phy_driver ksphy_driver[] = { .cable_test_start = lan8814_cable_test_start, .cable_test_get_status = ksz886x_cable_test_get_status, }, { - .phy_id = PHY_ID_KSZ9131, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_LAN8842), + .name = "Microchip LAN8842 Gigabit PHY", + .flags = PHY_POLL_CABLE_TEST, + .driver_data = &lan8814_type, + .probe = lan8842_probe, + .config_init = lan8842_config_init, + .config_intr = lan8842_config_intr, + .inband_caps = lan8842_inband_caps, + .config_inband = lan8842_config_inband, + .handle_interrupt = lan8842_handle_interrupt, + .get_phy_stats = lan8842_get_phy_stats, + .update_stats = lan8842_update_stats, + .get_tunable = lan8842_get_tunable, + .set_tunable = lan8842_set_tunable, + .cable_test_start = lan8814_cable_test_start, + .cable_test_get_status = ksz886x_cable_test_get_status, +}, { + PHY_ID_MATCH_MODEL(PHY_ID_KSZ9131), .name = "Microchip KSZ9131 Gigabit PHY", /* PHY_GBIT_FEATURES */ .flags = PHY_POLL_CABLE_TEST, @@ -5894,8 +6417,7 @@ static struct phy_driver ksphy_driver[] = { .cable_test_get_status = ksz9x31_cable_test_get_status, .get_features = ksz9477_get_features, }, { - .phy_id = PHY_ID_KSZ8873MLL, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_KSZ8873MLL), .name = "Micrel KSZ8873MLL Switch", /* PHY_BASIC_FEATURES */ .config_init = kszphy_config_init, @@ -5904,8 +6426,7 @@ static struct phy_driver ksphy_driver[] = { .suspend = genphy_suspend, .resume = genphy_resume, }, { - .phy_id = PHY_ID_KSZ886X, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_KSZ886X), .name = "Micrel KSZ8851 Ethernet MAC or KSZ886X Switch", .driver_data = &ksz886x_type, /* PHY_BASIC_FEATURES */ @@ -5925,8 +6446,7 @@ static struct phy_driver ksphy_driver[] = { .suspend = genphy_suspend, .resume = genphy_resume, }, { - .phy_id = PHY_ID_KSZ9477, - .phy_id_mask = MICREL_PHY_ID_MASK, + PHY_ID_MATCH_MODEL(PHY_ID_KSZ9477), .name = "Microchip KSZ9477", .probe = kszphy_probe, /* PHY_GBIT_FEATURES */ @@ -5953,22 +6473,24 @@ MODULE_LICENSE("GPL"); static const struct mdio_device_id __maybe_unused micrel_tbl[] = { { PHY_ID_KSZ9021, 0x000ffffe }, - { PHY_ID_KSZ9031, MICREL_PHY_ID_MASK }, - { PHY_ID_KSZ9131, MICREL_PHY_ID_MASK }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ9031) }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ9131) }, { PHY_ID_KSZ8001, 0x00fffffc }, - { PHY_ID_KS8737, MICREL_PHY_ID_MASK }, + { PHY_ID_MATCH_MODEL(PHY_ID_KS8737) }, { PHY_ID_KSZ8021, 0x00ffffff }, { PHY_ID_KSZ8031, 0x00ffffff }, - { PHY_ID_KSZ8041, MICREL_PHY_ID_MASK }, - { PHY_ID_KSZ8051, MICREL_PHY_ID_MASK }, - { PHY_ID_KSZ8061, MICREL_PHY_ID_MASK }, - { PHY_ID_KSZ8081, MICREL_PHY_ID_MASK }, - { PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK }, - { PHY_ID_KSZ886X, MICREL_PHY_ID_MASK }, - { PHY_ID_KSZ9477, MICREL_PHY_ID_MASK }, - { PHY_ID_LAN8814, MICREL_PHY_ID_MASK }, - { PHY_ID_LAN8804, MICREL_PHY_ID_MASK }, - { PHY_ID_LAN8841, MICREL_PHY_ID_MASK }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ8041) }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ8041RNLI) }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ8051) }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ8061) }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ8081) }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ8873MLL) }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ886X) }, + { PHY_ID_MATCH_MODEL(PHY_ID_KSZ9477) }, + { PHY_ID_MATCH_MODEL(PHY_ID_LAN8814) }, + { PHY_ID_MATCH_MODEL(PHY_ID_LAN8804) }, + { PHY_ID_MATCH_MODEL(PHY_ID_LAN8841) }, + { PHY_ID_MATCH_MODEL(PHY_ID_LAN8842) }, { } }; |