atheros: update to 3.3.4 (based on work by acoul), fix mvswitch driver for newer...
[openwrt/staging/wigyori.git] / target / linux / generic / files / drivers / net / phy / mvswitch.c
1 /*
2 * Marvell 88E6060 switch driver
3 * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License v2 as published by the
7 * Free Software Foundation
8 */
9 #include <linux/kernel.h>
10 #include <linux/string.h>
11 #include <linux/errno.h>
12 #include <linux/unistd.h>
13 #include <linux/slab.h>
14 #include <linux/interrupt.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/netdevice.h>
18 #include <linux/etherdevice.h>
19 #include <linux/skbuff.h>
20 #include <linux/spinlock.h>
21 #include <linux/mm.h>
22 #include <linux/module.h>
23 #include <linux/mii.h>
24 #include <linux/ethtool.h>
25 #include <linux/phy.h>
26 #include <linux/if_vlan.h>
27
28 #include <asm/io.h>
29 #include <asm/irq.h>
30 #include <asm/uaccess.h>
31 #include "mvswitch.h"
32
33 /* Undefine this to use trailer mode instead.
34 * I don't know if header mode works with all chips */
35 #define HEADER_MODE 1
36
37 MODULE_DESCRIPTION("Marvell 88E6060 Switch driver");
38 MODULE_AUTHOR("Felix Fietkau");
39 MODULE_LICENSE("GPL");
40
41 #define MVSWITCH_MAGIC 0x88E6060
42
43 struct mvswitch_priv {
44 const struct net_device_ops *ndo_old;
45 struct net_device_ops ndo;
46 u8 vlans[16];
47 };
48
49 #define to_mvsw(_phy) ((struct mvswitch_priv *) (_phy)->priv)
50
51 static inline u16
52 r16(struct phy_device *phydev, int addr, int reg)
53 {
54 return phydev->bus->read(phydev->bus, addr, reg);
55 }
56
57 static inline void
58 w16(struct phy_device *phydev, int addr, int reg, u16 val)
59 {
60 phydev->bus->write(phydev->bus, addr, reg, val);
61 }
62
63
64 static int
65 mvswitch_mangle_tx(struct sk_buff *skb, struct net_device *dev)
66 {
67 struct mvswitch_priv *priv;
68 char *buf = NULL;
69 u16 vid;
70
71 priv = dev->phy_ptr;
72 if (unlikely(!priv))
73 goto error;
74
75 if (unlikely(skb->len < 16))
76 goto error;
77
78 #ifdef HEADER_MODE
79 if (__vlan_hwaccel_get_tag(skb, &vid))
80 goto error;
81
82 if (skb_cloned(skb) || (skb->len <= 62) || (skb_headroom(skb) < MV_HEADER_SIZE)) {
83 if (pskb_expand_head(skb, MV_HEADER_SIZE, (skb->len < 62 ? 62 - skb->len : 0), GFP_ATOMIC))
84 goto error_expand;
85 if (skb->len < 62)
86 skb->len = 62;
87 }
88 buf = skb_push(skb, MV_HEADER_SIZE);
89 #else
90 if (__vlan_get_tag(skb, &vid))
91 goto error;
92
93 if (unlikely((vid > 15 || !priv->vlans[vid])))
94 goto error;
95
96 if (skb->len <= 64) {
97 if (pskb_expand_head(skb, 0, 64 + MV_TRAILER_SIZE - skb->len, GFP_ATOMIC))
98 goto error_expand;
99
100 buf = skb->data + 64;
101 skb->len = 64 + MV_TRAILER_SIZE;
102 } else {
103 if (skb_cloned(skb) || unlikely(skb_tailroom(skb) < 4)) {
104 if (pskb_expand_head(skb, 0, 4, GFP_ATOMIC))
105 goto error_expand;
106 }
107 buf = skb_put(skb, 4);
108 }
109
110 /* move the ethernet header 4 bytes forward, overwriting the vlan tag */
111 memmove(skb->data + 4, skb->data, 12);
112 skb->data += 4;
113 skb->len -= 4;
114 skb->mac_header += 4;
115 #endif
116
117 if (!buf)
118 goto error;
119
120
121 #ifdef HEADER_MODE
122 /* prepend the tag */
123 *((__be16 *) buf) = cpu_to_be16(
124 ((vid << MV_HEADER_VLAN_S) & MV_HEADER_VLAN_M) |
125 ((priv->vlans[vid] << MV_HEADER_PORTS_S) & MV_HEADER_PORTS_M)
126 );
127 #else
128 /* append the tag */
129 *((__be32 *) buf) = cpu_to_be32((
130 (MV_TRAILER_OVERRIDE << MV_TRAILER_FLAGS_S) |
131 ((priv->vlans[vid] & MV_TRAILER_PORTS_M) << MV_TRAILER_PORTS_S)
132 ));
133 #endif
134
135 return priv->ndo_old->ndo_start_xmit(skb, dev);
136
137 error_expand:
138 if (net_ratelimit())
139 printk("%s: failed to expand/update skb for the switch\n", dev->name);
140
141 error:
142 /* any errors? drop the packet! */
143 dev_kfree_skb_any(skb);
144 return 0;
145 }
146
147 static int
148 mvswitch_mangle_rx(struct sk_buff *skb, int napi)
149 {
150 struct mvswitch_priv *priv;
151 struct net_device *dev;
152 int vlan = -1;
153 unsigned char *buf;
154 int i;
155
156 dev = skb->dev;
157 if (!dev)
158 goto error;
159
160 priv = dev->phy_ptr;
161 if (!priv)
162 goto error;
163
164 #ifdef HEADER_MODE
165 buf = skb->data;
166 skb_pull(skb, MV_HEADER_SIZE);
167 #else
168 buf = skb->data + skb->len - MV_TRAILER_SIZE;
169 if (buf[0] != 0x80)
170 goto error;
171 #endif
172
173 /* look for the vlan matching the incoming port */
174 for (i = 0; i < ARRAY_SIZE(priv->vlans); i++) {
175 if ((1 << buf[1]) & priv->vlans[i])
176 vlan = i;
177 }
178
179 if (vlan == -1)
180 goto error;
181
182 skb->protocol = eth_type_trans(skb, skb->dev);
183
184 __vlan_hwaccel_put_tag(skb, vlan);
185 if (napi)
186 return netif_receive_skb(skb);
187 else
188 return netif_rx(skb);
189
190 error:
191 /* no vlan? eat the packet! */
192 dev_kfree_skb_any(skb);
193 return 0;
194 }
195
196
197 static int
198 mvswitch_netif_rx(struct sk_buff *skb)
199 {
200 return mvswitch_mangle_rx(skb, 0);
201 }
202
203 static int
204 mvswitch_netif_receive_skb(struct sk_buff *skb)
205 {
206 return mvswitch_mangle_rx(skb, 1);
207 }
208
209
210 static int
211 mvswitch_wait_mask(struct phy_device *pdev, int addr, int reg, u16 mask, u16 val)
212 {
213 int i = 100;
214 u16 r;
215
216 do {
217 r = r16(pdev, addr, reg) & mask;
218 if (r == val)
219 return 0;
220 } while(--i > 0);
221 return -ETIMEDOUT;
222 }
223
224 static int
225 mvswitch_config_init(struct phy_device *pdev)
226 {
227 struct mvswitch_priv *priv = to_mvsw(pdev);
228 struct net_device *dev = pdev->attached_dev;
229 u8 vlmap = 0;
230 int i;
231
232 if (!dev)
233 return -EINVAL;
234
235 printk("%s: Marvell 88E6060 PHY driver attached.\n", dev->name);
236 pdev->supported = ADVERTISED_100baseT_Full;
237 pdev->advertising = ADVERTISED_100baseT_Full;
238 dev->phy_ptr = priv;
239 pdev->irq = PHY_POLL;
240 #ifdef HEADER_MODE
241 dev->flags |= IFF_PROMISC;
242 #endif
243
244 /* initialize default vlans */
245 for (i = 0; i < MV_PORTS; i++)
246 priv->vlans[(i == MV_WANPORT ? 2 : 1)] |= (1 << i);
247
248 /* before entering reset, disable all ports */
249 for (i = 0; i < MV_PORTS; i++)
250 w16(pdev, MV_PORTREG(CONTROL, i), 0x00);
251
252 msleep(2); /* wait for the status change to settle in */
253
254 /* put the ATU in reset */
255 w16(pdev, MV_SWITCHREG(ATU_CTRL), MV_ATUCTL_RESET);
256
257 i = mvswitch_wait_mask(pdev, MV_SWITCHREG(ATU_CTRL), MV_ATUCTL_RESET, 0);
258 if (i < 0) {
259 printk("%s: Timeout waiting for the switch to reset.\n", dev->name);
260 return i;
261 }
262
263 /* set the ATU flags */
264 w16(pdev, MV_SWITCHREG(ATU_CTRL),
265 MV_ATUCTL_NO_LEARN |
266 MV_ATUCTL_ATU_1K |
267 MV_ATUCTL_AGETIME(MV_ATUCTL_AGETIME_MIN) /* minimum without disabling ageing */
268 );
269
270 /* initialize the cpu port */
271 w16(pdev, MV_PORTREG(CONTROL, MV_CPUPORT),
272 #ifdef HEADER_MODE
273 MV_PORTCTRL_HEADER |
274 #else
275 MV_PORTCTRL_RXTR |
276 MV_PORTCTRL_TXTR |
277 #endif
278 MV_PORTCTRL_ENABLED
279 );
280 /* wait for the phy change to settle in */
281 msleep(2);
282 for (i = 0; i < MV_PORTS; i++) {
283 u8 pvid = 0;
284 int j;
285
286 vlmap = 0;
287
288 /* look for the matching vlan */
289 for (j = 0; j < ARRAY_SIZE(priv->vlans); j++) {
290 if (priv->vlans[j] & (1 << i)) {
291 vlmap = priv->vlans[j];
292 pvid = j;
293 }
294 }
295 /* leave port unconfigured if it's not part of a vlan */
296 if (!vlmap)
297 continue;
298
299 /* add the cpu port to the allowed destinations list */
300 vlmap |= (1 << MV_CPUPORT);
301
302 /* take port out of its own vlan destination map */
303 vlmap &= ~(1 << i);
304
305 /* apply vlan settings */
306 w16(pdev, MV_PORTREG(VLANMAP, i),
307 MV_PORTVLAN_PORTS(vlmap) |
308 MV_PORTVLAN_ID(i)
309 );
310
311 /* re-enable port */
312 w16(pdev, MV_PORTREG(CONTROL, i),
313 MV_PORTCTRL_ENABLED
314 );
315 }
316
317 w16(pdev, MV_PORTREG(VLANMAP, MV_CPUPORT),
318 MV_PORTVLAN_ID(MV_CPUPORT)
319 );
320
321 /* set the port association vector */
322 for (i = 0; i <= MV_PORTS; i++) {
323 w16(pdev, MV_PORTREG(ASSOC, i),
324 MV_PORTASSOC_PORTS(1 << i)
325 );
326 }
327
328 /* init switch control */
329 w16(pdev, MV_SWITCHREG(CTRL),
330 MV_SWITCHCTL_MSIZE |
331 MV_SWITCHCTL_DROP
332 );
333
334 /* hook into the tx function */
335 priv->ndo_old = dev->netdev_ops;
336 memcpy(&priv->ndo, priv->ndo_old, sizeof(struct net_device_ops));
337 priv->ndo.ndo_start_xmit = mvswitch_mangle_tx;
338 dev->netdev_ops = &priv->ndo;
339
340 pdev->pkt_align = 2;
341 pdev->netif_receive_skb = mvswitch_netif_receive_skb;
342 pdev->netif_rx = mvswitch_netif_rx;
343 #ifdef HEADER_MODE
344 dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
345 #else
346 dev->features |= NETIF_F_HW_VLAN_RX;
347 #endif
348
349 return 0;
350 }
351
352 static int
353 mvswitch_read_status(struct phy_device *pdev)
354 {
355 pdev->speed = SPEED_100;
356 pdev->duplex = DUPLEX_FULL;
357 pdev->link = 1;
358
359 /* XXX ugly workaround: we can't force the switch
360 * to gracefully handle hosts moving from one port to another,
361 * so we have to regularly clear the ATU database */
362
363 /* wait for the ATU to become available */
364 mvswitch_wait_mask(pdev, MV_SWITCHREG(ATU_OP), MV_ATUOP_INPROGRESS, 0);
365
366 /* flush the ATU */
367 w16(pdev, MV_SWITCHREG(ATU_OP),
368 MV_ATUOP_INPROGRESS |
369 MV_ATUOP_FLUSH_ALL
370 );
371
372 /* wait for operation to complete */
373 mvswitch_wait_mask(pdev, MV_SWITCHREG(ATU_OP), MV_ATUOP_INPROGRESS, 0);
374
375 return 0;
376 }
377
378 static int
379 mvswitch_config_aneg(struct phy_device *phydev)
380 {
381 return 0;
382 }
383
384 static void
385 mvswitch_remove(struct phy_device *pdev)
386 {
387 struct mvswitch_priv *priv = to_mvsw(pdev);
388 struct net_device *dev = pdev->attached_dev;
389
390 /* restore old netdev ops */
391 if (priv->ndo_old && dev)
392 dev->netdev_ops = priv->ndo_old;
393 dev->phy_ptr = NULL;
394 dev->features &= ~NETIF_F_HW_VLAN_RX;
395 kfree(priv);
396 }
397
398 static int
399 mvswitch_probe(struct phy_device *pdev)
400 {
401 struct mvswitch_priv *priv;
402
403 priv = kzalloc(sizeof(struct mvswitch_priv), GFP_KERNEL);
404 if (priv == NULL)
405 return -ENOMEM;
406
407 pdev->priv = priv;
408
409 return 0;
410 }
411
412 static int
413 mvswitch_fixup(struct phy_device *dev)
414 {
415 u16 reg;
416
417 if (dev->addr != 0x10)
418 return 0;
419
420 reg = dev->bus->read(dev->bus, MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
421 if (reg != MV_IDENT_VALUE)
422 return 0;
423
424 dev->phy_id = MVSWITCH_MAGIC;
425 return 0;
426 }
427
428
429 static struct phy_driver mvswitch_driver = {
430 .name = "Marvell 88E6060",
431 .phy_id = MVSWITCH_MAGIC,
432 .phy_id_mask = 0xffffffff,
433 .features = PHY_BASIC_FEATURES,
434 .probe = &mvswitch_probe,
435 .remove = &mvswitch_remove,
436 .config_init = &mvswitch_config_init,
437 .config_aneg = &mvswitch_config_aneg,
438 .read_status = &mvswitch_read_status,
439 .driver = { .owner = THIS_MODULE,},
440 };
441
442 static int __init
443 mvswitch_init(void)
444 {
445 phy_register_fixup_for_id(PHY_ANY_ID, mvswitch_fixup);
446 return phy_driver_register(&mvswitch_driver);
447 }
448
449 static void __exit
450 mvswitch_exit(void)
451 {
452 phy_driver_unregister(&mvswitch_driver);
453 }
454
455 module_init(mvswitch_init);
456 module_exit(mvswitch_exit);