Commit a79d8e93d300adb84cccc38ac396cfb118c238ad

Authored by Vitaly Bordug
Committed by Kumar Gala
1 parent 9b6d19dd1d

phy/fixed.c: rework to not duplicate PHY layer functionality

With that patch fixed.c now fully emulates MDIO bus, thus no need
to duplicate PHY layer functionality. That, in turn, drastically
simplifies the code, and drops down line count.

As an additional bonus, now there is no need to register MDIO bus
for each PHY, all emulated PHYs placed on the platform fixed MDIO bus.
There is also no more need to pre-allocate PHYs via .config option,
this is all now handled dynamically.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
Acked-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>

Showing 3 changed files with 195 additions and 333 deletions Side-by-side Diff

drivers/net/phy/Kconfig
... ... @@ -61,34 +61,12 @@
61 61 Currently supports the IP175C PHY.
62 62  
63 63 config FIXED_PHY
64   - tristate "Drivers for PHY emulation on fixed speed/link"
  64 + bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
65 65 ---help---
66   - Adds the driver to PHY layer to cover the boards that do not have any PHY bound,
67   - but with the ability to manipulate the speed/link in software. The relevant MII
68   - speed/duplex parameters could be effectively handled in a user-specified function.
69   - Currently tested with mpc866ads.
  66 + Adds the platform "fixed" MDIO Bus to cover the boards that use
  67 + PHYs that are not connected to the real MDIO bus.
70 68  
71   -config FIXED_MII_10_FDX
72   - bool "Emulation for 10M Fdx fixed PHY behavior"
73   - depends on FIXED_PHY
74   -
75   -config FIXED_MII_100_FDX
76   - bool "Emulation for 100M Fdx fixed PHY behavior"
77   - depends on FIXED_PHY
78   -
79   -config FIXED_MII_1000_FDX
80   - bool "Emulation for 1000M Fdx fixed PHY behavior"
81   - depends on FIXED_PHY
82   -
83   -config FIXED_MII_AMNT
84   - int "Number of emulated PHYs to allocate "
85   - depends on FIXED_PHY
86   - default "1"
87   - ---help---
88   - Sometimes it is required to have several independent emulated
89   - PHYs on the bus (in case of multi-eth but phy-less HW for instance).
90   - This control will have specified number allocated for each fixed
91   - PHY type enabled.
  69 + Currently tested with mpc866ads and mpc8349e-mitx.
92 70  
93 71 config MDIO_BITBANG
94 72 tristate "Support for bitbanged MDIO buses"
drivers/net/phy/fixed.c
1 1 /*
2   - * drivers/net/phy/fixed.c
  2 + * Fixed MDIO bus (MDIO bus emulation with fixed PHYs)
3 3 *
4   - * Driver for fixed PHYs, when transceiver is able to operate in one fixed mode.
  4 + * Author: Vitaly Bordug <vbordug@ru.mvista.com>
  5 + * Anton Vorontsov <avorontsov@ru.mvista.com>
5 6 *
6   - * Author: Vitaly Bordug
  7 + * Copyright (c) 2006-2007 MontaVista Software, Inc.
7 8 *
8   - * Copyright (c) 2006 MontaVista Software, Inc.
9   - *
10 9 * This program is free software; you can redistribute it and/or modify it
11 10 * under the terms of the GNU General Public License as published by the
12 11 * Free Software Foundation; either version 2 of the License, or (at your
13 12 * option) any later version.
14   - *
15 13 */
  14 +
16 15 #include <linux/kernel.h>
17   -#include <linux/string.h>
18   -#include <linux/errno.h>
19   -#include <linux/unistd.h>
20   -#include <linux/slab.h>
21   -#include <linux/interrupt.h>
22   -#include <linux/init.h>
23   -#include <linux/delay.h>
24   -#include <linux/netdevice.h>
25   -#include <linux/etherdevice.h>
26   -#include <linux/skbuff.h>
27   -#include <linux/spinlock.h>
28   -#include <linux/mm.h>
29 16 #include <linux/module.h>
  17 +#include <linux/platform_device.h>
  18 +#include <linux/list.h>
