aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2009-04-29 04:06:34 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-29 20:32:31 -0400
commit23c3320cb039debfb94b27e8e9bfe26dd47692c3 (patch)
treebfb9253e7a6bc4472050db8e9241ad85a99283ab
parent68e7f45e118f98b77cfa007aa2d97b5dac69fe6b (diff)
chelsio: Use generic MDIO definitions and mdio_mii_ioctl()
Compile-tested only. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/chelsio/common.h2
-rw-r--r--drivers/net/chelsio/cphy.h45
-rw-r--r--drivers/net/chelsio/cxgb2.c36
-rw-r--r--drivers/net/chelsio/mv88x201x.c45
-rw-r--r--drivers/net/chelsio/my3126.c10
-rw-r--r--drivers/net/chelsio/subr.c43
7 files changed, 82 insertions, 100 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2f81db51b45..1ccd54714c4 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2450,6 +2450,7 @@ config CHELSIO_T1
2450 tristate "Chelsio 10Gb Ethernet support" 2450 tristate "Chelsio 10Gb Ethernet support"
2451 depends on PCI 2451 depends on PCI
2452 select CRC32 2452 select CRC32
2453 select MDIO
2453 help 2454 help
2454 This driver supports Chelsio gigabit and 10-gigabit 2455 This driver supports Chelsio gigabit and 10-gigabit
2455 Ethernet cards. More information about adapter features and 2456 Ethernet cards. More information about adapter features and
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index 4bd2455b0fe..699d22c5fe0 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -46,7 +46,7 @@
46#include <linux/pci.h> 46#include <linux/pci.h>
47#include <linux/ethtool.h> 47#include <linux/ethtool.h>
48#include <linux/if_vlan.h> 48#include <linux/if_vlan.h>
49#include <linux/mii.h> 49#include <linux/mdio.h>
50#include <linux/crc32.h> 50#include <linux/crc32.h>
51#include <linux/init.h> 51#include <linux/init.h>
52#include <asm/io.h> 52#include <asm/io.h>
diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h
index 79d855e267e..8b5165a5af3 100644
--- a/drivers/net/chelsio/cphy.h
+++ b/drivers/net/chelsio/cphy.h
@@ -43,10 +43,11 @@
43 43
44struct mdio_ops { 44struct mdio_ops {
45 void (*init)(adapter_t *adapter, const struct board_info *bi); 45 void (*init)(adapter_t *adapter, const struct board_info *bi);
46 int (*read)(adapter_t *adapter, int phy_addr, int mmd_addr, 46 int (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
47 int reg_addr, unsigned int *val); 47 u16 reg_addr);
48 int (*write)(adapter_t *adapter, int phy_addr, int mmd_addr, 48 int (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
49 int reg_addr, unsigned int val); 49 u16 reg_addr, u16 val);
50 unsigned mode_support;
50}; 51};
51 52
52/* PHY interrupt types */ 53/* PHY interrupt types */
@@ -83,11 +84,12 @@ struct cphy_ops {
83 int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex); 84 int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex);
84 int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, 85 int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
85 int *duplex, int *fc); 86 int *duplex, int *fc);
87
88 u32 mmds;
86}; 89};
87 90
88/* A PHY instance */ 91/* A PHY instance */
89struct cphy { 92struct cphy {
90 int addr; /* PHY address */
91 int state; /* Link status state machine */ 93 int state; /* Link status state machine */
92 adapter_t *adapter; /* associated adapter */ 94 adapter_t *adapter; /* associated adapter */
93 95
@@ -101,36 +103,37 @@ struct cphy {
101 u32 elmer_gpo; 103 u32 elmer_gpo;
102 104
103 const struct cphy_ops *ops; /* PHY operations */ 105 const struct cphy_ops *ops; /* PHY operations */
104 int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr, 106 struct mdio_if_info mdio;
105 int reg_addr, unsigned int *val);
106 int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr,
107 int reg_addr, unsigned int val);
108 struct cphy_instance *instance; 107 struct cphy_instance *instance;
109}; 108};
110 109
111/* Convenience MDIO read/write wrappers */ 110/* Convenience MDIO read/write wrappers */
112static inline int mdio_read(struct cphy *cphy, int mmd, int reg, 111static inline int cphy_mdio_read(struct cphy *cphy, int mmd, int reg,
113 unsigned int *valp) 112 unsigned int *valp)
114{ 113{
115 return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp); 114 int rc = cphy->mdio.mdio_read(cphy->mdio.dev, cphy->mdio.prtad, mmd,
115 reg);
116 *valp = (rc >= 0) ? rc : -1;
117 return (rc >= 0) ? 0 : rc;
116} 118}
117 119
118static inline int mdio_write(struct cphy *cphy, int mmd, int reg, 120static inline int cphy_mdio_write(struct cphy *cphy, int mmd, int reg,
119 unsigned int val) 121 unsigned int val)
120{ 122{
121 return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val); 123 return cphy->mdio.mdio_write(cphy->mdio.dev, cphy->mdio.prtad, mmd,
124 reg, val);
122} 125}
123 126
124static inline int simple_mdio_read(struct cphy *cphy, int reg, 127static inline int simple_mdio_read(struct cphy *cphy, int reg,
125 unsigned int *valp) 128 unsigned int *valp)
126{ 129{
127 return mdio_read(cphy, 0, reg, valp); 130 return cphy_mdio_read(cphy, MDIO_DEVAD_NONE, reg, valp);
128} 131}
129 132
130static inline int simple_mdio_write(struct cphy *cphy, int reg, 133static inline int simple_mdio_write(struct cphy *cphy, int reg,
131 unsigned int val) 134 unsigned int val)
132{ 135{
133 return mdio_write(cphy, 0, reg, val); 136 return cphy_mdio_write(cphy, MDIO_DEVAD_NONE, reg, val);
134} 137}
135 138
136/* Convenience initializer */ 139/* Convenience initializer */
@@ -139,11 +142,13 @@ static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
139 const struct mdio_ops *mdio_ops) 142 const struct mdio_ops *mdio_ops)
140{ 143{
141 phy->adapter = adapter; 144 phy->adapter = adapter;
142 phy->addr = phy_addr;
143 phy->ops = phy_ops; 145 phy->ops = phy_ops;
144 if (mdio_ops) { 146 if (mdio_ops) {
145 phy->mdio_read = mdio_ops->read; 147 phy->mdio.prtad = phy_addr;
146 phy->mdio_write = mdio_ops->write; 148 phy->mdio.mmds = phy_ops->mmds;
149 phy->mdio.mode_support = mdio_ops->mode_support;
150 phy->mdio.mdio_read = mdio_ops->read;
151 phy->mdio.mdio_write = mdio_ops->write;
147 } 152 }
148} 153}
149 154
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index fa06994f973..082cdb28b51 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -589,7 +589,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
589 } 589 }
590 590
591 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; 591 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
592 cmd->phy_address = p->phy->addr; 592 cmd->phy_address = p->phy->mdio.prtad;
593 cmd->transceiver = XCVR_EXTERNAL; 593 cmd->transceiver = XCVR_EXTERNAL;
594 cmd->autoneg = p->link_config.autoneg; 594 cmd->autoneg = p->link_config.autoneg;
595 cmd->maxtxpkt = 0; 595 cmd->maxtxpkt = 0;
@@ -849,39 +849,9 @@ static const struct ethtool_ops t1_ethtool_ops = {
849static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) 849static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
850{ 850{
851 struct adapter *adapter = dev->ml_priv; 851 struct adapter *adapter = dev->ml_priv;
852 struct mii_ioctl_data *data = if_mii(req); 852 struct mdio_if_info *mdio = &adapter->port[dev->if_port].phy->mdio;
853
854 switch (cmd) {
855 case SIOCGMIIPHY:
856 data->phy_id = adapter->port[dev->if_port].phy->addr;
857 /* FALLTHRU */
858 case SIOCGMIIREG: {
859 struct cphy *phy = adapter->port[dev->if_port].phy;
860 u32 val;
861
862 if (!phy->mdio_read)
863 return -EOPNOTSUPP;
864 phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
865 &val);
866 data->val_out = val;
867 break;
868 }
869 case SIOCSMIIREG: {
870 struct cphy *phy = adapter->port[dev->if_port].phy;
871
872 if (!capable(CAP_NET_ADMIN))
873 return -EPERM;
874 if (!phy->mdio_write)
875 return -EOPNOTSUPP;
876 phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
877 data->val_in);
878 break;
879 }
880 853
881 default: 854 return mdio_mii_ioctl(mdio, if_mii(req), cmd);
882 return -EOPNOTSUPP;
883 }
884 return 0;
885} 855}
886 856
887static int t1_change_mtu(struct net_device *dev, int new_mtu) 857static int t1_change_mtu(struct net_device *dev, int new_mtu)
diff --git a/drivers/net/chelsio/mv88x201x.c b/drivers/net/chelsio/mv88x201x.c
index cd856041af3..29e0cba48d5 100644
--- a/drivers/net/chelsio/mv88x201x.c
+++ b/drivers/net/chelsio/mv88x201x.c
@@ -53,7 +53,7 @@ static int led_init(struct cphy *cphy)
53 * Writing these bits maps control to another 53 * Writing these bits maps control to another
54 * register. mmd(0x1) addr(0x7) 54 * register. mmd(0x1) addr(0x7)
55 */ 55 */
56 mdio_write(cphy, 0x3, 0x8304, 0xdddd); 56 cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8304, 0xdddd);
57 return 0; 57 return 0;
58} 58}
59 59
@@ -62,14 +62,14 @@ static int led_link(struct cphy *cphy, u32 do_enable)
62 u32 led = 0; 62 u32 led = 0;
63#define LINK_ENABLE_BIT 0x1 63#define LINK_ENABLE_BIT 0x1
64 64
65 mdio_read(cphy, 0x1, 0x7, &led); 65 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, &led);
66 66
67 if (do_enable & LINK_ENABLE_BIT) { 67 if (do_enable & LINK_ENABLE_BIT) {
68 led |= LINK_ENABLE_BIT; 68 led |= LINK_ENABLE_BIT;
69 mdio_write(cphy, 0x1, 0x7, led); 69 cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
70 } else { 70 } else {
71 led &= ~LINK_ENABLE_BIT; 71 led &= ~LINK_ENABLE_BIT;
72 mdio_write(cphy, 0x1, 0x7, led); 72 cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
73 } 73 }
74 return 0; 74 return 0;
75} 75}
@@ -86,7 +86,7 @@ static int mv88x201x_reset(struct cphy *cphy, int wait)
86static int mv88x201x_interrupt_enable(struct cphy *cphy) 86static int mv88x201x_interrupt_enable(struct cphy *cphy)
87{ 87{
88 /* Enable PHY LASI interrupts. */ 88 /* Enable PHY LASI interrupts. */
89 mdio_write(cphy, 0x1, 0x9002, 0x1); 89 cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, 0x9002, 0x1);
90 90
91 /* Enable Marvell interrupts through Elmer0. */ 91 /* Enable Marvell interrupts through Elmer0. */
92 if (t1_is_asic(cphy->adapter)) { 92 if (t1_is_asic(cphy->adapter)) {
@@ -102,7 +102,7 @@ static int mv88x201x_interrupt_enable(struct cphy *cphy)
102static int mv88x201x_interrupt_disable(struct cphy *cphy) 102static int mv88x201x_interrupt_disable(struct cphy *cphy)
103{ 103{
104 /* Disable PHY LASI interrupts. */ 104 /* Disable PHY LASI interrupts. */
105 mdio_write(cphy, 0x1, 0x9002, 0x0); 105 cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, 0x9002, 0x0);
106 106
107 /* Disable Marvell interrupts through Elmer0. */ 107 /* Disable Marvell interrupts through Elmer0. */
108 if (t1_is_asic(cphy->adapter)) { 108 if (t1_is_asic(cphy->adapter)) {
@@ -122,25 +122,25 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy)
122 122
123#ifdef MV88x2010_LINK_STATUS_BUGS 123#ifdef MV88x2010_LINK_STATUS_BUGS
124 /* Required to read twice before clear takes affect. */ 124 /* Required to read twice before clear takes affect. */
125 mdio_read(cphy, 0x1, 0x9003, &val); 125 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9003, &val);
126 mdio_read(cphy, 0x1, 0x9004, &val); 126 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9004, &val);
127 mdio_read(cphy, 0x1, 0x9005, &val); 127 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9005, &val);
128 128
129 /* Read this register after the others above it else 129 /* Read this register after the others above it else
130 * the register doesn't clear correctly. 130 * the register doesn't clear correctly.
131 */ 131 */
132 mdio_read(cphy, 0x1, 0x1, &val); 132 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
133#endif 133#endif
134 134
135 /* Clear link status. */ 135 /* Clear link status. */
136 mdio_read(cphy, 0x1, 0x1, &val); 136 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
137 /* Clear PHY LASI interrupts. */ 137 /* Clear PHY LASI interrupts. */
138 mdio_read(cphy, 0x1, 0x9005, &val); 138 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9005, &val);
139 139
140#ifdef MV88x2010_LINK_STATUS_BUGS 140#ifdef MV88x2010_LINK_STATUS_BUGS
141 /* Do it again. */ 141 /* Do it again. */
142 mdio_read(cphy, 0x1, 0x9003, &val); 142 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9003, &val);
143 mdio_read(cphy, 0x1, 0x9004, &val); 143 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9004, &val);
144#endif 144#endif
145 145
146 /* Clear Marvell interrupts through Elmer0. */ 146 /* Clear Marvell interrupts through Elmer0. */
@@ -172,13 +172,12 @@ static int mv88x201x_get_link_status(struct cphy *cphy, int *link_ok,
172 int *speed, int *duplex, int *fc) 172 int *speed, int *duplex, int *fc)
173{ 173{
174 u32 val = 0; 174 u32 val = 0;
175#define LINK_STATUS_BIT 0x4
176 175
177 if (link_ok) { 176 if (link_ok) {
178 /* Read link status. */ 177 /* Read link status. */
179 mdio_read(cphy, 0x1, 0x1, &val); 178 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
180 val &= LINK_STATUS_BIT; 179 val &= MDIO_STAT1_LSTATUS;
181 *link_ok = (val == LINK_STATUS_BIT); 180 *link_ok = (val == MDIO_STAT1_LSTATUS);
182 /* Turn on/off Link LED */ 181 /* Turn on/off Link LED */
183 led_link(cphy, *link_ok); 182 led_link(cphy, *link_ok);
184 } 183 }
@@ -205,6 +204,8 @@ static struct cphy_ops mv88x201x_ops = {
205 .interrupt_handler = mv88x201x_interrupt_handler, 204 .interrupt_handler = mv88x201x_interrupt_handler,
206 .get_link_status = mv88x201x_get_link_status, 205 .get_link_status = mv88x201x_get_link_status,
207 .set_loopback = mv88x201x_set_loopback, 206 .set_loopback = mv88x201x_set_loopback,
207 .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
208 MDIO_DEVS_PHYXS | MDIO_DEVS_WIS),
208}; 209};
209 210
210static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr, 211static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
@@ -219,12 +220,12 @@ static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
219 cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops); 220 cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops);
220 221
221 /* Commands the PHY to enable XFP's clock. */ 222 /* Commands the PHY to enable XFP's clock. */
222 mdio_read(cphy, 0x3, 0x8300, &val); 223 cphy_mdio_read(cphy, MDIO_MMD_PCS, 0x8300, &val);
223 mdio_write(cphy, 0x3, 0x8300, val | 1); 224 cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8300, val | 1);
224 225
225 /* Clear link status. Required because of a bug in the PHY. */ 226 /* Clear link status. Required because of a bug in the PHY. */
226 mdio_read(cphy, 0x1, 0x8, &val); 227 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT2, &val);
227 mdio_read(cphy, 0x3, 0x8, &val); 228 cphy_mdio_read(cphy, MDIO_MMD_PCS, MDIO_STAT2, &val);
228 229
229 /* Allows for Link,Ack LED turn on/off */ 230 /* Allows for Link,Ack LED turn on/off */
230 led_init(cphy); 231 led_init(cphy);
diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c
index 040acd29995..977c7e08b0e 100644
--- a/drivers/net/chelsio/my3126.c
+++ b/drivers/net/chelsio/my3126.c
@@ -43,11 +43,11 @@ static int my3126_interrupt_handler(struct cphy *cphy)
43 adapter = cphy->adapter; 43 adapter = cphy->adapter;
44 44
45 if (cphy->count == 50) { 45 if (cphy->count == 50) {
46 mdio_read(cphy, 0x1, 0x1, &val); 46 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
47 val16 = (u16) val; 47 val16 = (u16) val;
48 status = cphy->bmsr ^ val16; 48 status = cphy->bmsr ^ val16;
49 49
50 if (status & BMSR_LSTATUS) 50 if (status & MDIO_STAT1_LSTATUS)
51 t1_link_changed(adapter, 0); 51 t1_link_changed(adapter, 0);
52 cphy->bmsr = val16; 52 cphy->bmsr = val16;
53 53
@@ -114,14 +114,14 @@ static int my3126_get_link_status(struct cphy *cphy,
114 adapter_t *adapter; 114 adapter_t *adapter;
115 115
116 adapter = cphy->adapter; 116 adapter = cphy->adapter;
117 mdio_read(cphy, 0x1, 0x1, &val); 117 cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
118 val16 = (u16) val; 118 val16 = (u16) val;
119 119
120 /* Populate elmer_gpo with the register value */ 120 /* Populate elmer_gpo with the register value */
121 t1_tpi_read(adapter, A_ELMER0_GPO, &val); 121 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
122 cphy->elmer_gpo = val; 122 cphy->elmer_gpo = val;
123 123
124 *link_ok = (val16 & BMSR_LSTATUS); 124 *link_ok = (val16 & MDIO_STAT1_LSTATUS);
125 125
126 if (*link_ok) { 126 if (*link_ok) {
127 /* Turn on the LED. */ 127 /* Turn on the LED. */
@@ -163,6 +163,8 @@ static struct cphy_ops my3126_ops = {
163 .interrupt_handler = my3126_interrupt_handler, 163 .interrupt_handler = my3126_interrupt_handler,
164 .get_link_status = my3126_get_link_status, 164 .get_link_status = my3126_get_link_status,
165 .set_loopback = my3126_set_loopback, 165 .set_loopback = my3126_set_loopback,
166 .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
167 MDIO_DEVS_PHYXS),
166}; 168};
167 169
168static struct cphy *my3126_phy_create(adapter_t *adapter, 170static struct cphy *my3126_phy_create(adapter_t *adapter,
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
index 7adf30230c4..2564312b305 100644
--- a/drivers/net/chelsio/subr.c
+++ b/drivers/net/chelsio/subr.c
@@ -284,32 +284,29 @@ static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
284/* 284/*
285 * Elmer MI1 MDIO read/write operations. 285 * Elmer MI1 MDIO read/write operations.
286 */ 286 */
287static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr, 287static int mi1_mdio_read(struct net_device *dev, int phy_addr, int mmd_addr,
288 int reg_addr, unsigned int *valp) 288 u16 reg_addr)
289{ 289{
290 struct adapter *adapter = dev->ml_priv;
290 u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr); 291 u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
291 292 unsigned int val;
292 if (mmd_addr)
293 return -EINVAL;
294 293
295 spin_lock(&adapter->tpi_lock); 294 spin_lock(&adapter->tpi_lock);
296 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 295 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
297 __t1_tpi_write(adapter, 296 __t1_tpi_write(adapter,
298 A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ); 297 A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ);
299 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 298 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
300 __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); 299 __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
301 spin_unlock(&adapter->tpi_lock); 300 spin_unlock(&adapter->tpi_lock);
302 return 0; 301 return val;
303} 302}
304 303
305static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr, 304static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
306 int reg_addr, unsigned int val) 305 u16 reg_addr, u16 val)
307{ 306{
307 struct adapter *adapter = dev->ml_priv;
308 u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr); 308 u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
309 309
310 if (mmd_addr)
311 return -EINVAL;
312
313 spin_lock(&adapter->tpi_lock); 310 spin_lock(&adapter->tpi_lock);
314 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 311 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
315 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); 312 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
@@ -324,16 +321,19 @@ static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
324static const struct mdio_ops mi1_mdio_ops = { 321static const struct mdio_ops mi1_mdio_ops = {
325 .init = mi1_mdio_init, 322 .init = mi1_mdio_init,
326 .read = mi1_mdio_read, 323 .read = mi1_mdio_read,
327 .write = mi1_mdio_write 324 .write = mi1_mdio_write,
325 .mode_support = MDIO_SUPPORTS_C22
328}; 326};
329#endif 327#endif
330 328
331#endif 329#endif
332 330
333static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, 331static int mi1_mdio_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
334 int reg_addr, unsigned int *valp) 332 u16 reg_addr)
335{ 333{
334 struct adapter *adapter = dev->ml_priv;
336 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 335 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
336 unsigned int val;
337 337
338 spin_lock(&adapter->tpi_lock); 338 spin_lock(&adapter->tpi_lock);
339 339
@@ -350,14 +350,15 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
350 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 350 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
351 351
352 /* Read the data. */ 352 /* Read the data. */
353 __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); 353 __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
354 spin_unlock(&adapter->tpi_lock); 354 spin_unlock(&adapter->tpi_lock);
355 return 0; 355 return val;
356} 356}
357 357
358static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, 358static int mi1_mdio_ext_write(struct net_device *dev, int phy_addr,
359 int reg_addr, unsigned int val) 359 int mmd_addr, u16 reg_addr, u16 val)
360{ 360{
361 struct adapter *adapter = dev->ml_priv;
361 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 362 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
362 363
363 spin_lock(&adapter->tpi_lock); 364 spin_lock(&adapter->tpi_lock);
@@ -380,7 +381,8 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
380static const struct mdio_ops mi1_mdio_ext_ops = { 381static const struct mdio_ops mi1_mdio_ext_ops = {
381 .init = mi1_mdio_init, 382 .init = mi1_mdio_init,
382 .read = mi1_mdio_ext_read, 383 .read = mi1_mdio_ext_read,
383 .write = mi1_mdio_ext_write 384 .write = mi1_mdio_ext_write,
385 .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
384}; 386};
385 387
386enum { 388enum {
@@ -1140,6 +1142,7 @@ int __devinit t1_init_sw_modules(adapter_t *adapter,
1140 adapter->name, i); 1142 adapter->name, i);
1141 goto error; 1143 goto error;
1142 } 1144 }
1145 adapter->port[i].phy->mdio.dev = adapter->port[i].dev;
1143 1146
1144 adapter->port[i].mac = mac = bi->gmac->create(adapter, i); 1147 adapter->port[i].mac = mac = bi->gmac->create(adapter, i);
1145 if (!mac) { 1148 if (!mac) {