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
);