Blame view

drivers/net/phy/national.c 3.76 KB
a2443fd1a   Andrew Lunn   net: phy: Convert...
1
  // SPDX-License-Identifier: GPL-2.0+
4621bf129   David S. Miller   phy: Add file mis...
2
3
4
5
6
7
8
9
10
  /*
   * drivers/net/phy/national.c
   *
   * Driver for National Semiconductor PHYs
   *
   * Author: Stuart Menefy <stuart.menefy@st.com>
   * Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
   *
   * Copyright (c) 2008 STMicroelectronics Limited
4621bf129   David S. Miller   phy: Add file mis...
11
   */
8d242488c   Joe Perches   phy: Use pr_<level>
12
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
4621bf129   David S. Miller   phy: Add file mis...
13
14
15
16
17
18
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/mii.h>
  #include <linux/ethtool.h>
  #include <linux/phy.h>
  #include <linux/netdevice.h>
8d242488c   Joe Perches   phy: Use pr_<level>
19
  #define DEBUG
4621bf129   David S. Miller   phy: Add file mis...
20
21
  /* DP83865 phy identifier values */
  #define DP83865_PHY_ID	0x20005c7a
6e6f400f5   Giuseppe CAVALLARO   net/phy: fix DP83...
22
23
24
  #define DP83865_INT_STATUS	0x14
  #define DP83865_INT_MASK	0x15
  #define DP83865_INT_CLEAR	0x17
4621bf129   David S. Miller   phy: Add file mis...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  
  #define DP83865_INT_REMOTE_FAULT 0x0008
  #define DP83865_INT_ANE_COMPLETED 0x0010
  #define DP83865_INT_LINK_CHANGE	0xe000
  #define DP83865_INT_MASK_DEFAULT (DP83865_INT_REMOTE_FAULT | \
  				DP83865_INT_ANE_COMPLETED | \
  				DP83865_INT_LINK_CHANGE)
  
  /* Advanced proprietary configuration */
  #define NS_EXP_MEM_CTL	0x16
  #define NS_EXP_MEM_DATA	0x1d
  #define NS_EXP_MEM_ADD	0x1e
  
  #define LED_CTRL_REG 0x13
  #define AN_FALLBACK_AN 0x0001
  #define AN_FALLBACK_CRC 0x0002
  #define AN_FALLBACK_IE 0x0004
  #define ALL_FALLBACK_ON (AN_FALLBACK_AN |  AN_FALLBACK_CRC | AN_FALLBACK_IE)
  
  enum hdx_loopback {
  	hdx_loopback_on = 0,
  	hdx_loopback_off = 1,
  };
  
  static u8 ns_exp_read(struct phy_device *phydev, u16 reg)
  {
  	phy_write(phydev, NS_EXP_MEM_ADD, reg);
  	return phy_read(phydev, NS_EXP_MEM_DATA);
  }
  
  static void ns_exp_write(struct phy_device *phydev, u16 reg, u8 data)
  {
  	phy_write(phydev, NS_EXP_MEM_ADD, reg);
  	phy_write(phydev, NS_EXP_MEM_DATA, data);
  }
  
  static int ns_config_intr(struct phy_device *phydev)
  {
  	int err;
  
  	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
6e6f400f5   Giuseppe CAVALLARO   net/phy: fix DP83...
66
  		err = phy_write(phydev, DP83865_INT_MASK,
4621bf129   David S. Miller   phy: Add file mis...
67
68
  				DP83865_INT_MASK_DEFAULT);
  	else
6e6f400f5   Giuseppe CAVALLARO   net/phy: fix DP83...
69
  		err = phy_write(phydev, DP83865_INT_MASK, 0);
4621bf129   David S. Miller   phy: Add file mis...
70
71
72
73
74
75
  
  	return err;
  }
  
  static int ns_ack_interrupt(struct phy_device *phydev)
  {
6e6f400f5   Giuseppe CAVALLARO   net/phy: fix DP83...
76
  	int ret = phy_read(phydev, DP83865_INT_STATUS);
4621bf129   David S. Miller   phy: Add file mis...
77
78
  	if (ret < 0)
  		return ret;
6e6f400f5   Giuseppe CAVALLARO   net/phy: fix DP83...
79
80
81
82
83
  	/* Clear the interrupt status bit by writing a “1”
  	 * to the corresponding bit in INT_CLEAR (2:0 are reserved) */
  	ret = phy_write(phydev, DP83865_INT_CLEAR, ret & ~0x7);
  
  	return ret;
4621bf129   David S. Miller   phy: Add file mis...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  }
  
  static void ns_giga_speed_fallback(struct phy_device *phydev, int mode)
  {
  	int bmcr = phy_read(phydev, MII_BMCR);
  
  	phy_write(phydev, MII_BMCR, (bmcr | BMCR_PDOWN));
  
  	/* Enable 8 bit expended memory read/write (no auto increment) */
  	phy_write(phydev, NS_EXP_MEM_CTL, 0);
  	phy_write(phydev, NS_EXP_MEM_ADD, 0x1C0);
  	phy_write(phydev, NS_EXP_MEM_DATA, 0x0008);
  	phy_write(phydev, MII_BMCR, (bmcr & ~BMCR_PDOWN));
  	phy_write(phydev, LED_CTRL_REG, mode);
4621bf129   David S. Miller   phy: Add file mis...
98
99
100
101
  }
  
  static void ns_10_base_t_hdx_loopack(struct phy_device *phydev, int disable)
  {
e47488b2d   Peter Mamonov   net/phy: fix DP83...
102
  	u16 lb_dis = BIT(1);
4621bf129   David S. Miller   phy: Add file mis...
103
  	if (disable)
e47488b2d   Peter Mamonov   net/phy: fix DP83...
104
105
  		ns_exp_write(phydev, 0x1c0,
  			     ns_exp_read(phydev, 0x1c0) | lb_dis);
4621bf129   David S. Miller   phy: Add file mis...
106
107
  	else
  		ns_exp_write(phydev, 0x1c0,
e47488b2d   Peter Mamonov   net/phy: fix DP83...
108
  			     ns_exp_read(phydev, 0x1c0) & ~lb_dis);
4621bf129   David S. Miller   phy: Add file mis...
109

8d242488c   Joe Perches   phy: Use pr_<level>
110
111
  	pr_debug("10BASE-T HDX loopback %s
  ",
e47488b2d   Peter Mamonov   net/phy: fix DP83...
112
  		 (ns_exp_read(phydev, 0x1c0) & lb_dis) ? "off" : "on");
4621bf129   David S. Miller   phy: Add file mis...
113
114
115
116
117
118
119
120
121
122
  }
  
  static int ns_config_init(struct phy_device *phydev)
  {
  	ns_giga_speed_fallback(phydev, ALL_FALLBACK_ON);
  	/* In the latest MAC or switches design, the 10 Mbps loopback
  	   is desired to be turned off. */
  	ns_10_base_t_hdx_loopack(phydev, hdx_loopback_off);
  	return ns_ack_interrupt(phydev);
  }
