tools/elfutils: refresh portability patch for macOS
[openwrt/openwrt.git] / target / linux / generic / files / drivers / net / phy / psb6970.c
1 /*
2 * Lantiq PSB6970 (Tantos) Switch driver
3 *
4 * Copyright (c) 2009,2010 Team Embedded.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License v2 as published by the
8 * Free Software Foundation.
9 *
10 * The switch programming done in this driver follows the
11 * "Ethernet Traffic Separation using VLAN" Application Note as
12 * published by Lantiq.
13 */
14
15 #include <linux/module.h>
16 #include <linux/netdevice.h>
17 #include <linux/switch.h>
18 #include <linux/phy.h>
19 #include <linux/version.h>
20
21 #define PSB6970_MAX_VLANS 16
22 #define PSB6970_NUM_PORTS 7
23 #define PSB6970_DEFAULT_PORT_CPU 6
24 #define PSB6970_IS_CPU_PORT(x) ((x) > 4)
25
26 #define PHYADDR(_reg) ((_reg >> 5) & 0xff), (_reg & 0x1f)
27
28 /* --- Identification --- */
29 #define PSB6970_CI0 0x0100
30 #define PSB6970_CI0_MASK 0x000f
31 #define PSB6970_CI1 0x0101
32 #define PSB6970_CI1_VAL 0x2599
33 #define PSB6970_CI1_MASK 0xffff
34
35 /* --- VLAN filter table --- */
36 #define PSB6970_VFxL(i) ((i)*2+0x10) /* VLAN Filter Low */
37 #define PSB6970_VFxL_VV (1 << 15) /* VLAN_Valid */
38
39 #define PSB6970_VFxH(i) ((i)*2+0x11) /* VLAN Filter High */
40 #define PSB6970_VFxH_TM_SHIFT 7 /* Tagged Member */
41
42 /* --- Port registers --- */
43 #define PSB6970_EC(p) ((p)*0x20+2) /* Extended Control */
44 #define PSB6970_EC_IFNTE (1 << 1) /* Input Force No Tag Enable */
45
46 #define PSB6970_PBVM(p) ((p)*0x20+3) /* Port Base VLAN Map */
47 #define PSB6970_PBVM_VMCE (1 << 8)
48 #define PSB6970_PBVM_AOVTP (1 << 9)
49 #define PSB6970_PBVM_VSD (1 << 10)
50 #define PSB6970_PBVM_VC (1 << 11) /* VID Check with VID table */
51 #define PSB6970_PBVM_TBVE (1 << 13) /* Tag-Based VLAN enable */
52
53 #define PSB6970_DVID(p) ((p)*0x20+4) /* Default VLAN ID & Priority */
54
55 struct psb6970_priv {
56 struct switch_dev dev;
57 struct phy_device *phy;
58 u16 (*read) (struct phy_device* phydev, int reg);
59 void (*write) (struct phy_device* phydev, int reg, u16 val);
60 struct mutex reg_mutex;
61
62 /* all fields below are cleared on reset */
63 struct_group(psb6970_priv_volatile,
64 bool vlan;
65 u16 vlan_id[PSB6970_MAX_VLANS];
66 u8 vlan_table[PSB6970_MAX_VLANS];
67 u8 vlan_tagged;
68 u16 pvid[PSB6970_NUM_PORTS];
69 );
70 };
71
72 #define to_psb6970(_dev) container_of(_dev, struct psb6970_priv, dev)
73
74 static u16 psb6970_mii_read(struct phy_device *phydev, int reg)
75 {
76 struct mii_bus *bus = phydev->mdio.bus;
77
78 return bus->read(bus, PHYADDR(reg));
79 }
80
81 static void psb6970_mii_write(struct phy_device *phydev, int reg, u16 val)
82 {
83 struct mii_bus *bus = phydev->mdio.bus;
84
85 bus->write(bus, PHYADDR(reg), val);
86 }
87
88 static int
89 psb6970_set_vlan(struct switch_dev *dev, const struct switch_attr *attr,
90 struct switch_val *val)
91 {
92 struct psb6970_priv *priv = to_psb6970(dev);
93 priv->vlan = !!val->value.i;
94 return 0;
95 }
96
97 static int
98 psb6970_get_vlan(struct switch_dev *dev, const struct switch_attr *attr,
99 struct switch_val *val)
100 {
101 struct psb6970_priv *priv = to_psb6970(dev);
102 val->value.i = priv->vlan;
103 return 0;
104 }
105
106 static int psb6970_set_pvid(struct switch_dev *dev, int port, int vlan)
107 {
108 struct psb6970_priv *priv = to_psb6970(dev);
109
110 /* make sure no invalid PVIDs get set */
111 if (vlan >= dev->vlans)
112 return -EINVAL;
113
114 priv->pvid[port] = vlan;
115 return 0;
116 }
117
118 static int psb6970_get_pvid(struct switch_dev *dev, int port, int *vlan)
119 {
120 struct psb6970_priv *priv = to_psb6970(dev);
121 *vlan = priv->pvid[port];
122 return 0;
123 }
124
125 static int
126 psb6970_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
127 struct switch_val *val)
128 {
129 struct psb6970_priv *priv = to_psb6970(dev);
130 priv->vlan_id[val->port_vlan] = val->value.i;
131 return 0;
132 }
133
134 static int
135 psb6970_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
136 struct switch_val *val)
137 {
138 struct psb6970_priv *priv = to_psb6970(dev);
139 val->value.i = priv->vlan_id[val->port_vlan];
140 return 0;
141 }
142
143 static struct switch_attr psb6970_globals[] = {
144 {
145 .type = SWITCH_TYPE_INT,
146 .name = "enable_vlan",
147 .description = "Enable VLAN mode",
148 .set = psb6970_set_vlan,
149 .get = psb6970_get_vlan,
150 .max = 1},
151 };
152
153 static struct switch_attr psb6970_port[] = {
154 };
155
156 static struct switch_attr psb6970_vlan[] = {
157 {
158 .type = SWITCH_TYPE_INT,
159 .name = "vid",
160 .description = "VLAN ID (0-4094)",
161 .set = psb6970_set_vid,
162 .get = psb6970_get_vid,
163 .max = 4094,
164 },
165 };
166
167 static int psb6970_get_ports(struct switch_dev *dev, struct switch_val *val)
168 {
169 struct psb6970_priv *priv = to_psb6970(dev);
170 u8 ports = priv->vlan_table[val->port_vlan];
171 int i;
172
173 val->len = 0;
174 for (i = 0; i < PSB6970_NUM_PORTS; i++) {
175 struct switch_port *p;
176
177 if (!(ports & (1 << i)))
178 continue;
179
180 p = &val->value.ports[val->len++];
181 p->id = i;
182 if (priv->vlan_tagged & (1 << i))
183 p->flags = (1 << SWITCH_PORT_FLAG_TAGGED);
184 else
185 p->flags = 0;
186 }
187 return 0;
188 }
189
190 static int psb6970_set_ports(struct switch_dev *dev, struct switch_val *val)
191 {
192 struct psb6970_priv *priv = to_psb6970(dev);
193 u8 *vt = &priv->vlan_table[val->port_vlan];
194 int i, j;
195
196 *vt = 0;
197 for (i = 0; i < val->len; i++) {
198 struct switch_port *p = &val->value.ports[i];
199
200 if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED))
201 priv->vlan_tagged |= (1 << p->id);
202 else {
203 priv->vlan_tagged &= ~(1 << p->id);
204 priv->pvid[p->id] = val->port_vlan;
205
206 /* make sure that an untagged port does not
207 * appear in other vlans */
208 for (j = 0; j < PSB6970_MAX_VLANS; j++) {
209 if (j == val->port_vlan)
210 continue;
211 priv->vlan_table[j] &= ~(1 << p->id);
212 }
213 }
214
215 *vt |= 1 << p->id;
216 }
217 return 0;
218 }
219
220 static int psb6970_hw_apply(struct switch_dev *dev)
221 {
222 struct psb6970_priv *priv = to_psb6970(dev);
223 int i, j;
224
225 mutex_lock(&priv->reg_mutex);
226
227 if (priv->vlan) {
228 /* into the vlan translation unit */
229 for (j = 0; j < PSB6970_MAX_VLANS; j++) {
230 u8 vp = priv->vlan_table[j];
231
232 if (vp) {
233 priv->write(priv->phy, PSB6970_VFxL(j),
234 PSB6970_VFxL_VV | priv->vlan_id[j]);
235 priv->write(priv->phy, PSB6970_VFxH(j),
236 ((vp & priv->
237 vlan_tagged) <<
238 PSB6970_VFxH_TM_SHIFT) | vp);
239 } else /* clear VLAN Valid flag for unused vlans */
240 priv->write(priv->phy, PSB6970_VFxL(j), 0);
241
242 }
243 }
244
245 /* update the port destination mask registers and tag settings */
246 for (i = 0; i < PSB6970_NUM_PORTS; i++) {
247 int dvid = 1, pbvm = 0x7f | PSB6970_PBVM_VSD, ec = 0;
248
249 if (priv->vlan) {
250 ec = PSB6970_EC_IFNTE;
251 dvid = priv->vlan_id[priv->pvid[i]];
252 pbvm |= PSB6970_PBVM_TBVE | PSB6970_PBVM_VMCE;
253
254 if ((i << 1) & priv->vlan_tagged)
255 pbvm |= PSB6970_PBVM_AOVTP | PSB6970_PBVM_VC;
256 }
257
258 priv->write(priv->phy, PSB6970_PBVM(i), pbvm);
259
260 if (!PSB6970_IS_CPU_PORT(i)) {
261 priv->write(priv->phy, PSB6970_EC(i), ec);
262 priv->write(priv->phy, PSB6970_DVID(i), dvid);
263 }
264 }
265
266 mutex_unlock(&priv->reg_mutex);
267 return 0;
268 }
269
270 static int psb6970_reset_switch(struct switch_dev *dev)
271 {
272 struct psb6970_priv *priv = to_psb6970(dev);
273 int i;
274
275 mutex_lock(&priv->reg_mutex);
276
277 memset(&priv->psb6970_priv_volatile, 0,
278 sizeof(priv->psb6970_priv_volatile));
279
280 for (i = 0; i < PSB6970_MAX_VLANS; i++)
281 priv->vlan_id[i] = i;
282
283 mutex_unlock(&priv->reg_mutex);
284
285 return psb6970_hw_apply(dev);
286 }
287
288 static const struct switch_dev_ops psb6970_ops = {
289 .attr_global = {
290 .attr = psb6970_globals,
291 .n_attr = ARRAY_SIZE(psb6970_globals),
292 },
293 .attr_port = {
294 .attr = psb6970_port,
295 .n_attr = ARRAY_SIZE(psb6970_port),
296 },
297 .attr_vlan = {
298 .attr = psb6970_vlan,
299 .n_attr = ARRAY_SIZE(psb6970_vlan),
300 },
301 .get_port_pvid = psb6970_get_pvid,
302 .set_port_pvid = psb6970_set_pvid,
303 .get_vlan_ports = psb6970_get_ports,
304 .set_vlan_ports = psb6970_set_ports,
305 .apply_config = psb6970_hw_apply,
306 .reset_switch = psb6970_reset_switch,
307 };
308
309 static int psb6970_config_init(struct phy_device *pdev)
310 {
311 struct psb6970_priv *priv;
312 struct switch_dev *swdev;
313 int ret;
314
315 priv = kzalloc(sizeof(struct psb6970_priv), GFP_KERNEL);
316 if (priv == NULL)
317 return -ENOMEM;
318
319 priv->phy = pdev;
320
321 if (pdev->mdio.addr == 0)
322 printk(KERN_INFO "%s: psb6970 switch driver attached.\n",
323 pdev->attached_dev->name);
324
325 if (pdev->mdio.addr != 0) {
326 kfree(priv);
327 return 0;
328 }
329
330 linkmode_zero(pdev->supported);
331 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pdev->supported);
332 linkmode_copy(pdev->advertising, pdev->supported);
333
334 mutex_init(&priv->reg_mutex);
335 priv->read = psb6970_mii_read;
336 priv->write = psb6970_mii_write;
337
338 pdev->priv = priv;
339
340 swdev = &priv->dev;
341 swdev->cpu_port = PSB6970_DEFAULT_PORT_CPU;
342 swdev->ops = &psb6970_ops;
343
344 swdev->name = "Lantiq PSB6970";
345 swdev->vlans = PSB6970_MAX_VLANS;
346 swdev->ports = PSB6970_NUM_PORTS;
347
348 if ((ret = register_switch(&priv->dev, pdev->attached_dev)) < 0) {
349 kfree(priv);
350 goto done;
351 }
352
353 ret = psb6970_reset_switch(&priv->dev);
354 if (ret) {
355 kfree(priv);
356 goto done;
357 }
358
359 done:
360 return ret;
361 }
362
363 static int psb6970_read_status(struct phy_device *phydev)
364 {
365 phydev->speed = SPEED_100;
366 phydev->duplex = DUPLEX_FULL;
367 phydev->link = 1;
368
369 phydev->state = PHY_RUNNING;
370 netif_carrier_on(phydev->attached_dev);
371 phydev->adjust_link(phydev->attached_dev);
372
373 return 0;
374 }
375
376 static int psb6970_config_aneg(struct phy_device *phydev)
377 {
378 return 0;
379 }
380
381 static int psb6970_probe(struct phy_device *pdev)
382 {
383 return 0;
384 }
385
386 static void psb6970_remove(struct phy_device *pdev)
387 {
388 struct psb6970_priv *priv = pdev->priv;
389
390 if (!priv)
391 return;
392
393 if (pdev->mdio.addr == 0)
394 unregister_switch(&priv->dev);
395 kfree(priv);
396 }
397
398 static int psb6970_fixup(struct phy_device *dev)
399 {
400 struct mii_bus *bus = dev->mdio.bus;
401 u16 reg;
402
403 /* look for the switch on the bus */
404 reg = bus->read(bus, PHYADDR(PSB6970_CI1)) & PSB6970_CI1_MASK;
405 if (reg != PSB6970_CI1_VAL)
406 return 0;
407
408 dev->phy_id = (reg << 16);
409 dev->phy_id |= bus->read(bus, PHYADDR(PSB6970_CI0)) & PSB6970_CI0_MASK;
410
411 return 0;
412 }
413
414 static struct phy_driver psb6970_driver = {
415 .name = "Lantiq PSB6970",
416 .phy_id = PSB6970_CI1_VAL << 16,
417 .phy_id_mask = 0xffff0000,
418 .features = PHY_BASIC_FEATURES,
419 .probe = psb6970_probe,
420 .remove = psb6970_remove,
421 .config_init = &psb6970_config_init,
422 .config_aneg = &psb6970_config_aneg,
423 .read_status = &psb6970_read_status,
424 };
425
426 int __init psb6970_init(void)
427 {
428 phy_register_fixup_for_id(PHY_ANY_ID, psb6970_fixup);
429 return phy_driver_register(&psb6970_driver, THIS_MODULE);
430 }
431
432 module_init(psb6970_init);
433
434 void __exit psb6970_exit(void)
435 {
436 phy_driver_unregister(&psb6970_driver);
437 }
438
439 module_exit(psb6970_exit);
440
441 MODULE_DESCRIPTION("Lantiq PSB6970 Switch");
442 MODULE_AUTHOR("Ithamar R. Adema <ithamar.adema@team-embedded.nl>");
443 MODULE_LICENSE("GPL");