2 * ADM6996 switch driver
4 * swconfig interface based on ar8216.c
6 * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org>
7 * VLAN support Copyright (c) 2010, 2011 Peter Lebbing <peter@digitalbrains.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License v2 as published by the
11 * Free Software Foundation
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/errno.h>
18 #include <linux/unistd.h>
19 #include <linux/slab.h>
20 #include <linux/interrupt.h>
21 #include <linux/init.h>
22 #include <linux/delay.h>
23 #include <linux/netdevice.h>
24 #include <linux/etherdevice.h>
25 #include <linux/skbuff.h>
26 #include <linux/spinlock.h>
28 #include <linux/module.h>
29 #include <linux/mii.h>
30 #include <linux/ethtool.h>
31 #include <linux/phy.h>
32 #include <linux/switch.h>
36 #include <asm/uaccess.h>
39 MODULE_DESCRIPTION("Infineon ADM6996 Switch");
40 MODULE_AUTHOR("Felix Fietkau, Peter Lebbing <peter@digitalbrains.com>");
41 MODULE_LICENSE("GPL");
48 static const char * const adm6996_model_name[] =
55 struct switch_dev dev;
56 struct phy_device *phydev;
58 enum adm6996_model model;
61 bool vlan_enabled; /* Current hardware state */
64 u16 addr; /* Debugging: register address to operate on */
67 u16 pvid[ADM_NUM_PORTS]; /* Primary VLAN ID */
69 u16 vlan_id[ADM_NUM_VLANS];
70 u8 vlan_table[ADM_NUM_VLANS]; /* bitmap, 1 = port is member */
71 u8 vlan_tagged[ADM_NUM_VLANS]; /* bitmap, 1 = tagged member */
73 struct mutex reg_mutex;
75 /* use abstraction for regops, we want to add gpio support in the future */
76 u16 (*read)(struct phy_device *phydev, enum admreg reg);
77 void (*write)(struct phy_device *phydev, enum admreg reg, u16 val);
80 #define to_adm(_dev) container_of(_dev, struct adm6996_priv, dev)
81 #define phy_to_adm(_phy) ((struct adm6996_priv *) (_phy)->priv)
84 r16(struct phy_device *pdev, enum admreg reg)
86 return phy_to_adm(pdev)->read(pdev, reg);
90 w16(struct phy_device *pdev, enum admreg reg, u16 val)
92 phy_to_adm(pdev)->write(pdev, reg, val);
97 adm6996_read_mii_reg(struct phy_device *phydev, enum admreg reg)
99 return phydev->bus->read(phydev->bus, PHYADDR(reg));
103 adm6996_write_mii_reg(struct phy_device *phydev, enum admreg reg, u16 val)
105 phydev->bus->write(phydev->bus, PHYADDR(reg), val);
109 adm6996_set_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr,
110 struct switch_val *val)
112 struct adm6996_priv *priv = to_adm(dev);
114 if (val->value.i > 1)
117 priv->enable_vlan = val->value.i;
123 adm6996_get_enable_vlan(struct switch_dev *dev, const struct switch_attr *attr,
124 struct switch_val *val)
126 struct adm6996_priv *priv = to_adm(dev);
128 val->value.i = priv->enable_vlan;
136 adm6996_set_addr(struct switch_dev *dev, const struct switch_attr *attr,
137 struct switch_val *val)
139 struct adm6996_priv *priv = to_adm(dev);
141 if (val->value.i > 1023)
144 priv->addr = val->value.i;
150 adm6996_get_addr(struct switch_dev *dev, const struct switch_attr *attr,
151 struct switch_val *val)
153 struct adm6996_priv *priv = to_adm(dev);
155 val->value.i = priv->addr;
161 adm6996_set_data(struct switch_dev *dev, const struct switch_attr *attr,
162 struct switch_val *val)
164 struct adm6996_priv *priv = to_adm(dev);
166 if (val->value.i > 65535)
169 w16(priv->phydev, priv->addr, val->value.i);
175 adm6996_get_data(struct switch_dev *dev, const struct switch_attr *attr,
176 struct switch_val *val)
178 struct adm6996_priv *priv = to_adm(dev);
180 val->value.i = r16(priv->phydev, priv->addr);
185 #endif /* def DEBUG */
188 adm6996_set_pvid(struct switch_dev *dev, int port, int vlan)
190 struct adm6996_priv *priv = to_adm(dev);
192 dev_dbg (&priv->phydev->dev, "set_pvid port %d vlan %d\n", port
195 if (vlan > ADM_VLAN_MAX_ID)
198 priv->pvid[port] = vlan;
204 adm6996_get_pvid(struct switch_dev *dev, int port, int *vlan)
206 struct adm6996_priv *priv = to_adm(dev);
208 dev_dbg (&priv->phydev->dev, "get_pvid port %d\n", port);
209 *vlan = priv->pvid[port];
215 adm6996_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
216 struct switch_val *val)
218 struct adm6996_priv *priv = to_adm(dev);
220 dev_dbg (&priv->phydev->dev, "set_vid port %d vid %d\n", val->port_vlan,
223 if (val->value.i > ADM_VLAN_MAX_ID)
226 priv->vlan_id[val->port_vlan] = val->value.i;
232 adm6996_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
233 struct switch_val *val)
235 struct adm6996_priv *priv = to_adm(dev);
237 dev_dbg (&priv->phydev->dev, "get_vid port %d\n", val->port_vlan);
239 val->value.i = priv->vlan_id[val->port_vlan];
245 adm6996_get_ports(struct switch_dev *dev, struct switch_val *val)
247 struct adm6996_priv *priv = to_adm(dev);
248 u8 ports = priv->vlan_table[val->port_vlan];
249 u8 tagged = priv->vlan_tagged[val->port_vlan];
252 dev_dbg (&priv->phydev->dev, "get_ports port_vlan %d\n",
257 for (i = 0; i < ADM_NUM_PORTS; i++) {
258 struct switch_port *p;
260 if (!(ports & (1 << i)))
263 p = &val->value.ports[val->len++];
265 if (tagged & (1 << i))
266 p->flags = (1 << SWITCH_PORT_FLAG_TAGGED);
275 adm6996_set_ports(struct switch_dev *dev, struct switch_val *val)
277 struct adm6996_priv *priv = to_adm(dev);
278 u8 *ports = &priv->vlan_table[val->port_vlan];
279 u8 *tagged = &priv->vlan_tagged[val->port_vlan];
282 dev_dbg (&priv->phydev->dev, "set_ports port_vlan %d ports",
288 for (i = 0; i < val->len; i++) {
289 struct switch_port *p = &val->value.ports[i];
292 pr_cont(" %d%s", p->id,
293 ((p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) ? "T" :
297 if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED))
298 *tagged |= (1 << p->id);
300 *ports |= (1 << p->id);
311 * Precondition: reg_mutex must be held
314 adm6996_enable_vlan(struct adm6996_priv *priv)
318 reg = r16(priv->phydev, ADM_OTBE_P2_PVID);
319 reg &= ~(ADM_OTBE_MASK);
320 w16(priv->phydev, ADM_OTBE_P2_PVID, reg);
321 reg = r16(priv->phydev, ADM_IFNTE);
322 reg &= ~(ADM_IFNTE_MASK);
323 w16(priv->phydev, ADM_IFNTE, reg);
324 reg = r16(priv->phydev, ADM_VID_CHECK);
325 reg |= ADM_VID_CHECK_MASK;
326 w16(priv->phydev, ADM_VID_CHECK, reg);
327 reg = r16(priv->phydev, ADM_SYSC0);
330 w16(priv->phydev, ADM_SYSC0, reg);
331 reg = r16(priv->phydev, ADM_SYSC3);
333 w16(priv->phydev, ADM_SYSC3, reg);
340 * Sets VLAN mapping for port-based VLAN with all ports connected to
341 * eachother (this is also the power-on default).
343 * Precondition: reg_mutex must be held
346 adm6996_disable_vlan(struct adm6996_priv *priv)
351 for (i = 0; i < ADM_NUM_PORTS; i++) {
352 reg = ADM_VLAN_FILT_MEMBER_MASK;
353 w16(priv->phydev, ADM_VLAN_FILT_L(i), reg);
354 reg = ADM_VLAN_FILT_VALID | ADM_VLAN_FILT_VID(1);
355 w16(priv->phydev, ADM_VLAN_FILT_H(i), reg);
358 reg = r16(priv->phydev, ADM_OTBE_P2_PVID);
359 reg |= ADM_OTBE_MASK;
360 w16(priv->phydev, ADM_OTBE_P2_PVID, reg);
361 reg = r16(priv->phydev, ADM_IFNTE);
362 reg |= ADM_IFNTE_MASK;
363 w16(priv->phydev, ADM_IFNTE, reg);
364 reg = r16(priv->phydev, ADM_VID_CHECK);
365 reg &= ~(ADM_VID_CHECK_MASK);
366 w16(priv->phydev, ADM_VID_CHECK, reg);
367 reg = r16(priv->phydev, ADM_SYSC0);
370 w16(priv->phydev, ADM_SYSC0, reg);
371 reg = r16(priv->phydev, ADM_SYSC3);
373 w16(priv->phydev, ADM_SYSC3, reg);
377 * Precondition: reg_mutex must be held
380 adm6996_apply_port_pvids(struct adm6996_priv *priv)
385 for (i = 0; i < ADM_NUM_PORTS; i++) {
386 reg = r16(priv->phydev, adm_portcfg[i]);
387 reg &= ~(ADM_PORTCFG_PVID_MASK);
388 reg |= ADM_PORTCFG_PVID(priv->pvid[i]);
389 w16(priv->phydev, adm_portcfg[i], reg);
392 w16(priv->phydev, ADM_P0_PVID, ADM_P0_PVID_VAL(priv->pvid[0]));
393 w16(priv->phydev, ADM_P1_PVID, ADM_P1_PVID_VAL(priv->pvid[1]));
394 reg = r16(priv->phydev, ADM_OTBE_P2_PVID);
395 reg &= ~(ADM_P2_PVID_MASK);
396 reg |= ADM_P2_PVID_VAL(priv->pvid[2]);
397 w16(priv->phydev, ADM_OTBE_P2_PVID, reg);
398 reg = ADM_P3_PVID_VAL(priv->pvid[3]);
399 reg |= ADM_P4_PVID_VAL(priv->pvid[4]);
400 w16(priv->phydev, ADM_P3_P4_PVID, reg);
401 w16(priv->phydev, ADM_P5_PVID, ADM_P5_PVID_VAL(priv->pvid[5]));
405 * Precondition: reg_mutex must be held
408 adm6996_apply_vlan_filters(struct adm6996_priv *priv)
414 for (i = 0; i < ADM_NUM_VLANS; i++) {
415 vid = priv->vlan_id[i];
416 ports = priv->vlan_table[i];
417 tagged = priv->vlan_tagged[i];
420 /* Disable VLAN entry */
421 w16(priv->phydev, ADM_VLAN_FILT_H(i), 0);
422 w16(priv->phydev, ADM_VLAN_FILT_L(i), 0);
426 reg = ADM_VLAN_FILT_MEMBER(ports);
427 reg |= ADM_VLAN_FILT_TAGGED(tagged);
428 w16(priv->phydev, ADM_VLAN_FILT_L(i), reg);
429 reg = ADM_VLAN_FILT_VALID | ADM_VLAN_FILT_VID(vid);
430 w16(priv->phydev, ADM_VLAN_FILT_H(i), reg);
435 adm6996_hw_apply(struct switch_dev *dev)
437 struct adm6996_priv *priv = to_adm(dev);
439 dev_dbg(&priv->phydev->dev, "hw_apply\n");
441 mutex_lock(&priv->reg_mutex);
443 if (!priv->enable_vlan) {
444 if (priv->vlan_enabled) {
445 adm6996_disable_vlan(priv);
446 priv->vlan_enabled = 0;
451 if (!priv->vlan_enabled) {
452 adm6996_enable_vlan(priv);
453 priv->vlan_enabled = 1;
456 adm6996_apply_port_pvids(priv);
457 adm6996_apply_vlan_filters(priv);
460 mutex_unlock(&priv->reg_mutex);
468 * The ADM6996 can't do a software-initiated reset, so we just initialise the
469 * registers we support in this driver.
471 * Precondition: reg_mutex must be held
474 adm6996_perform_reset (struct adm6996_priv *priv)
478 /* initialize port and vlan settings */
479 for (i = 0; i < ADM_NUM_PORTS - 1; i++) {
480 w16(priv->phydev, adm_portcfg[i], ADM_PORTCFG_INIT |
481 ADM_PORTCFG_PVID(0));
483 w16(priv->phydev, adm_portcfg[5], ADM_PORTCFG_CPU);
485 /* reset all PHY ports */
486 for (i = 0; i < ADM_PHY_PORTS; i++) {
487 w16(priv->phydev, ADM_PHY_PORT(i), ADM_PHYCFG_INIT);
490 priv->enable_vlan = 0;
491 priv->vlan_enabled = 0;
493 for (i = 0; i < ADM_NUM_PORTS; i++) {
497 for (i = 0; i < ADM_NUM_VLANS; i++) {
498 priv->vlan_id[i] = i;
499 priv->vlan_table[i] = 0;
500 priv->vlan_tagged[i] = 0;
503 if (priv->model == ADM6996M) {
504 /* Clear VLAN priority map so prio's are unused */
505 w16 (priv->phydev, ADM_VLAN_PRIOMAP, 0);
507 adm6996_disable_vlan(priv);
508 adm6996_apply_port_pvids(priv);
513 adm6996_reset_switch(struct switch_dev *dev)
515 struct adm6996_priv *priv = to_adm(dev);
517 dev_dbg (&priv->phydev->dev, "reset\n");
518 mutex_lock(&priv->reg_mutex);
519 adm6996_perform_reset (priv);
520 mutex_unlock(&priv->reg_mutex);
524 static struct switch_attr adm6996_globals[] = {
526 .type = SWITCH_TYPE_INT,
527 .name = "enable_vlan",
528 .description = "Enable VLANs",
529 .set = adm6996_set_enable_vlan,
530 .get = adm6996_get_enable_vlan,
534 .type = SWITCH_TYPE_INT,
537 "Direct register access: set register address (0 - 1023)",
538 .set = adm6996_set_addr,
539 .get = adm6996_get_addr,
542 .type = SWITCH_TYPE_INT,
545 "Direct register access: read/write to register (0 - 65535)",
546 .set = adm6996_set_data,
547 .get = adm6996_get_data,
549 #endif /* def DEBUG */
552 static struct switch_attr adm6996_port[] = {
555 static struct switch_attr adm6996_vlan[] = {
557 .type = SWITCH_TYPE_INT,
559 .description = "VLAN ID",
560 .set = adm6996_set_vid,
561 .get = adm6996_get_vid,
565 static const struct switch_dev_ops adm6996_ops = {
567 .attr = adm6996_globals,
568 .n_attr = ARRAY_SIZE(adm6996_globals),
571 .attr = adm6996_port,
572 .n_attr = ARRAY_SIZE(adm6996_port),
575 .attr = adm6996_vlan,
576 .n_attr = ARRAY_SIZE(adm6996_vlan),
578 .get_port_pvid = adm6996_get_pvid,
579 .set_port_pvid = adm6996_set_pvid,
580 .get_vlan_ports = adm6996_get_ports,
581 .set_vlan_ports = adm6996_set_ports,
582 .apply_config = adm6996_hw_apply,
583 .reset_switch = adm6996_reset_switch,
586 static int adm6996_config_init(struct phy_device *pdev)
588 struct adm6996_priv *priv;
589 struct switch_dev *swdev;
594 pdev->supported = ADVERTISED_100baseT_Full;
595 pdev->advertising = ADVERTISED_100baseT_Full;
597 if (pdev->addr != 0) {
598 pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n"
599 , pdev->attached_dev->name, pdev->addr);
603 priv = kzalloc(sizeof(struct adm6996_priv), GFP_KERNEL);
607 mutex_init(&priv->reg_mutex);
609 priv->read = adm6996_read_mii_reg;
610 priv->write = adm6996_write_mii_reg;
613 /* Detect type of chip */
614 old = r16(pdev, ADM_VID_CHECK);
615 test = old ^ (1 << 12);
616 w16(pdev, ADM_VID_CHECK, test);
617 test ^= r16(pdev, ADM_VID_CHECK);
618 if (test & (1 << 12)) {
620 * Bit 12 of this register is read-only.
621 * This is the FC model.
623 priv->model = ADM6996FC;
625 /* Bit 12 is read-write. This is the M model. */
626 priv->model = ADM6996M;
627 w16(pdev, ADM_VID_CHECK, old);
631 swdev->name = (adm6996_model_name[priv->model]);
632 swdev->cpu_port = ADM_CPU_PORT;
633 swdev->ports = ADM_NUM_PORTS;
634 swdev->vlans = ADM_NUM_VLANS;
635 swdev->ops = &adm6996_ops;
637 pr_info ("%s: %s model PHY found.\n", pdev->attached_dev->name,
640 mutex_lock(&priv->reg_mutex);
641 adm6996_perform_reset (priv);
642 mutex_unlock(&priv->reg_mutex);
644 if (priv->model == ADM6996M) {
645 if ((ret = register_switch(swdev, pdev->attached_dev)) < 0) {
655 * Warning: phydev->priv is NULL if phydev->addr != 0
657 static int adm6996_read_status(struct phy_device *phydev)
659 phydev->speed = SPEED_100;
660 phydev->duplex = DUPLEX_FULL;
666 * Warning: phydev->priv is NULL if phydev->addr != 0
668 static int adm6996_config_aneg(struct phy_device *phydev)
673 static int adm6996_fixup(struct phy_device *dev)
675 struct mii_bus *bus = dev->bus;
678 /* Our custom registers are at PHY addresses 0-10. Claim those. */
682 /* look for the switch on the bus */
683 reg = bus->read(bus, PHYADDR(ADM_SIG0)) & ADM_SIG0_MASK;
684 if (reg != ADM_SIG0_VAL)
687 reg = bus->read(bus, PHYADDR(ADM_SIG1)) & ADM_SIG1_MASK;
688 if (reg != ADM_SIG1_VAL)
691 dev->phy_id = (ADM_SIG0_VAL << 16) | ADM_SIG1_VAL;
696 static int adm6996_probe(struct phy_device *pdev)
701 static void adm6996_remove(struct phy_device *pdev)
703 struct adm6996_priv *priv = phy_to_adm(pdev);
705 if (priv != NULL && priv->model == ADM6996M)
706 unregister_switch(&priv->dev);
712 static struct phy_driver adm6996_driver = {
713 .name = "Infineon ADM6996",
714 .phy_id = (ADM_SIG0_VAL << 16) | ADM_SIG1_VAL,
715 .phy_id_mask = 0xffffffff,
716 .features = PHY_BASIC_FEATURES,
717 .probe = adm6996_probe,
718 .remove = adm6996_remove,
719 .config_init = &adm6996_config_init,
720 .config_aneg = &adm6996_config_aneg,
721 .read_status = &adm6996_read_status,
722 .driver = { .owner = THIS_MODULE,},
725 static int __init adm6996_init(void)
727 phy_register_fixup_for_id(PHY_ANY_ID, adm6996_fixup);
728 return phy_driver_register(&adm6996_driver);
731 static void __exit adm6996_exit(void)
733 phy_driver_unregister(&adm6996_driver);
736 module_init(adm6996_init);
737 module_exit(adm6996_exit);