116dffa0b   Johan Hovold   net: phy: replace...
123
  static struct phy_driver dp83865_driver[] = { {
4621bf129   David S. Miller   phy: Add file mis...
124
125
126
  	.phy_id = DP83865_PHY_ID,
  	.phy_id_mask = 0xfffffff0,
  	.name = "NatSemi DP83865",
dcdecdcfe   Heiner Kallweit   net: phy: switch ...
127
  	/* PHY_GBIT_FEATURES */
4621bf129   David S. Miller   phy: Add file mis...
128
  	.config_init = ns_config_init,
4621bf129   David S. Miller   phy: Add file mis...
129
130
  	.ack_interrupt = ns_ack_interrupt,
  	.config_intr = ns_config_intr,
116dffa0b   Johan Hovold   net: phy: replace...
131
  } };
4621bf129   David S. Miller   phy: Add file mis...
132

116dffa0b   Johan Hovold   net: phy: replace...
133
  module_phy_driver(dp83865_driver);
4621bf129   David S. Miller   phy: Add file mis...
134
135
136
137
  
  MODULE_DESCRIPTION("NatSemi PHY driver");
  MODULE_AUTHOR("Stuart Menefy");
  MODULE_LICENSE("GPL");
cf93c9458   Uwe Kleine-König   net/phy: fix many...
138
  static struct mdio_device_id __maybe_unused ns_tbl[] = {
4e4f10f64   David Woodhouse   phylib: Add modul...
139
140
141
142
143
  	{ DP83865_PHY_ID, 0xfffffff0 },
  	{ }
  };
  
  MODULE_DEVICE_TABLE(mdio, ns_tbl);