2323
2424#define DP83822_DEVADDR 0x1f
2525
26+ #define MII_DP83822_CTRL_2 0x0a
27+ #define MII_DP83822_PHYSTS 0x10
2628#define MII_DP83822_PHYSCR 0x11
2729#define MII_DP83822_MISR1 0x12
2830#define MII_DP83822_MISR2 0x13
31+ #define MII_DP83822_FCSCR 0x14
2932#define MII_DP83822_RCSR 0x17
3033#define MII_DP83822_RESET_CTRL 0x1f
3134#define MII_DP83822_GENCFG 0x465
35+ #define MII_DP83822_SOR1 0x467
36+
37+ /* GENCFG */
38+ #define DP83822_SIG_DET_LOW BIT(0)
39+
40+ /* Control Register 2 bits */
41+ #define DP83822_FX_ENABLE BIT(14)
3242
3343#define DP83822_HW_RESET BIT(15)
3444#define DP83822_SW_RESET BIT(14)
3545
46+ /* PHY STS bits */
47+ #define DP83822_PHYSTS_DUPLEX BIT(2)
48+ #define DP83822_PHYSTS_10 BIT(1)
49+ #define DP83822_PHYSTS_LINK BIT(0)
50+
3651/* PHYSCR Register Fields */
3752#define DP83822_PHYSCR_INT_OE BIT(0) /* Interrupt Output Enable */
3853#define DP83822_PHYSCR_INTEN BIT(1) /* Interrupt Enable */
8398#define DP83822_RX_CLK_SHIFT BIT(12)
8499#define DP83822_TX_CLK_SHIFT BIT(11)
85100
101+ /* SOR1 mode */
102+ #define DP83822_STRAP_MODE1 0
103+ #define DP83822_STRAP_MODE2 BIT(0)
104+ #define DP83822_STRAP_MODE3 BIT(1)
105+ #define DP83822_STRAP_MODE4 GENMASK(1, 0)
106+
107+ #define DP83822_COL_STRAP_MASK GENMASK(11, 10)
108+ #define DP83822_COL_SHIFT 10
109+ #define DP83822_RX_ER_STR_MASK GENMASK(9, 8)
110+ #define DP83822_RX_ER_SHIFT 8
111+
112+ #define MII_DP83822_FIBER_ADVERTISE (ADVERTISED_TP | ADVERTISED_MII | \
113+ ADVERTISED_FIBRE | ADVERTISED_BNC | \
114+ ADVERTISED_Pause | ADVERTISED_Asym_Pause | \
115+ ADVERTISED_100baseT_Full)
116+
117+ struct dp83822_private {
118+ bool fx_signal_det_low ;
119+ int fx_enabled ;
120+ u16 fx_sd_enable ;
121+ };
122+
86123static int dp83822_ack_interrupt (struct phy_device * phydev )
87124{
88125 int err ;
@@ -197,6 +234,7 @@ static void dp83822_get_wol(struct phy_device *phydev,
197234
198235static int dp83822_config_intr (struct phy_device * phydev )
199236{
237+ struct dp83822_private * dp83822 = phydev -> priv ;
200238 int misr_status ;
201239 int physcr_status ;
202240 int err ;
@@ -208,13 +246,16 @@ static int dp83822_config_intr(struct phy_device *phydev)
208246
209247 misr_status |= (DP83822_RX_ERR_HF_INT_EN |
210248 DP83822_FALSE_CARRIER_HF_INT_EN |
211- DP83822_ANEG_COMPLETE_INT_EN |
212- DP83822_DUP_MODE_CHANGE_INT_EN |
213- DP83822_SPEED_CHANGED_INT_EN |
214249 DP83822_LINK_STAT_INT_EN |
215250 DP83822_ENERGY_DET_INT_EN |
216251 DP83822_LINK_QUAL_INT_EN );
217252
253+ if (!dp83822 -> fx_enabled )
254+ misr_status |= DP83822_ANEG_COMPLETE_INT_EN |
255+ DP83822_DUP_MODE_CHANGE_INT_EN |
256+ DP83822_SPEED_CHANGED_INT_EN ;
257+
258+
218259 err = phy_write (phydev , MII_DP83822_MISR1 , misr_status );
219260 if (err < 0 )
220261 return err ;
@@ -224,14 +265,16 @@ static int dp83822_config_intr(struct phy_device *phydev)
224265 return misr_status ;
225266
226267 misr_status |= (DP83822_JABBER_DET_INT_EN |
227- DP83822_WOL_PKT_INT_EN |
228268 DP83822_SLEEP_MODE_INT_EN |
229- DP83822_MDI_XOVER_INT_EN |
230269 DP83822_LB_FIFO_INT_EN |
231270 DP83822_PAGE_RX_INT_EN |
232- DP83822_ANEG_ERR_INT_EN |
233271 DP83822_EEE_ERROR_CHANGE_INT_EN );
234272
273+ if (!dp83822 -> fx_enabled )
274+ misr_status |= DP83822_MDI_XOVER_INT_EN |
275+ DP83822_ANEG_ERR_INT_EN |
276+ DP83822_WOL_PKT_INT_EN ;
277+
235278 err = phy_write (phydev , MII_DP83822_MISR2 , misr_status );
236279 if (err < 0 )
237280 return err ;
@@ -270,13 +313,60 @@ static int dp8382x_disable_wol(struct phy_device *phydev)
270313 MII_DP83822_WOL_CFG , value );
271314}
272315
316+ static int dp83822_read_status (struct phy_device * phydev )
317+ {
318+ struct dp83822_private * dp83822 = phydev -> priv ;
319+ int status = phy_read (phydev , MII_DP83822_PHYSTS );
320+ int ctrl2 ;
321+ int ret ;
322+
323+ if (dp83822 -> fx_enabled ) {
324+ if (status & DP83822_PHYSTS_LINK ) {
325+ phydev -> speed = SPEED_UNKNOWN ;
326+ phydev -> duplex = DUPLEX_UNKNOWN ;
327+ } else {
328+ ctrl2 = phy_read (phydev , MII_DP83822_CTRL_2 );
329+ if (ctrl2 < 0 )
330+ return ctrl2 ;
331+
332+ if (!(ctrl2 & DP83822_FX_ENABLE )) {
333+ ret = phy_write (phydev , MII_DP83822_CTRL_2 ,
334+ DP83822_FX_ENABLE | ctrl2 );
335+ if (ret < 0 )
336+ return ret ;
337+ }
338+ }
339+ }
340+
341+ ret = genphy_read_status (phydev );
342+ if (ret )
343+ return ret ;
344+
345+ if (status < 0 )
346+ return status ;
347+
348+ if (status & DP83822_PHYSTS_DUPLEX )
349+ phydev -> duplex = DUPLEX_FULL ;
350+ else
351+ phydev -> duplex = DUPLEX_HALF ;
352+
353+ if (status & DP83822_PHYSTS_10 )
354+ phydev -> speed = SPEED_10 ;
355+ else
356+ phydev -> speed = SPEED_100 ;
357+
358+ return 0 ;
359+ }
360+
273361static int dp83822_config_init (struct phy_device * phydev )
274362{
363+ struct dp83822_private * dp83822 = phydev -> priv ;
275364 struct device * dev = & phydev -> mdio .dev ;
276365 int rgmii_delay ;
277366 s32 rx_int_delay ;
278367 s32 tx_int_delay ;
279368 int err = 0 ;
369+ int bmcr ;
280370
281371 if (phy_interface_is_rgmii (phydev )) {
282372 rx_int_delay = phy_get_internal_delay (phydev , dev , NULL , 0 ,
@@ -302,6 +392,53 @@ static int dp83822_config_init(struct phy_device *phydev)
302392 }
303393 }
304394
395+ if (dp83822 -> fx_enabled ) {
396+ err = phy_modify (phydev , MII_DP83822_CTRL_2 ,
397+ DP83822_FX_ENABLE , 1 );
398+ if (err < 0 )
399+ return err ;
400+
401+ /* Only allow advertising what this PHY supports */
402+ linkmode_and (phydev -> advertising , phydev -> advertising ,
403+ phydev -> supported );
404+
405+ linkmode_set_bit (ETHTOOL_LINK_MODE_FIBRE_BIT ,
406+ phydev -> supported );
407+ linkmode_set_bit (ETHTOOL_LINK_MODE_FIBRE_BIT ,
408+ phydev -> advertising );
409+
410+ /* Auto neg is not supported in fiber mode */
411+ bmcr = phy_read (phydev , MII_BMCR );
412+ if (bmcr < 0 )
413+ return bmcr ;
414+
415+ if (bmcr & BMCR_ANENABLE ) {
416+ err = phy_modify (phydev , MII_BMCR , BMCR_ANENABLE , 0 );
417+ if (err < 0 )
418+ return err ;
419+ }
420+ phydev -> autoneg = AUTONEG_DISABLE ;
421+ linkmode_clear_bit (ETHTOOL_LINK_MODE_Autoneg_BIT ,
422+ phydev -> supported );
423+ linkmode_clear_bit (ETHTOOL_LINK_MODE_Autoneg_BIT ,
424+ phydev -> advertising );
425+
426+ /* Setup fiber advertisement */
427+ err = phy_modify_changed (phydev , MII_ADVERTISE ,
428+ MII_DP83822_FIBER_ADVERTISE ,
429+ MII_DP83822_FIBER_ADVERTISE );
430+
431+ if (err < 0 )
432+ return err ;
433+
434+ if (dp83822 -> fx_signal_det_low ) {
435+ err = phy_set_bits_mmd (phydev , DP83822_DEVADDR ,
436+ MII_DP83822_GENCFG ,
437+ DP83822_SIG_DET_LOW );
438+ if (err )
439+ return err ;
440+ }
441+ }
305442 return dp8382x_disable_wol (phydev );
306443}
307444
@@ -314,13 +451,85 @@ static int dp83822_phy_reset(struct phy_device *phydev)
314451{
315452 int err ;
316453
317- err = phy_write (phydev , MII_DP83822_RESET_CTRL , DP83822_HW_RESET );
454+ err = phy_write (phydev , MII_DP83822_RESET_CTRL , DP83822_SW_RESET );
318455 if (err < 0 )
319456 return err ;
320457
321458 return phydev -> drv -> config_init (phydev );
322459}
323460
461+ #ifdef CONFIG_OF_MDIO
462+ static int dp83822_of_init (struct phy_device * phydev )
463+ {
464+ struct dp83822_private * dp83822 = phydev -> priv ;
465+ struct device * dev = & phydev -> mdio .dev ;
466+
467+ /* Signal detection for the PHY is only enabled if the FX_EN and the
468+ * SD_EN pins are strapped. Signal detection can only enabled if FX_EN
469+ * is strapped otherwise signal detection is disabled for the PHY.
470+ */
471+ if (dp83822 -> fx_enabled && dp83822 -> fx_sd_enable )
472+ dp83822 -> fx_signal_det_low = device_property_present (dev ,
473+ "ti,link-loss-low" );
474+ if (!dp83822 -> fx_enabled )
475+ dp83822 -> fx_enabled = device_property_present (dev ,
476+ "ti,fiber-mode" );
477+
478+ return 0 ;
479+ }
480+ #else
481+ static int dp83822_of_init (struct phy_device * phydev )
482+ {
483+ return 0 ;
484+ }
485+ #endif /* CONFIG_OF_MDIO */
486+
487+ static int dp83822_read_straps (struct phy_device * phydev )
488+ {
489+ struct dp83822_private * dp83822 = phydev -> priv ;
490+ int fx_enabled , fx_sd_enable ;
491+ int val ;
492+
493+ val = phy_read_mmd (phydev , DP83822_DEVADDR , MII_DP83822_SOR1 );
494+ if (val < 0 )
495+ return val ;
496+
497+ fx_enabled = (val & DP83822_COL_STRAP_MASK ) >> DP83822_COL_SHIFT ;
498+ if (fx_enabled == DP83822_STRAP_MODE2 ||
499+ fx_enabled == DP83822_STRAP_MODE3 )
500+ dp83822 -> fx_enabled = 1 ;
501+
502+ if (dp83822 -> fx_enabled ) {
503+ fx_sd_enable = (val & DP83822_RX_ER_STR_MASK ) >> DP83822_RX_ER_SHIFT ;
504+ if (fx_sd_enable == DP83822_STRAP_MODE3 ||
505+ fx_sd_enable == DP83822_STRAP_MODE4 )
506+ dp83822 -> fx_sd_enable = 1 ;
507+ }
508+
509+ return 0 ;
510+ }
511+
512+ static int dp83822_probe (struct phy_device * phydev )
513+ {
514+ struct dp83822_private * dp83822 ;
515+ int ret ;
516+
517+ dp83822 = devm_kzalloc (& phydev -> mdio .dev , sizeof (* dp83822 ),
518+ GFP_KERNEL );
519+ if (!dp83822 )
520+ return - ENOMEM ;
521+
522+ phydev -> priv = dp83822 ;
523+
524+ ret = dp83822_read_straps (phydev );
525+ if (ret )
526+ return ret ;
527+
528+ dp83822_of_init (phydev );
529+
530+ return 0 ;
531+ }
532+
324533static int dp83822_suspend (struct phy_device * phydev )
325534{
326535 int value ;
@@ -352,8 +561,10 @@ static int dp83822_resume(struct phy_device *phydev)
352561 PHY_ID_MATCH_MODEL(_id), \
353562 .name = (_name), \
354563 /* PHY_BASIC_FEATURES */ \
564+ .probe = dp83822_probe, \
355565 .soft_reset = dp83822_phy_reset, \
356566 .config_init = dp83822_config_init, \
567+ .read_status = dp83822_read_status, \
357568 .get_wol = dp83822_get_wol, \
358569 .set_wol = dp83822_set_wol, \
359570 .ack_interrupt = dp83822_ack_interrupt, \
0 commit comments