lantiq: add Linux 5.10 support as testing kernel
[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 bool vlan;
64 u16 vlan_id[PSB6970_MAX_VLANS];
65 u8 vlan_table[PSB6970_MAX_VLANS];
66 u8 vlan_tagged;
67 u16 pvid[PSB6970_NUM_PORTS];
68 };
69
70 #define to_psb6970(_dev) container_of(_dev, struct psb6970_priv, dev)
71
72 static u16 psb6970_mii_read(struct phy_device *phydev, int reg)
73 {
74 struct mii_bus *bus = phydev->mdio.bus;
75
76 return bus->read(bus, PHYADDR(reg));
77 }
78
79 static void psb6970_mii_write(struct phy_device *phydev, int reg, u16 val)
80 {
81 struct mii_bus *bus = phydev->mdio.bus;
82
83 bus->write(bus, PHYADDR(reg), val);
84 }
85
86 static int
87 psb6970_set_vlan(struct switch_dev *dev, const struct switch_attr *attr,
88 struct switch_val *val)
89 {
90 struct psb6970_priv *priv = to_psb6970(dev);
91 priv->vlan = !!val->value.i;
92 return 0;
93 }
94
95 static int
96 psb6970_get_vlan(struct switch_dev *dev, const struct switch_attr *attr,
97 struct switch_val *val)
98 {
99 struct psb6970_priv *priv = to_psb6970(dev);
100 val->value.i = priv->vlan;
101 return 0;
102 }
103
104 static int psb6970_set_pvid(struct switch_dev *dev, int port, int vlan)
105 {
106 struct psb6970_priv *priv = to_psb6970(dev);
107
108 /* make sure no invalid PVIDs get set */
109 if (vlan >= dev->vlans)
110 return -EINVAL;
111
112 priv->pvid[port] = vlan;
113 return 0;
114 }
115
116 static int psb6970_get_pvid(struct switch_dev *dev, int port, int *vlan)
117 {
118 struct psb6970_priv *priv = to_psb6970(dev);
119 *vlan = priv->pvid[port];
120 return 0;
121 }
122
123 static int
124 psb6970_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
125 struct switch_val *val)
126 {
127 struct psb6970_priv *priv = to_psb6970(dev);
128 priv->vlan_id[val->port_vlan] = val->value.i;
129 return 0;
130 }
131
132 static int
133 psb6970_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
134 struct switch_val *val)
135 {
136 struct psb6970_priv *priv = to_psb6970(dev);
137 val->value.i = priv->vlan_id[val->port_vlan];
138 return 0;
139 }
140
141 static struct switch_attr psb6970_globals[] = {
142 {
143 .type = SWITCH_TYPE_INT,
144 .name = "enable_vlan",
145 .description = "Enable VLAN mode",
146 .set = psb6970_set_vlan,
147 .get = psb6970_get_vlan,
148 .max = 1},
149 };
150
151 static struct switch_attr psb6970_port[] = {
152 };
153
154 static struct switch_attr psb6970_vlan[] = {
155 {
156 .type = SWITCH_TYPE_INT,
157 .name = "vid",
158 .description = "VLAN ID (0-4094)",
159 .set = psb6970_set_vid,
160 .get = psb6970_get_vid,
161 .max = 4094,
162 },
163 };
164
165 static int psb6970_get_ports(struct switch_dev *dev, struct switch_val *val)
166 {
167 struct psb6970_priv *priv = to_psb6970(dev);
168 u8 ports = priv->vlan_table[val->port_vlan];
169 int i;
170
171 val->len = 0;
172 for (i = 0; i < PSB6970_NUM_PORTS; i++) {
173 struct switch_port *p;
174
175 if (!(ports & (1 << i)))
176 continue;
177
178 p = &val->value.ports[val->len++];
179 p->id = i;
180 if (priv->vlan_tagged & (1 << i))
181 p->flags = (1 << SWITCH_PORT_FLAG_TAGGED);
182 else
183 p->flags = 0;
184 }
185 return 0;
186 }
187
188 static int psb6970_set_ports(struct switch_dev *dev, struct switch_val *val)
189 {
190 struct psb6970_priv *priv = to_psb6970(dev);
191 u8 *vt = &priv->vlan_table[val->port_vlan];
192 int i, j;
193
194 *vt = 0;
195 for (i = 0; i < val->len; i++) {
196 struct switch_port *p = &val->value.ports[i];
197
198 if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED))
199 priv->vlan_tagged |= (1 << p->id);
200 else {
201 priv->vlan_tagged &= ~(1 << p->id);
202 priv->pvid[p->id] = val->port_vlan;
203
204 /* make sure that an untagged port does not
205 * appear in other vlans */
206 for (j = 0; j < PSB6970_MAX_VLANS; j++) {
207 if (j == val->port_vlan)
208 continue;
209 priv->vlan_table[j] &= ~(1 << p->id);
210 }
211 }
212
213 *vt |= 1 << p->id;
214 }
215 return 0;
216 }
217
218 static int psb6970_hw_apply(struct switch_dev *dev)
219 {
220 struct psb6970_priv *priv = to_psb6970(dev);
221 int i, j;
222
223 mutex_lock(&priv->reg_mutex);
224
225 if (priv->vlan) {
226 /* into the vlan translation unit */
227 for (j = 0; j < PSB6970_MAX_VLANS; j++) {
228 u8 vp = priv->vlan_table[j];
229
230 if (vp) {
231 priv->write(priv->phy, PSB6970_VFxL(j),
232 PSB6970_VFxL_VV | priv->vlan_id[j]);
233 priv->write(priv->phy, PSB6970_VFxH(j),
234 ((vp & priv->
235 vlan_tagged) <<
236 PSB6970_VFxH_TM_SHIFT) | vp);
237 } else /* clear VLAN Valid flag for unused vlans */
238 priv->write(priv->phy, PSB6970_VFxL(j), 0);
239
240 }
241 }
242
243 /* update the port destination mask registers and tag settings */
244 for (i = 0; i < PSB6970_NUM_PORTS; i++) {
245 int dvid = 1, pbvm = 0x7f | PSB6970_PBVM_VSD, ec = 0;
246
247 if (priv->vlan) {
248 ec = PSB6970_EC_IFNTE;
249 dvid = priv->vlan_id[priv->pvid[i]];
250 pbvm |= PSB6970_PBVM_TBVE | PSB6970_PBVM_VMCE;
251
252 if ((i << 1) & priv->vlan_tagged)
253 pbvm |= PSB6970_PBVM_AOVTP | PSB6970_PBVM_VC;
254 }
255
256 priv->write(priv->phy, PSB6970_PBVM(i), pbvm);
257
258 if (!PSB6970_IS_CPU_PORT(i)) {
259 priv->write(priv->phy, PSB6970_EC(i), ec);
260 priv->write(priv->phy, PSB6970_DVID(i), dvid);
261 }
262 }
263
264 mutex_unlock(&priv->reg_mutex);
265 return 0;
266 }
267
268 static int psb6970_reset_switch(struct switch_dev *dev)
269 {
270 struct psb6970_priv *priv = to_psb6970(dev);
271 int i;
272
273 mutex_lock(&priv->reg_mutex);
274
275 memset(&priv->vlan, 0, sizeof(struct psb6970_priv) -
276 offsetof(struct psb6970_priv, vlan));
277
278 for (i = 0; i < PSB6970_MAX_VLANS; i++)
279 priv->vlan_id[i] = i;
280
281 mutex_unlock(&priv->reg_mutex);
282
283 return psb6970_hw_apply(dev);
284 }
285
286 static const struct switch_dev_ops psb6970_ops = {
287 .attr_global = {
288 .attr = psb6970_globals,
289 .n_attr = ARRAY_SIZE(psb6970_globals),
290 },
291 .attr_port = {
292 .attr = psb6970_port,
293 .n_attr = ARRAY_SIZE(psb6970_port),
294 },
295 .attr_vlan = {
296 .attr = psb6970_vlan,
297 .n_attr = ARRAY_SIZE(psb6970_vlan),
298 },
299 .get_port_pvid = psb6970_get_pvid,
300 .set_port_pvid = psb6970_set_pvid,
301 .get_vlan_ports = psb6970_get_ports,
302 .set_vlan_ports = psb6970_set_ports,
303 .apply_config = psb6970_hw_apply,
304 .reset_switch = psb6970_reset_switch,
305 };
306
307 static int psb6970_config_init(struct phy_device *pdev)
308 {
309 struct psb6970_priv *priv;
310 struct net_device *dev = pdev->attached_dev;
311 struct switch_dev *swdev;
312 int ret;
313
314 priv = kzalloc(sizeof(struct psb6970_priv), GFP_KERNEL);
315 if (priv == NULL)
316 return -ENOMEM;
317
318 priv->phy = pdev;
319
320 if (pdev->mdio.addr == 0)
321 printk(KERN_INFO "%s: psb6970 switch driver attached.\n",
322 pdev->attached_dev->name);
323
324 if (pdev->mdio.addr != 0) {
325 kfree(priv);
326 return 0;
327 }
328
329 linkmode_zero(pdev->supported);
330 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pdev->supported);
331 linkmode_copy(pdev->advertising, pdev->supported);
332
333 mutex_init(&priv->reg_mutex);
334 priv->read = psb6970_mii_read;
335 priv->write = psb6970_mii_write;
336
337 pdev->priv = priv;
338
339 swdev = &priv->dev;
340 swdev->cpu_port = PSB6970_DEFAULT_PORT_CPU;
341 swdev->ops = &psb6970_ops;
342
343 swdev->name = "Lantiq PSB6970";
344 swdev->vlans = PSB6970_MAX_VLANS;
345 swdev->ports = PSB6970_NUM_PORTS;
346
347 if ((ret = register_switch(&priv->dev, pdev->attached_dev)) < 0) {
348 kfree(priv);
349 goto done;
350 }
351
352 ret = psb6970_reset_switch(&priv->dev);
353 if (ret) {
354 kfree(priv);
355 goto done;
356 }
357
358 done:
359 return ret;
360 }
361
362 static int psb6970_read_status(struct phy_device *phydev)
363 {
364 phydev->speed = SPEED_100;
365 phydev->duplex = DUPLEX_FULL;
366 phydev->link = 1;
367
368 phydev->state = PHY_RUNNING;
369 netif_carrier_on(phydev->attached_dev);
370 phydev->adjust_link(phydev->attached_dev);
371
372 return 0;
373 }
374
375 static int psb6970_config_aneg(struct phy_device *phydev)
376 {
377 return 0;
378 }
379
380 static int psb6970_probe(struct phy_device *pdev)
381 {
382 return 0;
383 }
384
385 static void psb6970_remove(struct phy_device *pdev)
386 {
387 struct psb6970_priv *priv = pdev->priv;
388
389 if (!priv)
390 return;
391
392 if (pdev->mdio.addr == 0)
393 unregister_switch(&priv->dev);
394 kfree(priv);
395 }
396
397 static int psb6970_fixup(struct phy_device *dev)
398 {
399 struct mii_bus *bus = dev->mdio.bus;
400 u16 reg;
401
402 /* look for the switch on the bus */
403 reg = bus->read(bus, PHYADDR(PSB6970_CI1)) & PSB6970_CI1_MASK;
404 if (reg != PSB6970_CI1_VAL)
405 return 0;
406
407 dev->phy_id = (reg << 16);
408 dev->phy_id |= bus->read(bus, PHYADDR(PSB6970_CI0)) & PSB6970_CI0_MASK;
409
410 return 0;
411 }
412
413 static struct phy_driver psb6970_driver = {
414 .name = "Lantiq PSB6970",
415 .phy_id = PSB6970_CI1_VAL << 16,
416 .phy_id_mask = 0xffff0000,
417 .features = PHY_BASIC_FEATURES,
418 .probe = psb6970_probe,
419 .remove = psb6970_remove,
420 .config_init = &psb6970_config_init,
421 .config_aneg = &psb6970_config_aneg,
422 .read_status = &psb6970_read_status,
423 };
424
425 int __init psb6970_init(void)
426 {
427 phy_register_fixup_for_id(PHY_ANY_ID, psb6970_fixup);
428 return phy_driver_register(&psb6970_driver, THIS_MODULE);
429 }
430
431 module_init(psb6970_init);
432
433 void __exit psb6970_exit(void)
434 {
435 phy_driver_unregister(&psb6970_driver);
436 }
437
438 module_exit(psb6970_exit);
439
440 MODULE_DESCRIPTION("Lantiq PSB6970 Switch");
441 MODULE_AUTHOR("Ithamar R. Adema <ithamar.adema@team-embedded.nl>");
442 MODULE_LICENSE("GPL");