30 19 #include <linux/mii.h>
31   -#include <linux/ethtool.h>
32 20 #include <linux/phy.h>
33 21 #include <linux/phy_fixed.h>
34 22  
35   -#include <asm/io.h>
36   -#include <asm/irq.h>
37   -#include <asm/uaccess.h>
  23 +#define MII_REGS_NUM 29
38 24  
39   -/* we need to track the allocated pointers in order to free them on exit */
40   -static struct fixed_info *fixed_phy_ptrs[CONFIG_FIXED_MII_AMNT*MAX_PHY_AMNT];
  25 +struct fixed_mdio_bus {
  26 + int irqs[PHY_MAX_ADDR];
  27 + struct mii_bus mii_bus;
  28 + struct list_head phys;
  29 +};
41 30  
42   -/*-----------------------------------------------------------------------------
43   - * If something weird is required to be done with link/speed,
44   - * network driver is able to assign a function to implement this.
45   - * May be useful for PHY's that need to be software-driven.
46   - *-----------------------------------------------------------------------------*/
47   -int fixed_mdio_set_link_update(struct phy_device *phydev,
48   - int (*link_update) (struct net_device *,
49   - struct fixed_phy_status *))
50   -{
51   - struct fixed_info *fixed;
  31 +struct fixed_phy {
  32 + int id;
  33 + u16 regs[MII_REGS_NUM];
  34 + struct phy_device *phydev;
  35 + struct fixed_phy_status status;
  36 + int (*link_update)(struct net_device *, struct fixed_phy_status *);
  37 + struct list_head node;
  38 +};
52 39  
53   - if (link_update == NULL)
54   - return -EINVAL;
  40 +static struct platform_device *pdev;
  41 +static struct fixed_mdio_bus platform_fmb = {
  42 + .phys = LIST_HEAD_INIT(platform_fmb.phys),
  43 +};
55 44  
56   - if (phydev) {
57   - if (phydev->bus) {
58   - fixed = phydev->bus->priv;
59   - fixed->link_update = link_update;
60   - return 0;
61   - }
62   - }
63   - return -EINVAL;
64   -}
65   -
66   -EXPORT_SYMBOL(fixed_mdio_set_link_update);
67   -
68   -struct fixed_info *fixed_mdio_get_phydev (int phydev_ind)
  45 +static int fixed_phy_update_regs(struct fixed_phy *fp)
