2019-01-21 19:10:19 +01:00
// SPDX-License-Identifier: GPL-2.0
2015-10-20 16:28:57 -05:00
/*
* Driver for the Texas Instruments DP83848 PHY
*
2016-02-07 11:47:17 -06:00
* Copyright ( C ) 2015 - 2016 Texas Instruments Incorporated - http : //www.ti.com/
2015-10-20 16:28:57 -05:00
*/
# include <linux/module.h>
# include <linux/phy.h>
2016-02-07 11:47:18 -06:00
# define TI_DP83848C_PHY_ID 0x20005ca0
2017-01-17 09:08:16 +01:00
# define TI_DP83620_PHY_ID 0x20005ce0
2016-02-07 11:47:18 -06:00
# define NS_DP83848C_PHY_ID 0x20005c90
2016-02-07 11:47:20 -06:00
# define TLK10X_PHY_ID 0x2000a210
2015-10-20 16:28:57 -05:00
/* Registers */
2016-02-07 11:47:21 -06:00
# define DP83848_MICR 0x11 /* MII Interrupt Control Register */
# define DP83848_MISR 0x12 /* MII Interrupt Status Register */
2015-10-20 16:28:57 -05:00
/* MICR Register Fields */
# define DP83848_MICR_INT_OE BIT(0) /* Interrupt Output Enable */
# define DP83848_MICR_INTEN BIT(1) /* Interrupt Enable */
/* MISR Register Fields */
# define DP83848_MISR_RHF_INT_EN BIT(0) /* Receive Error Counter */
# define DP83848_MISR_FHF_INT_EN BIT(1) /* False Carrier Counter */
# define DP83848_MISR_ANC_INT_EN BIT(2) /* Auto-negotiation complete */
# define DP83848_MISR_DUP_INT_EN BIT(3) /* Duplex Status */
# define DP83848_MISR_SPD_INT_EN BIT(4) /* Speed status */
# define DP83848_MISR_LINK_INT_EN BIT(5) /* Link status */
# define DP83848_MISR_ED_INT_EN BIT(6) /* Energy detect */
# define DP83848_MISR_LQM_INT_EN BIT(7) /* Link Quality Monitor */
2016-02-07 11:47:19 -06:00
# define DP83848_INT_EN_MASK \
( DP83848_MISR_ANC_INT_EN | \
DP83848_MISR_DUP_INT_EN | \
DP83848_MISR_SPD_INT_EN | \
DP83848_MISR_LINK_INT_EN )
2020-11-23 17:38:13 +02:00
# define DP83848_MISR_RHF_INT BIT(8)
# define DP83848_MISR_FHF_INT BIT(9)
# define DP83848_MISR_ANC_INT BIT(10)
# define DP83848_MISR_DUP_INT BIT(11)
# define DP83848_MISR_SPD_INT BIT(12)
# define DP83848_MISR_LINK_INT BIT(13)
# define DP83848_MISR_ED_INT BIT(14)
# define DP83848_INT_MASK \
( DP83848_MISR_ANC_INT | \
DP83848_MISR_DUP_INT | \
DP83848_MISR_SPD_INT | \
DP83848_MISR_LINK_INT )
2015-10-20 16:28:57 -05:00
static int dp83848_ack_interrupt ( struct phy_device * phydev )
{
int err = phy_read ( phydev , DP83848_MISR ) ;
return err < 0 ? err : 0 ;
}
static int dp83848_config_intr ( struct phy_device * phydev )
{
2016-02-07 11:47:19 -06:00
int control , ret ;
control = phy_read ( phydev , DP83848_MICR ) ;
if ( control < 0 )
return control ;
2015-10-20 16:28:57 -05:00
if ( phydev - > interrupts = = PHY_INTERRUPT_ENABLED ) {
2020-11-23 17:38:14 +02:00
ret = dp83848_ack_interrupt ( phydev ) ;
if ( ret )
return ret ;
2016-02-07 11:47:19 -06:00
control | = DP83848_MICR_INT_OE ;
control | = DP83848_MICR_INTEN ;
2015-10-20 16:28:57 -05:00
2016-02-07 11:47:19 -06:00
ret = phy_write ( phydev , DP83848_MISR , DP83848_INT_EN_MASK ) ;
if ( ret < 0 )
return ret ;
2020-11-23 17:38:14 +02:00
ret = phy_write ( phydev , DP83848_MICR , control ) ;
2016-02-07 11:47:19 -06:00
} else {
control & = ~ DP83848_MICR_INTEN ;
2020-11-23 17:38:14 +02:00
ret = phy_write ( phydev , DP83848_MICR , control ) ;
if ( ret )
return ret ;
ret = dp83848_ack_interrupt ( phydev ) ;
2015-10-20 16:28:57 -05:00
}
2020-11-23 17:38:14 +02:00
return ret ;
2015-10-20 16:28:57 -05:00
}
2020-11-23 17:38:13 +02:00
static irqreturn_t dp83848_handle_interrupt ( struct phy_device * phydev )
{
int irq_status ;
irq_status = phy_read ( phydev , DP83848_MISR ) ;
if ( irq_status < 0 ) {
phy_error ( phydev ) ;
return IRQ_NONE ;
}
if ( ! ( irq_status & DP83848_INT_MASK ) )
return IRQ_NONE ;
phy_trigger_machine ( phydev ) ;
return IRQ_HANDLED ;
}
net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
DP83620 register set is compatible with the DP83848, but it also supports
100base-FX. When the hardware is configured such as that fiber mode is
enabled, autonegotiation is not possible.
The chip, however, doesn't expose this information via BMSR_ANEGCAPABLE.
Instead, this bit is always set high, even if the particular hardware
configuration makes it so that auto negotiation is not possible [1]. Under
these circumstances, the phy subsystem keeps trying for autonegotiation to
happen, without success.
Hereby, we inspect BMCR_ANENABLE bit after genphy_config_init, which on
reset is set to 0 when auto negotiation is disabled, and so we use this
value instead of BMSR_ANEGCAPABLE.
[1] https://e2e.ti.com/support/interface/ethernet/f/903/p/697165/2571170
Signed-off-by: Alvaro Gamez Machado <alvaro.gamez@hazent.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-06-08 12:23:39 +02:00
static int dp83848_config_init ( struct phy_device * phydev )
{
int val ;
/* DP83620 always reports Auto Negotiation Ability on BMSR. Instead,
* we check initial value of BMCR Auto negotiation enable bit
*/
val = phy_read ( phydev , MII_BMCR ) ;
if ( ! ( val & BMCR_ANENABLE ) )
phydev - > autoneg = AUTONEG_DISABLE ;
return 0 ;
}
2015-10-20 16:28:57 -05:00
static struct mdio_device_id __maybe_unused dp83848_tbl [ ] = {
2016-02-07 11:47:18 -06:00
{ TI_DP83848C_PHY_ID , 0xfffffff0 } ,
{ NS_DP83848C_PHY_ID , 0xfffffff0 } ,
2017-01-17 09:08:16 +01:00
{ TI_DP83620_PHY_ID , 0xfffffff0 } ,
2016-02-07 11:47:20 -06:00
{ TLK10X_PHY_ID , 0xfffffff0 } ,
2015-10-20 16:28:57 -05:00
{ }
} ;
MODULE_DEVICE_TABLE ( mdio , dp83848_tbl ) ;
net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
DP83620 register set is compatible with the DP83848, but it also supports
100base-FX. When the hardware is configured such as that fiber mode is
enabled, autonegotiation is not possible.
The chip, however, doesn't expose this information via BMSR_ANEGCAPABLE.
Instead, this bit is always set high, even if the particular hardware
configuration makes it so that auto negotiation is not possible [1]. Under
these circumstances, the phy subsystem keeps trying for autonegotiation to
happen, without success.
Hereby, we inspect BMCR_ANENABLE bit after genphy_config_init, which on
reset is set to 0 when auto negotiation is disabled, and so we use this
value instead of BMSR_ANEGCAPABLE.
[1] https://e2e.ti.com/support/interface/ethernet/f/903/p/697165/2571170
Signed-off-by: Alvaro Gamez Machado <alvaro.gamez@hazent.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-06-08 12:23:39 +02:00
# define DP83848_PHY_DRIVER(_id, _name, _config_init) \
2016-02-07 11:47:17 -06:00
{ \
. phy_id = _id , \
. phy_id_mask = 0xfffffff0 , \
. name = _name , \
2019-04-12 20:47:03 +02:00
/* PHY_BASIC_FEATURES */ \
2016-02-07 11:47:17 -06:00
\
. soft_reset = genphy_soft_reset , \
net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
DP83620 register set is compatible with the DP83848, but it also supports
100base-FX. When the hardware is configured such as that fiber mode is
enabled, autonegotiation is not possible.
The chip, however, doesn't expose this information via BMSR_ANEGCAPABLE.
Instead, this bit is always set high, even if the particular hardware
configuration makes it so that auto negotiation is not possible [1]. Under
these circumstances, the phy subsystem keeps trying for autonegotiation to
happen, without success.
Hereby, we inspect BMCR_ANENABLE bit after genphy_config_init, which on
reset is set to 0 when auto negotiation is disabled, and so we use this
value instead of BMSR_ANEGCAPABLE.
[1] https://e2e.ti.com/support/interface/ethernet/f/903/p/697165/2571170
Signed-off-by: Alvaro Gamez Machado <alvaro.gamez@hazent.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-06-08 12:23:39 +02:00
. config_init = _config_init , \
2016-02-07 11:47:17 -06:00
. suspend = genphy_suspend , \
. resume = genphy_resume , \
\
/* IRQ related */ \
. config_intr = dp83848_config_intr , \
2020-11-23 17:38:13 +02:00
. handle_interrupt = dp83848_handle_interrupt , \
2016-02-07 11:47:17 -06:00
}
2015-10-20 16:28:57 -05:00
2016-02-07 11:47:17 -06:00
static struct phy_driver dp83848_driver [ ] = {
net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
DP83620 register set is compatible with the DP83848, but it also supports
100base-FX. When the hardware is configured such as that fiber mode is
enabled, autonegotiation is not possible.
The chip, however, doesn't expose this information via BMSR_ANEGCAPABLE.
Instead, this bit is always set high, even if the particular hardware
configuration makes it so that auto negotiation is not possible [1]. Under
these circumstances, the phy subsystem keeps trying for autonegotiation to
happen, without success.
Hereby, we inspect BMCR_ANENABLE bit after genphy_config_init, which on
reset is set to 0 when auto negotiation is disabled, and so we use this
value instead of BMSR_ANEGCAPABLE.
[1] https://e2e.ti.com/support/interface/ethernet/f/903/p/697165/2571170
Signed-off-by: Alvaro Gamez Machado <alvaro.gamez@hazent.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-06-08 12:23:39 +02:00
DP83848_PHY_DRIVER ( TI_DP83848C_PHY_ID , " TI DP83848C 10/100 Mbps PHY " ,
2019-08-17 12:29:25 +02:00
NULL ) ,
net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
DP83620 register set is compatible with the DP83848, but it also supports
100base-FX. When the hardware is configured such as that fiber mode is
enabled, autonegotiation is not possible.
The chip, however, doesn't expose this information via BMSR_ANEGCAPABLE.
Instead, this bit is always set high, even if the particular hardware
configuration makes it so that auto negotiation is not possible [1]. Under
these circumstances, the phy subsystem keeps trying for autonegotiation to
happen, without success.
Hereby, we inspect BMCR_ANENABLE bit after genphy_config_init, which on
reset is set to 0 when auto negotiation is disabled, and so we use this
value instead of BMSR_ANEGCAPABLE.
[1] https://e2e.ti.com/support/interface/ethernet/f/903/p/697165/2571170
Signed-off-by: Alvaro Gamez Machado <alvaro.gamez@hazent.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-06-08 12:23:39 +02:00
DP83848_PHY_DRIVER ( NS_DP83848C_PHY_ID , " NS DP83848C 10/100 Mbps PHY " ,
2019-08-17 12:29:25 +02:00
NULL ) ,
net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
DP83620 register set is compatible with the DP83848, but it also supports
100base-FX. When the hardware is configured such as that fiber mode is
enabled, autonegotiation is not possible.
The chip, however, doesn't expose this information via BMSR_ANEGCAPABLE.
Instead, this bit is always set high, even if the particular hardware
configuration makes it so that auto negotiation is not possible [1]. Under
these circumstances, the phy subsystem keeps trying for autonegotiation to
happen, without success.
Hereby, we inspect BMCR_ANENABLE bit after genphy_config_init, which on
reset is set to 0 when auto negotiation is disabled, and so we use this
value instead of BMSR_ANEGCAPABLE.
[1] https://e2e.ti.com/support/interface/ethernet/f/903/p/697165/2571170
Signed-off-by: Alvaro Gamez Machado <alvaro.gamez@hazent.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-06-08 12:23:39 +02:00
DP83848_PHY_DRIVER ( TI_DP83620_PHY_ID , " TI DP83620 10/100 Mbps PHY " ,
dp83848_config_init ) ,
DP83848_PHY_DRIVER ( TLK10X_PHY_ID , " TI TLK10X 10/100 Mbps PHY " ,
2019-08-17 12:29:25 +02:00
NULL ) ,
2015-10-20 16:28:57 -05:00
} ;
module_phy_driver ( dp83848_driver ) ;
MODULE_DESCRIPTION ( " Texas Instruments DP83848 PHY driver " ) ;
2017-01-05 14:44:50 -06:00
MODULE_AUTHOR ( " Andrew F. Davis <afd@ti.com> " ) ;
2019-01-21 19:10:19 +01:00
MODULE_LICENSE ( " GPL v2 " ) ;