OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 7fa63fdde703aaabaa7199ae879219737a98a3f3 Mon Sep 17 00:00:00 2001 |
2 | From: Jonas Gorski <jonas.gorski@gmail.com> |
||
3 | Date: Fri, 6 Jan 2012 12:24:18 +0100 |
||
4 | Subject: [PATCH] NET: bcm63xx_enet: move phy_(dis)connect into probe/remove |
||
5 | |||
6 | Only connect/disconnect the phy during probe and remove, not during any |
||
7 | open/close. The phy seldom changes during the runtime, and disconnecting |
||
8 | the phy during close will prevent it from keeping any configuration over |
||
9 | a down/up cycle. |
||
10 | |||
11 | Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> |
||
12 | --- |
||
13 | drivers/net/ethernet/broadcom/bcm63xx_enet.c | 158 +++++++++++++-------------- |
||
14 | 1 file changed, 78 insertions(+), 80 deletions(-) |
||
15 | |||
16 | --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c |
||
17 | +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c |
||
18 | @@ -870,10 +870,8 @@ static int bcm_enet_open(struct net_devi |
||
19 | struct bcm_enet_priv *priv; |
||
20 | struct sockaddr addr; |
||
21 | struct device *kdev; |
||
22 | - struct phy_device *phydev; |
||
23 | int i, ret; |
||
24 | unsigned int size; |
||
25 | - char phy_id[MII_BUS_ID_SIZE + 3]; |
||
26 | void *p; |
||
27 | u32 val; |
||
28 | |||
29 | @@ -881,40 +879,10 @@ static int bcm_enet_open(struct net_devi |
||
30 | kdev = &priv->pdev->dev; |
||
31 | |||
32 | if (priv->has_phy) { |
||
33 | - /* connect to PHY */ |
||
34 | - snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, |
||
35 | - priv->mii_bus->id, priv->phy_id); |
||
36 | - |
||
37 | - phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, |
||
38 | - PHY_INTERFACE_MODE_MII); |
||
39 | - |
||
40 | - if (IS_ERR(phydev)) { |
||
41 | - dev_err(kdev, "could not attach to PHY\n"); |
||
42 | - return PTR_ERR(phydev); |
||
43 | - } |
||
44 | - |
||
45 | - /* mask with MAC supported features */ |
||
46 | - phydev->supported &= (SUPPORTED_10baseT_Half | |
||
47 | - SUPPORTED_10baseT_Full | |
||
48 | - SUPPORTED_100baseT_Half | |
||
49 | - SUPPORTED_100baseT_Full | |
||
50 | - SUPPORTED_Autoneg | |
||
51 | - SUPPORTED_Pause | |
||
52 | - SUPPORTED_MII); |
||
53 | - phydev->advertising = phydev->supported; |
||
54 | - |
||
55 | - if (priv->pause_auto && priv->pause_rx && priv->pause_tx) |
||
56 | - phydev->advertising |= SUPPORTED_Pause; |
||
57 | - else |
||
58 | - phydev->advertising &= ~SUPPORTED_Pause; |
||
59 | - |
||
60 | - phy_attached_info(phydev); |
||
61 | - |
||
62 | + /* Reset state */ |
||
63 | priv->old_link = 0; |
||
64 | priv->old_duplex = -1; |
||
65 | priv->old_pause = -1; |
||
66 | - } else { |
||
67 | - phydev = NULL; |
||
68 | } |
||
69 | |||
70 | /* mask all interrupts and request them */ |
||
71 | @@ -924,7 +892,7 @@ static int bcm_enet_open(struct net_devi |
||
72 | |||
73 | ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev); |
||
74 | if (ret) |
||
75 | - goto out_phy_disconnect; |
||
76 | + return ret; |
||
77 | |||
78 | ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, 0, |
||
79 | dev->name, dev); |
||
80 | @@ -1086,8 +1054,8 @@ static int bcm_enet_open(struct net_devi |
||
81 | enet_dmac_writel(priv, priv->dma_chan_int_mask, |
||
82 | ENETDMAC_IRMASK, priv->tx_chan); |
||
83 | |||
84 | - if (phydev) |
||
85 | - phy_start(phydev); |
||
86 | + if (priv->has_phy) |
||
87 | + phy_start(dev->phydev); |
||
88 | else |
||
89 | bcm_enet_adjust_link(dev); |
||
90 | |||
91 | @@ -1128,10 +1096,6 @@ out_freeirq_rx: |
||
92 | out_freeirq: |
||
93 | free_irq(dev->irq, dev); |
||
94 | |||
95 | -out_phy_disconnect: |
||
96 | - if (phydev) |
||
97 | - phy_disconnect(phydev); |
||
98 | - |
||
99 | return ret; |
||
100 | } |
||
101 | |||
102 | @@ -1236,10 +1200,6 @@ static int bcm_enet_stop(struct net_devi |
||
103 | free_irq(priv->irq_rx, dev); |
||
104 | free_irq(dev->irq, dev); |
||
105 | |||
106 | - /* release phy */ |
||
107 | - if (priv->has_phy) |
||
108 | - phy_disconnect(dev->phydev); |
||
109 | - |
||
110 | return 0; |
||
111 | } |
||
112 | |||
113 | @@ -1821,14 +1781,46 @@ static int bcm_enet_probe(struct platfor |
||
114 | |||
115 | /* do minimal hardware init to be able to probe mii bus */ |
||
116 | bcm_enet_hw_preinit(priv); |
||
117 | + spin_lock_init(&priv->rx_lock); |
||
118 | + |
||
119 | + /* init rx timeout (used for oom) */ |
||
120 | + init_timer(&priv->rx_timeout); |
||
121 | + priv->rx_timeout.function = bcm_enet_refill_rx_timer; |
||
122 | + priv->rx_timeout.data = (unsigned long)dev; |
||
123 | + |
||
124 | + /* init the mib update lock&work */ |
||
125 | + mutex_init(&priv->mib_update_lock); |
||
126 | + INIT_WORK(&priv->mib_update_task, bcm_enet_update_mib_counters_defer); |
||
127 | + |
||
128 | + /* zero mib counters */ |
||
129 | + for (i = 0; i < ENET_MIB_REG_COUNT; i++) |
||
130 | + enet_writel(priv, 0, ENET_MIB_REG(i)); |
||
131 | + |
||
132 | + /* register netdevice */ |
||
133 | + dev->netdev_ops = &bcm_enet_ops; |
||
134 | + netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16); |
||
135 | + |
||
136 | + dev->ethtool_ops = &bcm_enet_ethtool_ops; |
||
137 | + SET_NETDEV_DEV(dev, &pdev->dev); |
||
138 | + |
||
139 | + ret = register_netdev(dev); |
||
140 | + if (ret) |
||
141 | + goto out_uninit_hw; |
||
142 | + |
||
143 | + netif_carrier_off(dev); |
||
144 | + platform_set_drvdata(pdev, dev); |
||
145 | + priv->pdev = pdev; |
||
146 | + priv->net_dev = dev; |
||
147 | |||
148 | /* MII bus registration */ |
||
149 | if (priv->has_phy) { |
||
150 | + struct phy_device *phydev; |
||
151 | + char phy_id[MII_BUS_ID_SIZE + 3]; |
||
152 | |||
153 | priv->mii_bus = mdiobus_alloc(); |
||
154 | if (!priv->mii_bus) { |
||
155 | ret = -ENOMEM; |
||
156 | - goto out_uninit_hw; |
||
157 | + goto out_unregister_netdev; |
||
158 | } |
||
159 | |||
160 | bus = priv->mii_bus; |
||
161 | @@ -1852,6 +1844,35 @@ static int bcm_enet_probe(struct platfor |
||
162 | dev_err(&pdev->dev, "unable to register mdio bus\n"); |
||
163 | goto out_free_mdio; |
||
164 | } |
||
165 | + |
||
166 | + /* connect to PHY */ |
||
167 | + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, |
||
168 | + priv->mii_bus->id, priv->phy_id); |
||
169 | + |
||
170 | + phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, |
||
171 | + PHY_INTERFACE_MODE_MII); |
||
172 | + |
||
173 | + if (IS_ERR(phydev)) { |
||
174 | + dev_err(&pdev->dev, "could not attach to PHY\n"); |
||
175 | + goto out_unregister_mdio; |
||
176 | + } |
||
177 | + |
||
178 | + /* mask with MAC supported features */ |
||
179 | + phydev->supported &= (SUPPORTED_10baseT_Half | |
||
180 | + SUPPORTED_10baseT_Full | |
||
181 | + SUPPORTED_100baseT_Half | |
||
182 | + SUPPORTED_100baseT_Full | |
||
183 | + SUPPORTED_Autoneg | |
||
184 | + SUPPORTED_Pause | |
||
185 | + SUPPORTED_MII); |
||
186 | + phydev->advertising = phydev->supported; |
||
187 | + |
||
188 | + if (priv->pause_auto && priv->pause_rx && priv->pause_tx) |
||
189 | + phydev->advertising |= SUPPORTED_Pause; |
||
190 | + else |
||
191 | + phydev->advertising &= ~SUPPORTED_Pause; |
||
192 | + |
||
193 | + phy_attached_info(phydev); |
||
194 | } else { |
||
195 | |||
196 | /* run platform code to initialize PHY device */ |
||
197 | @@ -1859,44 +1880,16 @@ static int bcm_enet_probe(struct platfor |
||
198 | pd->mii_config(dev, 1, bcm_enet_mdio_read_mii, |
||
199 | bcm_enet_mdio_write_mii)) { |
||
200 | dev_err(&pdev->dev, "unable to configure mdio bus\n"); |
||
201 | - goto out_uninit_hw; |
||
202 | + goto out_unregister_netdev; |
||
203 | } |
||
204 | } |
||
205 | |||
206 | - spin_lock_init(&priv->rx_lock); |
||
207 | - |
||
208 | - /* init rx timeout (used for oom) */ |
||
209 | - init_timer(&priv->rx_timeout); |
||
210 | - priv->rx_timeout.function = bcm_enet_refill_rx_timer; |
||
211 | - priv->rx_timeout.data = (unsigned long)dev; |
||
212 | - |
||
213 | - /* init the mib update lock&work */ |
||
214 | - mutex_init(&priv->mib_update_lock); |
||
215 | - INIT_WORK(&priv->mib_update_task, bcm_enet_update_mib_counters_defer); |
||
216 | - |
||
217 | - /* zero mib counters */ |
||
218 | - for (i = 0; i < ENET_MIB_REG_COUNT; i++) |
||
219 | - enet_writel(priv, 0, ENET_MIB_REG(i)); |
||
220 | - |
||
221 | - /* register netdevice */ |
||
222 | - dev->netdev_ops = &bcm_enet_ops; |
||
223 | - netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16); |
||
224 | - |
||
225 | - dev->ethtool_ops = &bcm_enet_ethtool_ops; |
||
226 | - SET_NETDEV_DEV(dev, &pdev->dev); |
||
227 | - |
||
228 | - ret = register_netdev(dev); |
||
229 | - if (ret) |
||
230 | - goto out_unregister_mdio; |
||
231 | - |
||
232 | - netif_carrier_off(dev); |
||
233 | - platform_set_drvdata(pdev, dev); |
||
234 | - priv->pdev = pdev; |
||
235 | - priv->net_dev = dev; |
||
236 | - |
||
237 | return 0; |
||
238 | |||
239 | out_unregister_mdio: |
||
240 | + if (dev->phydev) |
||
241 | + phy_disconnect(dev->phydev); |
||
242 | + |
||
243 | if (priv->mii_bus) |
||
244 | mdiobus_unregister(priv->mii_bus); |
||
245 | |||
246 | @@ -1904,6 +1897,9 @@ out_free_mdio: |
||
247 | if (priv->mii_bus) |
||
248 | mdiobus_free(priv->mii_bus); |
||
249 | |||
250 | +out_unregister_netdev: |
||
251 | + unregister_netdev(dev); |
||
252 | + |
||
253 | out_uninit_hw: |
||
254 | /* turn off mdc clock */ |
||
255 | enet_writel(priv, 0, ENET_MIISC_REG); |
||
256 | @@ -1934,6 +1930,7 @@ static int bcm_enet_remove(struct platfo |
||
257 | enet_writel(priv, 0, ENET_MIISC_REG); |
||
258 | |||
259 | if (priv->has_phy) { |
||
260 | + phy_disconnect(dev->phydev); |
||
261 | mdiobus_unregister(priv->mii_bus); |
||
262 | mdiobus_free(priv->mii_bus); |
||
263 | } else { |