69 46 {
70   - if (phydev_ind >= MAX_PHY_AMNT)
71   - return NULL;
72   - return fixed_phy_ptrs[phydev_ind];
73   -}
74   -
75   -EXPORT_SYMBOL(fixed_mdio_get_phydev);
76   -
77   -/*-----------------------------------------------------------------------------
78   - * This is used for updating internal mii regs from the status
79   - *-----------------------------------------------------------------------------*/
80   -#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX)
81   -static int fixed_mdio_update_regs(struct fixed_info *fixed)
82   -{
83   - u16 *regs = fixed->regs;
84   - u16 bmsr = 0;
  47 + u16 bmsr = BMSR_ANEGCAPABLE;
85 48 u16 bmcr = 0;
  49 + u16 lpagb = 0;
  50 + u16 lpa = 0;
86 51  
87   - if (!regs) {
88   - printk(KERN_ERR "%s: regs not set up", __FUNCTION__);
89   - return -EINVAL;
90   - }
91   -
92   - if (fixed->phy_status.link)
93   - bmsr |= BMSR_LSTATUS;
94   -
95   - if (fixed->phy_status.duplex) {
  52 + if (fp->status.duplex) {
96 53 bmcr |= BMCR_FULLDPLX;
97 54  
98   - switch (fixed->phy_status.speed) {
  55 + switch (fp->status.speed) {
  56 + case 1000:
  57 + bmsr |= BMSR_ESTATEN;
  58 + bmcr |= BMCR_SPEED1000;
  59 + lpagb |= LPA_1000FULL;
  60 + break;
99 61 case 100:
100 62 bmsr |= BMSR_100FULL;
101 63 bmcr |= BMCR_SPEED100;
  64 + lpa |= LPA_100FULL;
102 65 break;
103   -
104 66 case 10:
105 67 bmsr |= BMSR_10FULL;
  68 + lpa |= LPA_10FULL;
106 69 break;
  70 + default:
  71 + printk(KERN_WARNING "fixed phy: unknown speed\n");
  72 + return -EINVAL;
107 73 }
108 74 } else {
109   - switch (fixed->phy_status.speed) {
  75 + switch (fp->status.speed) {
  76 + case 1000:
  77 + bmsr |= BMSR_ESTATEN;
  78 + bmcr |= BMCR_SPEED1000;
  79 + lpagb |= LPA_1000HALF;
  80 + break;
110 81 case 100:
111 82 bmsr |= BMSR_100HALF;
112 83 bmcr |= BMCR_SPEED100;
  84 + lpa |= LPA_100HALF;
113 85 break;
114   -
115 86 case 10:
116   - bmsr |= BMSR_100HALF;
  87 + bmsr |= BMSR_10HALF;
  88 + lpa |= LPA_10HALF;
117 89 break;
  90 + default:
  91 + printk(KERN_WARNING "fixed phy: unknown speed\n");
  92 + return -EINVAL;
118 93 }
119 94 }
120 95  
121   - regs[MII_BMCR] = bmcr;
122   - regs[MII_BMSR] = bmsr | 0x800; /*we are always capable of 10 hdx */
  96 + if (fp->status.link)
  97 + bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
123 98  
  99 + if (fp->status.pause)
  100 + lpa |= LPA_PAUSE_CAP;
  101 +
  102 + if (fp->status.asym_pause)
  103 + lpa |= LPA_PAUSE_ASYM;
  104 +
  105 + fp->regs[MII_PHYSID1] = fp->id >> 16;
  106 + fp->regs[MII_PHYSID2] = fp->id;
  107 +
  108 + fp->regs[MII_BMSR] = bmsr;
  109 + fp->regs[MII_BMCR] = bmcr;
  110 + fp->regs[MII_LPA] = lpa;
  111 + fp->regs[MII_STAT1000] = lpagb;
  112 +
124 113 return 0;
125 114 }
126 115  
127   -static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location)
  116 +static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num)
128 117 {
129   - struct fixed_info *fixed = bus->priv;
  118 + struct fixed_mdio_bus *fmb = container_of(bus, struct fixed_mdio_bus,
  119 + mii_bus);
  120 + struct fixed_phy *fp;
130 121  
131   - /* if user has registered link update callback, use it */
132   - if (fixed->phydev)
133   - if (fixed->phydev->attached_dev) {
134   - if (fixed->link_update) {
135   - fixed->link_update(fixed->phydev->attached_dev,
136   - &fixed->phy_status);
137   - fixed_mdio_update_regs(fixed);
  122 + if (reg_num >= MII_REGS_NUM)
  123 + return -1;
  124 +
  125 + list_for_each_entry(fp, &fmb->phys, node) {
  126 + if (fp->id == phy_id) {
  127 + /* Issue callback if user registered it. */
  128 + if (fp->link_update) {
  129 + fp->link_update(fp->phydev->attached_dev,
  130 + &fp->status);
  131 + fixed_phy_update_regs(fp);
138 132 }
  133 + return fp->regs[reg_num];
139 134 }
  135 + }
140 136  
141   - if ((unsigned int)location >= fixed->regs_num)
142   - return -1;
143   - return fixed->regs[location];
  137 + return 0xFFFF;
144 138 }
145 139  
146   -static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location,
147   - u16 val)
  140 +static int fixed_mdio_write(struct mii_bus *bus, int phy_id, int reg_num,
  141 + u16 val)
148 142 {
149   - /* do nothing for now */
150 143 return 0;
151 144 }
152 145  
153   -static int fixed_mii_reset(struct mii_bus *bus)
  146 +/*
  147 + * If something weird is required to be done with link/speed,
  148 + * network driver is able to assign a function to implement this.
  149 + * May be useful for PHY's that need to be software-driven.
  150 + */
  151 +int fixed_phy_set_link_update(struct phy_device *phydev,
  152 + int (*link_update)(struct net_device *,
  153 + struct fixed_phy_status *))
154 154 {
155   - /*nothing here - no way/need to reset it */
156   - return 0;
157   -}
158   -#endif
  155 + struct fixed_mdio_bus *fmb = &platform_fmb;
  156 + struct fixed_phy *fp;
159 157  
160   -static int fixed_config_aneg(struct phy_device *phydev)
161   -{
162   - /* :TODO:03/13/2006 09:45:37 PM::
163   - The full autoneg funcionality can be emulated,
164   - but no need to have anything here for now
165   - */
166   - return 0;
167   -}
  158 + if (!link_update || !phydev || !phydev->bus)
  159 + return -EINVAL;
168 160  
169   -/*-----------------------------------------------------------------------------
170   - * the manual bind will do the magic - with phy_id_mask == 0
171   - * match will never return true...
172   - *-----------------------------------------------------------------------------*/
173   -static struct phy_driver fixed_mdio_driver = {
174   - .name = "Fixed PHY",
175   -#ifdef CONFIG_FIXED_MII_1000_FDX
176   - .features = PHY_GBIT_FEATURES,
177   -#else
178   - .features = PHY_BASIC_FEATURES,
179   -#endif
180   - .config_aneg = fixed_config_aneg,
181   - .read_status = genphy_read_status,
182   - .driver = { .owner = THIS_MODULE, },
183   -};
  161 + list_for_each_entry(fp, &fmb->phys, node) {
  162 + if (fp->id == phydev->phy_id) {
  163 + fp->link_update = link_update;
  164 + fp->phydev = phydev;
  165 + return 0;
  166 + }
  167 + }
184 168  
185   -static void fixed_mdio_release(struct device *dev)
186   -{
187   - struct phy_device *phydev = container_of(dev, struct phy_device, dev);
188   - struct mii_bus *bus = phydev->bus;
189   - struct fixed_info *fixed = bus->priv;
190   -
191   - kfree(phydev);
192   - kfree(bus->dev);
193   - kfree(bus);
194   - kfree(fixed->regs);
195   - kfree(fixed);
  169 + return -ENOENT;
196 170 }
  171 +EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
197 172  
198   -/*-----------------------------------------------------------------------------
199   - * This func is used to create all the necessary stuff, bind
200   - * the fixed phy driver and register all it on the mdio_bus_type.
201   - * speed is either 10 or 100 or 1000, duplex is boolean.
202   - * number is used to create multiple fixed PHYs, so that several devices can
203   - * utilize them simultaneously.
204   - *
205   - * The device on mdio bus will look like [bus_id]:[phy_id],
206   - * bus_id = number
207   - * phy_id = speed+duplex.
208   - *-----------------------------------------------------------------------------*/
209   -#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX)
210   -struct fixed_info *fixed_mdio_register_device(
211   - int bus_id, int speed, int duplex, u8 phy_id)
  173 +int fixed_phy_add(unsigned int irq, int phy_id,
  174 + struct fixed_phy_status *status)
212 175 {
213   - struct mii_bus *new_bus;
214   - struct fixed_info *fixed;
215   - struct phy_device *phydev;
216   - int err;
  176 + int ret;
  177 + struct fixed_mdio_bus *fmb = &platform_fmb;
  178 + struct fixed_phy *fp;
217 179  
218   - struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL);
  180 + fp = kzalloc(sizeof(*fp), GFP_KERNEL);
  181 + if (!fp)
  182 + return -ENOMEM;
219 183  
220   - if (dev == NULL)
221   - goto err_dev_alloc;
  184 + memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM);
222 185  
223   - new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
  186 + fmb->irqs[phy_id] = irq;
224 187  
225   - if (new_bus == NULL)
226   - goto err_bus_alloc;
  188 + fp->id = phy_id;
  189 + fp->status = *status;
227 190  
228   - fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL);
  191 + ret = fixed_phy_update_regs(fp);
  192 + if (ret)
  193 + goto err_regs;
