aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/fixed.c33
-rw-r--r--drivers/net/phy/mdio-bitbang.c4
-rw-r--r--drivers/net/phy/mdio-ofgpio.c11
-rw-r--r--drivers/net/phy/mdio_bus.c232
-rw-r--r--drivers/net/phy/phy.c60
-rw-r--r--drivers/net/phy/phy_device.c50
6 files changed, 258 insertions, 132 deletions
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 4e07956a483b..cf24cc34debe 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -24,7 +24,7 @@
24 24
25struct fixed_mdio_bus { 25struct fixed_mdio_bus {
26 int irqs[PHY_MAX_ADDR]; 26 int irqs[PHY_MAX_ADDR];
27 struct mii_bus mii_bus; 27 struct mii_bus *mii_bus;
28 struct list_head phys; 28 struct list_head phys;
29}; 29};
30 30
@@ -115,8 +115,7 @@ static int fixed_phy_update_regs(struct fixed_phy *fp)
115 115
116static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num) 116static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num)
117{ 117{
118 struct fixed_mdio_bus *fmb = container_of(bus, struct fixed_mdio_bus, 118 struct fixed_mdio_bus *fmb = bus->priv;
119 mii_bus);
120 struct fixed_phy *fp; 119 struct fixed_phy *fp;
121 120
122 if (reg_num >= MII_REGS_NUM) 121 if (reg_num >= MII_REGS_NUM)
@@ -213,19 +212,28 @@ static int __init fixed_mdio_bus_init(void)
213 goto err_pdev; 212 goto err_pdev;
214 } 213 }
215 214
216 snprintf(fmb->mii_bus.id, MII_BUS_ID_SIZE, "0"); 215 fmb->mii_bus = mdiobus_alloc();
217 fmb->mii_bus.name = "Fixed MDIO Bus"; 216 if (fmb->mii_bus == NULL) {
218 fmb->mii_bus.dev = &pdev->dev; 217 ret = -ENOMEM;
219 fmb->mii_bus.read = &fixed_mdio_read; 218 goto err_mdiobus_reg;
220 fmb->mii_bus.write = &fixed_mdio_write; 219 }
221 fmb->mii_bus.irq = fmb->irqs;
222 220
223 ret = mdiobus_register(&fmb->mii_bus); 221 snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "0");
222 fmb->mii_bus->name = "Fixed MDIO Bus";
223 fmb->mii_bus->priv = fmb;
224 fmb->mii_bus->parent = &pdev->dev;
225 fmb->mii_bus->read = &fixed_mdio_read;
226 fmb->mii_bus->write = &fixed_mdio_write;
227 fmb->mii_bus->irq = fmb->irqs;
228
229 ret = mdiobus_register(fmb->mii_bus);
224 if (ret) 230 if (ret)
225 goto err_mdiobus_reg; 231 goto err_mdiobus_alloc;
226 232
227 return 0; 233 return 0;
228 234
235err_mdiobus_alloc:
236 mdiobus_free(fmb->mii_bus);
229err_mdiobus_reg: 237err_mdiobus_reg:
230 platform_device_unregister(pdev); 238 platform_device_unregister(pdev);
231err_pdev: 239err_pdev:
@@ -238,7 +246,8 @@ static void __exit fixed_mdio_bus_exit(void)
238 struct fixed_mdio_bus *fmb = &platform_fmb; 246 struct fixed_mdio_bus *fmb = &platform_fmb;
239 struct fixed_phy *fp, *tmp; 247 struct fixed_phy *fp, *tmp;
240 248
241 mdiobus_unregister(&fmb->mii_bus); 249 mdiobus_unregister(fmb->mii_bus);
250 mdiobus_free(fmb->mii_bus);
242 platform_device_unregister(pdev); 251 platform_device_unregister(pdev);
243 252
244 list_for_each_entry_safe(fp, tmp, &fmb->phys, node) { 253 list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index c01b78013ddc..2576055b350b 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -165,7 +165,7 @@ struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
165{ 165{
166 struct mii_bus *bus; 166 struct mii_bus *bus;
167 167
168 bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); 168 bus = mdiobus_alloc();
169 if (!bus) 169 if (!bus)
170 return NULL; 170 return NULL;
171 171
@@ -184,7 +184,7 @@ void free_mdio_bitbang(struct mii_bus *bus)
184 struct mdiobb_ctrl *ctrl = bus->priv; 184 struct mdiobb_ctrl *ctrl = bus->priv;
185 185
186 module_put(ctrl->ops->owner); 186 module_put(ctrl->ops->owner);
187 kfree(bus); 187 mdiobus_free(bus);
188} 188}
189EXPORT_SYMBOL(free_mdio_bitbang); 189EXPORT_SYMBOL(free_mdio_bitbang);
190 190
diff --git a/drivers/net/phy/mdio-ofgpio.c b/drivers/net/phy/mdio-ofgpio.c
index 7edfc0c34835..2ff97754e574 100644
--- a/drivers/net/phy/mdio-ofgpio.c
+++ b/drivers/net/phy/mdio-ofgpio.c
@@ -122,7 +122,7 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
122 122
123 new_bus = alloc_mdio_bitbang(&bitbang->ctrl); 123 new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
124 if (!new_bus) 124 if (!new_bus)
125 goto out_free_priv; 125 goto out_free_bitbang;
126 126
127 new_bus->name = "GPIO Bitbanged MII", 127 new_bus->name = "GPIO Bitbanged MII",
128 128
@@ -142,7 +142,7 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
142 if (!strcmp(np->type, "ethernet-phy")) 142 if (!strcmp(np->type, "ethernet-phy"))
143 add_phy(new_bus, np); 143 add_phy(new_bus, np);
144 144
145 new_bus->dev = &ofdev->dev; 145 new_bus->parent = &ofdev->dev;
146 dev_set_drvdata(&ofdev->dev, new_bus); 146 dev_set_drvdata(&ofdev->dev, new_bus);
147 147
148 ret = mdiobus_register(new_bus); 148 ret = mdiobus_register(new_bus);
@@ -155,9 +155,9 @@ out_free_irqs:
155 dev_set_drvdata(&ofdev->dev, NULL); 155 dev_set_drvdata(&ofdev->dev, NULL);
156 kfree(new_bus->irq); 156 kfree(new_bus->irq);
157out_free_bus: 157out_free_bus:
158 kfree(new_bus);
159out_free_priv:
160 free_mdio_bitbang(new_bus); 158 free_mdio_bitbang(new_bus);
159out_free_bitbang:
160 kfree(bitbang);
161out: 161out:
162 return ret; 162 return ret;
163} 163}
@@ -168,11 +168,10 @@ static int mdio_ofgpio_remove(struct of_device *ofdev)
168 struct mdio_gpio_info *bitbang = bus->priv; 168 struct mdio_gpio_info *bitbang = bus->priv;
169 169
170 mdiobus_unregister(bus); 170 mdiobus_unregister(bus);
171 kfree(bus->irq);
171 free_mdio_bitbang(bus); 172 free_mdio_bitbang(bus);
172 dev_set_drvdata(&ofdev->dev, NULL); 173 dev_set_drvdata(&ofdev->dev, NULL);
173 kfree(bus->irq);
174 kfree(bitbang); 174 kfree(bitbang);
175 kfree(bus);
176 175
177 return 0; 176 return 0;
178} 177}
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 94e0b7ed76f1..d0ed1ef284a8 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -36,6 +36,43 @@
36#include <asm/uaccess.h> 36#include <asm/uaccess.h>
37 37
38/** 38/**
39 * mdiobus_alloc - allocate a mii_bus structure
40 *
41 * Description: called by a bus driver to allocate an mii_bus
42 * structure to fill in.
43 */
44struct mii_bus *mdiobus_alloc(void)
45{
46 struct mii_bus *bus;
47
48 bus = kzalloc(sizeof(*bus), GFP_KERNEL);
49 if (bus != NULL)
50 bus->state = MDIOBUS_ALLOCATED;
51
52 return bus;
53}
54EXPORT_SYMBOL(mdiobus_alloc);
55
56/**
57 * mdiobus_release - mii_bus device release callback
58 * @d: the target struct device that contains the mii_bus
59 *
60 * Description: called when the last reference to an mii_bus is
61 * dropped, to free the underlying memory.
62 */
63static void mdiobus_release(struct device *d)
64{
65 struct mii_bus *bus = to_mii_bus(d);
66 BUG_ON(bus->state != MDIOBUS_RELEASED);
67 kfree(bus);
68}
69
70static struct class mdio_bus_class = {
71 .name = "mdio_bus",
72 .dev_release = mdiobus_release,
73};
74
75/**
39 * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus 76 * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
40 * @bus: target mii_bus 77 * @bus: target mii_bus
41 * 78 *
@@ -54,55 +91,36 @@ int mdiobus_register(struct mii_bus *bus)
54 NULL == bus->write) 91 NULL == bus->write)
55 return -EINVAL; 92 return -EINVAL;
56 93
57 mutex_init(&bus->mdio_lock); 94 BUG_ON(bus->state != MDIOBUS_ALLOCATED &&
58 95 bus->state != MDIOBUS_UNREGISTERED);
59 if (bus->reset)
60 bus->reset(bus);
61
62 for (i = 0; i < PHY_MAX_ADDR; i++) {
63 struct phy_device *phydev;
64
65 if (bus->phy_mask & (1 << i)) {
66 bus->phy_map[i] = NULL;
67 continue;
68 }
69
70 phydev = get_phy_device(bus, i);
71 96
72 if (IS_ERR(phydev)) 97 bus->dev.parent = bus->parent;
73 return PTR_ERR(phydev); 98 bus->dev.class = &mdio_bus_class;
99 bus->dev.groups = NULL;
100 memcpy(bus->dev.bus_id, bus->id, MII_BUS_ID_SIZE);
74 101
75 /* There's a PHY at this address 102 err = device_register(&bus->dev);
76 * We need to set: 103 if (err) {
77 * 1) IRQ 104 printk(KERN_ERR "mii_bus %s failed to register\n", bus->id);
78 * 2) bus_id 105 return -EINVAL;
79 * 3) parent 106 }
80 * 4) bus
81 * 5) mii_bus
82 * And, we need to register it */
83 if (phydev) {
84 phydev->irq = bus->irq[i];
85 107
86 phydev->dev.parent = bus->dev; 108 bus->state = MDIOBUS_REGISTERED;
87 phydev->dev.bus = &mdio_bus_type;
88 snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, i);
89 109
90 phydev->bus = bus; 110 mutex_init(&bus->mdio_lock);
91 111
92 /* Run all of the fixups for this PHY */ 112 if (bus->reset)
93 phy_scan_fixups(phydev); 113 bus->reset(bus);
94 114
95 err = device_register(&phydev->dev); 115 for (i = 0; i < PHY_MAX_ADDR; i++) {
116 bus->phy_map[i] = NULL;
117 if ((bus->phy_mask & (1 << i)) == 0) {
118 struct phy_device *phydev;
96 119
97 if (err) { 120 phydev = mdiobus_scan(bus, i);
98 printk(KERN_ERR "phy %d failed to register\n", 121 if (IS_ERR(phydev))
99 i); 122 err = PTR_ERR(phydev);
100 phy_device_free(phydev);
101 phydev = NULL;
102 }
103 } 123 }
104
105 bus->phy_map[i] = phydev;
106 } 124 }
107 125
108 pr_info("%s: probed\n", bus->name); 126 pr_info("%s: probed\n", bus->name);
@@ -115,6 +133,10 @@ void mdiobus_unregister(struct mii_bus *bus)
115{ 133{
116 int i; 134 int i;
117 135
136 BUG_ON(bus->state != MDIOBUS_REGISTERED);
137 bus->state = MDIOBUS_UNREGISTERED;
138
139 device_unregister(&bus->dev);
118 for (i = 0; i < PHY_MAX_ADDR; i++) { 140 for (i = 0; i < PHY_MAX_ADDR; i++) {
119 if (bus->phy_map[i]) 141 if (bus->phy_map[i])
120 device_unregister(&bus->phy_map[i]->dev); 142 device_unregister(&bus->phy_map[i]->dev);
@@ -123,6 +145,122 @@ void mdiobus_unregister(struct mii_bus *bus)
123EXPORT_SYMBOL(mdiobus_unregister); 145EXPORT_SYMBOL(mdiobus_unregister);
124 146
125/** 147/**
148 * mdiobus_free - free a struct mii_bus
149 * @bus: mii_bus to free
150 *
151 * This function releases the reference to the underlying device
152 * object in the mii_bus. If this is the last reference, the mii_bus
153 * will be freed.
154 */
155void mdiobus_free(struct mii_bus *bus)
156{
157 /*
158 * For compatibility with error handling in drivers.
159 */
160 if (bus->state == MDIOBUS_ALLOCATED) {
161 kfree(bus);
162 return;
163 }
164
165 BUG_ON(bus->state != MDIOBUS_UNREGISTERED);
166 bus->state = MDIOBUS_RELEASED;
167
168 put_device(&bus->dev);
169}
170EXPORT_SYMBOL(mdiobus_free);
171
172struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
173{
174 struct phy_device *phydev;
175 int err;
176
177 phydev = get_phy_device(bus, addr);
178 if (IS_ERR(phydev) || phydev == NULL)
179 return phydev;
180
181 /* There's a PHY at this address
182 * We need to set:
183 * 1) IRQ
184 * 2) bus_id
185 * 3) parent
186 * 4) bus
187 * 5) mii_bus
188 * And, we need to register it */
189
190 phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
191
192 phydev->dev.parent = bus->parent;
193 phydev->dev.bus = &mdio_bus_type;
194 snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, addr);
195
196 phydev->bus = bus;
197
198 /* Run all of the fixups for this PHY */
199 phy_scan_fixups(phydev);
200
201 err = device_register(&phydev->dev);
202 if (err) {
203 printk(KERN_ERR "phy %d failed to register\n", addr);
204 phy_device_free(phydev);
205 phydev = NULL;
206 }
207
208 bus->phy_map[addr] = phydev;
209
210 return phydev;
211}
212EXPORT_SYMBOL(mdiobus_scan);
213
214/**
215 * mdiobus_read - Convenience function for reading a given MII mgmt register
216 * @bus: the mii_bus struct
217 * @addr: the phy address
218 * @regnum: register number to read
219 *
220 * NOTE: MUST NOT be called from interrupt context,
221 * because the bus read/write functions may wait for an interrupt
222 * to conclude the operation.
223 */
224int mdiobus_read(struct mii_bus *bus, int addr, u16 regnum)
225{
226 int retval;
227
228 BUG_ON(in_interrupt());
229
230 mutex_lock(&bus->mdio_lock);
231 retval = bus->read(bus, addr, regnum);
232 mutex_unlock(&bus->mdio_lock);
233
234 return retval;
235}
236EXPORT_SYMBOL(mdiobus_read);
237
238/**
239 * mdiobus_write - Convenience function for writing a given MII mgmt register
240 * @bus: the mii_bus struct
241 * @addr: the phy address
242 * @regnum: register number to write
243 * @val: value to write to @regnum
244 *
245 * NOTE: MUST NOT be called from interrupt context,
246 * because the bus read/write functions may wait for an interrupt
247 * to conclude the operation.
248 */
249int mdiobus_write(struct mii_bus *bus, int addr, u16 regnum, u16 val)
250{
251 int err;
252
253 BUG_ON(in_interrupt());
254
255 mutex_lock(&bus->mdio_lock);
256 err = bus->write(bus, addr, regnum, val);
257 mutex_unlock(&bus->mdio_lock);
258
259 return err;
260}
261EXPORT_SYMBOL(mdiobus_write);
262
263/**
126 * mdio_bus_match - determine if given PHY driver supports the given PHY device 264 * mdio_bus_match - determine if given PHY driver supports the given PHY device
127 * @dev: target PHY device 265 * @dev: target PHY device
128 * @drv: given PHY driver 266 * @drv: given PHY driver
@@ -174,10 +312,20 @@ EXPORT_SYMBOL(mdio_bus_type);
174 312
175int __init mdio_bus_init(void) 313int __init mdio_bus_init(void)
176{ 314{
177 return bus_register(&mdio_bus_type); 315 int ret;
316
317 ret = class_register(&mdio_bus_class);
318 if (!ret) {
319 ret = bus_register(&mdio_bus_type);
320 if (ret)
321 class_unregister(&mdio_bus_class);
322 }
323
324 return ret;
178} 325}
179 326
180void mdio_bus_exit(void) 327void mdio_bus_exit(void)
181{ 328{
329 class_unregister(&mdio_bus_class);
182 bus_unregister(&mdio_bus_type); 330 bus_unregister(&mdio_bus_type);
183} 331}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 45cc2914d347..df4e6257d4a7 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -58,55 +58,6 @@ EXPORT_SYMBOL(phy_print_status);
58 58
59 59
60/** 60/**
61 * phy_read - Convenience function for reading a given PHY register
62 * @phydev: the phy_device struct
63 * @regnum: register number to read
64 *
65 * NOTE: MUST NOT be called from interrupt context,
66 * because the bus read/write functions may wait for an interrupt
67 * to conclude the operation.
68 */
69int phy_read(struct phy_device *phydev, u16 regnum)
70{
71 int retval;
72 struct mii_bus *bus = phydev->bus;
73
74 BUG_ON(in_interrupt());
75
76 mutex_lock(&bus->mdio_lock);
77 retval = bus->read(bus, phydev->addr, regnum);
78 mutex_unlock(&bus->mdio_lock);
79
80 return retval;
81}
82EXPORT_SYMBOL(phy_read);
83
84/**
85 * phy_write - Convenience function for writing a given PHY register
86 * @phydev: the phy_device struct
87 * @regnum: register number to write
88 * @val: value to write to @regnum
89 *
90 * NOTE: MUST NOT be called from interrupt context,
91 * because the bus read/write functions may wait for an interrupt
92 * to conclude the operation.
93 */
94int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
95{
96 int err;
97 struct mii_bus *bus = phydev->bus;
98
99 BUG_ON(in_interrupt());
100
101 mutex_lock(&bus->mdio_lock);
102 err = bus->write(bus, phydev->addr, regnum, val);
103 mutex_unlock(&bus->mdio_lock);
104
105 return err;
106}
107EXPORT_SYMBOL(phy_write);
108
109/**
110 * phy_clear_interrupt - Ack the phy device's interrupt 61 * phy_clear_interrupt - Ack the phy device's interrupt
111 * @phydev: the phy_device struct 62 * @phydev: the phy_device struct
112 * 63 *
@@ -366,7 +317,8 @@ int phy_mii_ioctl(struct phy_device *phydev,
366 switch (cmd) { 317 switch (cmd) {
367 case SIOCGMIIPHY: 318 case SIOCGMIIPHY:
368 mii_data->phy_id = phydev->addr; 319 mii_data->phy_id = phydev->addr;
369 break; 320 /* fall through */
321
370 case SIOCGMIIREG: 322 case SIOCGMIIREG:
371 mii_data->val_out = phy_read(phydev, mii_data->reg_num); 323 mii_data->val_out = phy_read(phydev, mii_data->reg_num);
372 break; 324 break;
@@ -413,7 +365,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
413 break; 365 break;
414 366
415 default: 367 default:
416 return -ENOTTY; 368 return -EOPNOTSUPP;
417 } 369 }
418 370
419 return 0; 371 return 0;
@@ -728,6 +680,12 @@ static void phy_change(struct work_struct *work)
728 if (err) 680 if (err)
729 goto irq_enable_err; 681 goto irq_enable_err;
730 682
683 /* Stop timer and run the state queue now. The work function for
684 * state_queue will start the timer up again.
685 */
686 del_timer(&phydev->phy_timer);
687 schedule_work(&phydev->state_queue);
688
731 return; 689 return;
732 690
733irq_enable_err: 691irq_enable_err:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 16a0e7de5888..f11e900b437b 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -419,13 +419,14 @@ EXPORT_SYMBOL(phy_detach);
419 * 419 *
420 * Description: Writes MII_ADVERTISE with the appropriate values, 420 * Description: Writes MII_ADVERTISE with the appropriate values,
421 * after sanitizing the values to make sure we only advertise 421 * after sanitizing the values to make sure we only advertise
422 * what is supported. 422 * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
423 * hasn't changed, and > 0 if it has changed.
423 */ 424 */
424int genphy_config_advert(struct phy_device *phydev) 425int genphy_config_advert(struct phy_device *phydev)
425{ 426{
426 u32 advertise; 427 u32 advertise;
427 int adv; 428 int oldadv, adv;
428 int err; 429 int err, changed = 0;
429 430
430 /* Only allow advertising what 431 /* Only allow advertising what
431 * this PHY supports */ 432 * this PHY supports */
@@ -433,7 +434,7 @@ int genphy_config_advert(struct phy_device *phydev)
433 advertise = phydev->advertising; 434 advertise = phydev->advertising;
434 435
435 /* Setup standard advertisement */ 436 /* Setup standard advertisement */
436 adv = phy_read(phydev, MII_ADVERTISE); 437 oldadv = adv = phy_read(phydev, MII_ADVERTISE);
437 438
438 if (adv < 0) 439 if (adv < 0)
439 return adv; 440 return adv;
@@ -453,15 +454,18 @@ int genphy_config_advert(struct phy_device *phydev)
453 if (advertise & ADVERTISED_Asym_Pause) 454 if (advertise & ADVERTISED_Asym_Pause)
454 adv |= ADVERTISE_PAUSE_ASYM; 455 adv |= ADVERTISE_PAUSE_ASYM;
455 456
456 err = phy_write(phydev, MII_ADVERTISE, adv); 457 if (adv != oldadv) {
458 err = phy_write(phydev, MII_ADVERTISE, adv);
457 459
458 if (err < 0) 460 if (err < 0)
459 return err; 461 return err;
462 changed = 1;
463 }
460 464
461 /* Configure gigabit if it's supported */ 465 /* Configure gigabit if it's supported */
462 if (phydev->supported & (SUPPORTED_1000baseT_Half | 466 if (phydev->supported & (SUPPORTED_1000baseT_Half |
463 SUPPORTED_1000baseT_Full)) { 467 SUPPORTED_1000baseT_Full)) {
464 adv = phy_read(phydev, MII_CTRL1000); 468 oldadv = adv = phy_read(phydev, MII_CTRL1000);
465 469
466 if (adv < 0) 470 if (adv < 0)
467 return adv; 471 return adv;
@@ -471,13 +475,17 @@ int genphy_config_advert(struct phy_device *phydev)
471 adv |= ADVERTISE_1000HALF; 475 adv |= ADVERTISE_1000HALF;
472 if (advertise & SUPPORTED_1000baseT_Full) 476 if (advertise & SUPPORTED_1000baseT_Full)
473 adv |= ADVERTISE_1000FULL; 477 adv |= ADVERTISE_1000FULL;
474 err = phy_write(phydev, MII_CTRL1000, adv);
475 478
476 if (err < 0) 479 if (adv != oldadv) {
477 return err; 480 err = phy_write(phydev, MII_CTRL1000, adv);
481
482 if (err < 0)
483 return err;
484 changed = 1;
485 }
478 } 486 }
479 487
480 return adv; 488 return changed;
481} 489}
482EXPORT_SYMBOL(genphy_config_advert); 490EXPORT_SYMBOL(genphy_config_advert);
483 491
@@ -549,6 +557,7 @@ int genphy_restart_aneg(struct phy_device *phydev)
549 557
550 return ctl; 558 return ctl;
551} 559}
560EXPORT_SYMBOL(genphy_restart_aneg);
552 561
553 562
554/** 563/**
@@ -561,19 +570,22 @@ int genphy_restart_aneg(struct phy_device *phydev)
561 */ 570 */
562int genphy_config_aneg(struct phy_device *phydev) 571int genphy_config_aneg(struct phy_device *phydev)
563{ 572{
564 int err = 0; 573 int result = 0;
565 574
566 if (AUTONEG_ENABLE == phydev->autoneg) { 575 if (AUTONEG_ENABLE == phydev->autoneg) {
567 err = genphy_config_advert(phydev); 576 int result = genphy_config_advert(phydev);
568 577
569 if (err < 0) 578 if (result < 0) /* error */
570 return err; 579 return result;
571 580
572 err = genphy_restart_aneg(phydev); 581 /* Only restart aneg if we are advertising something different
582 * than we were before. */
583 if (result > 0)
584 result = genphy_restart_aneg(phydev);
573 } else 585 } else
574 err = genphy_setup_forced(phydev); 586 result = genphy_setup_forced(phydev);
575 587
576 return err; 588 return result;
577} 589}
578EXPORT_SYMBOL(genphy_config_aneg); 590EXPORT_SYMBOL(genphy_config_aneg);
579 591