229 194  
230   - if (fixed == NULL)
231   - goto err_fixed_alloc;
  195 + list_add_tail(&fp->node, &fmb->phys);
232 196  
233   - fixed->regs = kzalloc(MII_REGS_NUM * sizeof(int), GFP_KERNEL);
234   - if (NULL == fixed->regs)
235   - goto err_fixed_regs_alloc;
  197 + return 0;
236 198  
237   - fixed->regs_num = MII_REGS_NUM;
238   - fixed->phy_status.speed = speed;
239   - fixed->phy_status.duplex = duplex;
240   - fixed->phy_status.link = 1;
  199 +err_regs:
  200 + kfree(fp);
  201 + return ret;
  202 +}
  203 +EXPORT_SYMBOL_GPL(fixed_phy_add);
241 204  
242   - new_bus->name = "Fixed MII Bus";
243   - new_bus->read = &fixed_mii_read;
244   - new_bus->write = &fixed_mii_write;
245   - new_bus->reset = &fixed_mii_reset;
246   - /*set up workspace */
247   - fixed_mdio_update_regs(fixed);
248   - new_bus->priv = fixed;
  205 +static int __init fixed_mdio_bus_init(void)
  206 +{
  207 + struct fixed_mdio_bus *fmb = &platform_fmb;
  208 + int ret;
249 209  
250   - new_bus->dev = dev;
251   - dev_set_drvdata(dev, new_bus);
  210 + pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
  211 + if (!pdev) {
  212 + ret = -ENOMEM;
  213 + goto err_pdev;
  214 + }
252 215  
253   - /* create phy_device and register it on the mdio bus */
254   - phydev = phy_device_create(new_bus, 0, 0);
255   - if (phydev == NULL)
256   - goto err_phy_dev_create;
  216 + fmb->mii_bus.id = 0;
  217 + fmb->mii_bus.name = "Fixed MDIO Bus";
  218 + fmb->mii_bus.dev = &pdev->dev;
  219 + fmb->mii_bus.read = &fixed_mdio_read;
  220 + fmb->mii_bus.write = &fixed_mdio_write;
  221 + fmb->mii_bus.irq = fmb->irqs;
257 222  
258   - /*
259   - * Put the phydev pointer into the fixed pack so that bus read/write
260   - * code could be able to access for instance attached netdev. Well it
261   - * doesn't have to do so, only in case of utilizing user-specified
262   - * link-update...
263   - */
  223 + ret = mdiobus_register(&fmb->mii_bus);
  224 + if (ret)
  225 + goto err_mdiobus_reg;
264 226  
265   - fixed->phydev = phydev;
266   - phydev->speed = speed;
267   - phydev->duplex = duplex;
  227 + return 0;
268 228  
269   - phydev->irq = PHY_IGNORE_INTERRUPT;
270   - phydev->dev.bus = &mdio_bus_type;
  229 +err_mdiobus_reg:
  230 + platform_device_unregister(pdev);
  231 +err_pdev:
  232 + return ret;
  233 +}
  234 +module_init(fixed_mdio_bus_init);
271 235  
272   - snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
273   - PHY_ID_FMT, bus_id, phy_id);
  236 +static void __exit fixed_mdio_bus_exit(void)
  237 +{
  238 + struct fixed_mdio_bus *fmb = &platform_fmb;
  239 + struct fixed_phy *fp;
274 240  
275   - phydev->bus = new_bus;
  241 + mdiobus_unregister(&fmb->mii_bus);
  242 + platform_device_unregister(pdev);
276 243  
277   - phydev->dev.driver = &fixed_mdio_driver.driver;
278   - phydev->dev.release = fixed_mdio_release;
279   - err = phydev->dev.driver->probe(&phydev->dev);
280   - if (err < 0) {
281   - printk(KERN_ERR "Phy %s: problems with fixed driver\n",
282   - phydev->dev.bus_id);
283   - goto err_out;
  244 + list_for_each_entry(fp, &fmb->phys, node) {
  245 + list_del(&fp->node);
  246 + kfree(fp);
284 247 }
285   - err = device_register(&phydev->dev);
286   - if (err) {
287   - printk(KERN_ERR "Phy %s failed to register\n",
288   - phydev->dev.bus_id);
289   - goto err_out;
290   - }
291   - //phydev->state = PHY_RUNNING; /* make phy go up quick, but in 10Mbit/HDX
292   - return fixed;
293   -
294   -err_out:
295   - kfree(phydev);
296   -err_phy_dev_create:
297   - kfree(fixed->regs);
298   -err_fixed_regs_alloc:
299   - kfree(fixed);
300   -err_fixed_alloc:
301   - kfree(new_bus);
302   -err_bus_alloc:
303   - kfree(dev);
304   -err_dev_alloc:
305   -
306   - return NULL;
307   -
308 248 }
309   -#endif
  249 +module_exit(fixed_mdio_bus_exit);
310 250  
311   -MODULE_DESCRIPTION("Fixed PHY device & driver for PAL");
  251 +MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)");
312 252 MODULE_AUTHOR("Vitaly Bordug");
313 253 MODULE_LICENSE("GPL");
314   -
315   -static int __init fixed_init(void)
316   -{
317   - int cnt = 0;
318   - int i;
319   -/* register on the bus... Not expected to be matched
320   - * with anything there...
321   - *
322   - */
323   - phy_driver_register(&fixed_mdio_driver);
324   -
325   -/* We will create several mdio devices here, and will bound the upper
326   - * driver to them.
327   - *
328   - * Then the external software can lookup the phy bus by searching
329   - * for 0:101, to be connected to the virtual 100M Fdx phy.
330   - *
331   - * In case several virtual PHYs required, the bus_id will be in form
332   - * [num]:[duplex]+[speed], which make it able even to define
333   - * driver-specific link control callback, if for instance PHY is
334   - * completely SW-driven.
335   - */
336   - for (i=1; i <= CONFIG_FIXED_MII_AMNT; i++) {
337   -#ifdef CONFIG_FIXED_MII_1000_FDX
338   - fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(0, 1000, 1, i);
339   -#endif
340   -#ifdef CONFIG_FIXED_MII_100_FDX
341   - fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(1, 100, 1, i);
342   -#endif
343   -#ifdef CONFIG_FIXED_MII_10_FDX
344   - fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(2, 10, 1, i);
345   -#endif
346   - }
347   -
348   - return 0;
349   -}
350   -
351   -static void __exit fixed_exit(void)
352   -{
353   - int i;
354   -
355   - phy_driver_unregister(&fixed_mdio_driver);
356   - for (i=0; i < MAX_PHY_AMNT; i++)
357   - if ( fixed_phy_ptrs[i] )
358   - device_unregister(&fixed_phy_ptrs[i]->phydev->dev);
359   -}
360   -
361   -module_init(fixed_init);
362   -module_exit(fixed_exit);
include/linux/phy_fixed.h
1 1 #ifndef __PHY_FIXED_H
2 2 #define __PHY_FIXED_H
3 3  
4   -#define MII_REGS_NUM 29
5   -
6   -/* max number of virtual phy stuff */
7   -#define MAX_PHY_AMNT 10
8   -/*
9   - The idea is to emulate normal phy behavior by responding with
10   - pre-defined values to mii BMCR read, so that read_status hook could
11   - take all the needed info.
12   -*/
13   -
14 4 struct fixed_phy_status {
15   - u8 link;
16   - u16 speed;
17   - u8 duplex;
  5 + int link;
  6 + int speed;
  7 + int duplex;
  8 + int pause;
  9 + int asym_pause;
18 10 };
19 11  
20   -/*-----------------------------------------------------------------------------
21   - * Private information hoder for mii_bus
22   - *-----------------------------------------------------------------------------*/
23   -struct fixed_info {
24   - u16 *regs;
25   - u8 regs_num;
26   - struct fixed_phy_status phy_status;
27   - struct phy_device *phydev; /* pointer to the container */
28   - /* link & speed cb */
29   - int (*link_update) (struct net_device *, struct fixed_phy_status *);
  12 +#ifdef CONFIG_FIXED_PHY
  13 +extern int fixed_phy_add(unsigned int irq, int phy_id,
  14 + struct fixed_phy_status *status);
  15 +#else
  16 +static inline int fixed_phy_add(unsigned int irq, int phy_id,
  17 + struct fixed_phy_status *status)
  18 +{
  19 + return -ENODEV;
  20 +}
  21 +#endif /* CONFIG_FIXED_PHY */
30 22  
31   -};
32   -
33   -
34   -int fixed_mdio_set_link_update(struct phy_device *,
35   - int (*link_update) (struct net_device *, struct fixed_phy_status *));
36   -struct fixed_info *fixed_mdio_get_phydev (int phydev_ind);
  23 +/*
  24 + * This function issued only by fixed_phy-aware drivers, no need
  25 + * protect it with #ifdef
  26 + */
  27 +extern int fixed_phy_set_link_update(struct phy_device *phydev,
  28 + int (*link_update)(struct net_device *,
  29 + struct fixed_phy_status *));
37 30  
38 31 #endif /* __PHY_FIXED_H */