2 * Lantiq PSB6970 (Tantos) Switch driver
4 * Copyright (c) 2009,2010 Team Embedded.
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.
10 * The switch programming done in this driver follows the
11 * "Ethernet Traffic Separation using VLAN" Application Note as
12 * published by Lantiq.
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>
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)
26 #define PHYADDR(_reg) ((_reg >> 5) & 0xff), (_reg & 0x1f)
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
35 /* --- VLAN filter table --- */
36 #define PSB6970_VFxL(i) ((i)*2+0x10) /* VLAN Filter Low */
37 #define PSB6970_VFxL_VV (1 << 15) /* VLAN_Valid */
39 #define PSB6970_VFxH(i) ((i)*2+0x11) /* VLAN Filter High */
40 #define PSB6970_VFxH_TM_SHIFT 7 /* Tagged Member */
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 */
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 */
53 #define PSB6970_DVID(p) ((p)*0x20+4) /* Default VLAN ID & Priority */
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
;
62 /* all fields below are cleared on reset */
64 u16 vlan_id
[PSB6970_MAX_VLANS
];
65 u8 vlan_table
[PSB6970_MAX_VLANS
];
67 u16 pvid
[PSB6970_NUM_PORTS
];
70 #define to_psb6970(_dev) container_of(_dev, struct psb6970_priv, dev)
72 static u16
psb6970_mii_read(struct phy_device
*phydev
, int reg
)
74 struct mii_bus
*bus
= phydev
->mdio
.bus
;
76 return bus
->read(bus
, PHYADDR(reg
));
79 static void psb6970_mii_write(struct phy_device
*phydev
, int reg
, u16 val
)
81 struct mii_bus
*bus
= phydev
->mdio
.bus
;
83 bus
->write(bus
, PHYADDR(reg
), val
);
87 psb6970_set_vlan(struct switch_dev
*dev
, const struct switch_attr
*attr
,
88 struct switch_val
*val
)
90 struct psb6970_priv
*priv
= to_psb6970(dev
);
91 priv
->vlan
= !!val
->value
.i
;
96 psb6970_get_vlan(struct switch_dev
*dev
, const struct switch_attr
*attr
,
97 struct switch_val
*val
)
99 struct psb6970_priv
*priv
= to_psb6970(dev
);
100 val
->value
.i
= priv
->vlan
;
104 static int psb6970_set_pvid(struct switch_dev
*dev
, int port
, int vlan
)
106 struct psb6970_priv
*priv
= to_psb6970(dev
);
108 /* make sure no invalid PVIDs get set */
109 if (vlan
>= dev
->vlans
)
112 priv
->pvid
[port
] = vlan
;
116 static int psb6970_get_pvid(struct switch_dev
*dev
, int port
, int *vlan
)
118 struct psb6970_priv
*priv
= to_psb6970(dev
);
119 *vlan
= priv
->pvid
[port
];
124 psb6970_set_vid(struct switch_dev
*dev
, const struct switch_attr
*attr
,
125 struct switch_val
*val
)
127 struct psb6970_priv
*priv
= to_psb6970(dev
);
128 priv
->vlan_id
[val
->port_vlan
] = val
->value
.i
;
133 psb6970_get_vid(struct switch_dev
*dev
, const struct switch_attr
*attr
,
134 struct switch_val
*val
)
136 struct psb6970_priv
*priv
= to_psb6970(dev
);
137 val
->value
.i
= priv
->vlan_id
[val
->port_vlan
];
141 static struct switch_attr psb6970_globals
[] = {
143 .type
= SWITCH_TYPE_INT
,
144 .name
= "enable_vlan",
145 .description
= "Enable VLAN mode",
146 .set
= psb6970_set_vlan
,
147 .get
= psb6970_get_vlan
,
151 static struct switch_attr psb6970_port
[] = {
154 static struct switch_attr psb6970_vlan
[] = {
156 .type
= SWITCH_TYPE_INT
,
158 .description
= "VLAN ID (0-4094)",
159 .set
= psb6970_set_vid
,
160 .get
= psb6970_get_vid
,
165 static int psb6970_get_ports(struct switch_dev
*dev
, struct switch_val
*val
)
167 struct psb6970_priv
*priv
= to_psb6970(dev
);
168 u8 ports
= priv
->vlan_table
[val
->port_vlan
];
172 for (i
= 0; i
< PSB6970_NUM_PORTS
; i
++) {
173 struct switch_port
*p
;
175 if (!(ports
& (1 << i
)))
178 p
= &val
->value
.ports
[val
->len
++];
180 if (priv
->vlan_tagged
& (1 << i
))
181 p
->flags
= (1 << SWITCH_PORT_FLAG_TAGGED
);
188 static int psb6970_set_ports(struct switch_dev
*dev
, struct switch_val
*val
)
190 struct psb6970_priv
*priv
= to_psb6970(dev
);
191 u8
*vt
= &priv
->vlan_table
[val
->port_vlan
];
195 for (i
= 0; i
< val
->len
; i
++) {
196 struct switch_port
*p
= &val
->value
.ports
[i
];
198 if (p
->flags
& (1 << SWITCH_PORT_FLAG_TAGGED
))
199 priv
->vlan_tagged
|= (1 << p
->id
);
201 priv
->vlan_tagged
&= ~(1 << p
->id
);
202 priv
->pvid
[p
->id
] = val
->port_vlan
;
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
)
209 priv
->vlan_table
[j
] &= ~(1 << p
->id
);
218 static int psb6970_hw_apply(struct switch_dev
*dev
)
220 struct psb6970_priv
*priv
= to_psb6970(dev
);
223 mutex_lock(&priv
->reg_mutex
);
226 /* into the vlan translation unit */
227 for (j
= 0; j
< PSB6970_MAX_VLANS
; j
++) {
228 u8 vp
= priv
->vlan_table
[j
];
231 priv
->write(priv
->phy
, PSB6970_VFxL(j
),
232 PSB6970_VFxL_VV
| priv
->vlan_id
[j
]);
233 priv
->write(priv
->phy
, PSB6970_VFxH(j
),
236 PSB6970_VFxH_TM_SHIFT
) | vp
);
237 } else /* clear VLAN Valid flag for unused vlans */
238 priv
->write(priv
->phy
, PSB6970_VFxL(j
), 0);
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;
248 ec
= PSB6970_EC_IFNTE
;
249 dvid
= priv
->vlan_id
[priv
->pvid
[i
]];
250 pbvm
|= PSB6970_PBVM_TBVE
| PSB6970_PBVM_VMCE
;
252 if ((i
<< 1) & priv
->vlan_tagged
)
253 pbvm
|= PSB6970_PBVM_AOVTP
| PSB6970_PBVM_VC
;
256 priv
->write(priv
->phy
, PSB6970_PBVM(i
), pbvm
);
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
);
264 mutex_unlock(&priv
->reg_mutex
);
268 static int psb6970_reset_switch(struct switch_dev
*dev
)
270 struct psb6970_priv
*priv
= to_psb6970(dev
);
273 mutex_lock(&priv
->reg_mutex
);
275 memset(&priv
->vlan
, 0, sizeof(struct psb6970_priv
) -
276 offsetof(struct psb6970_priv
, vlan
));
278 for (i
= 0; i
< PSB6970_MAX_VLANS
; i
++)
279 priv
->vlan_id
[i
] = i
;
281 mutex_unlock(&priv
->reg_mutex
);
283 return psb6970_hw_apply(dev
);
286 static const struct switch_dev_ops psb6970_ops
= {
288 .attr
= psb6970_globals
,
289 .n_attr
= ARRAY_SIZE(psb6970_globals
),
292 .attr
= psb6970_port
,
293 .n_attr
= ARRAY_SIZE(psb6970_port
),
296 .attr
= psb6970_vlan
,
297 .n_attr
= ARRAY_SIZE(psb6970_vlan
),
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
,
307 static int psb6970_config_init(struct phy_device
*pdev
)
309 struct psb6970_priv
*priv
;
310 struct net_device
*dev
= pdev
->attached_dev
;
311 struct switch_dev
*swdev
;
314 priv
= kzalloc(sizeof(struct psb6970_priv
), GFP_KERNEL
);
320 if (pdev
->mdio
.addr
== 0)
321 printk(KERN_INFO
"%s: psb6970 switch driver attached.\n",
322 pdev
->attached_dev
->name
);
324 if (pdev
->mdio
.addr
!= 0) {
329 linkmode_zero(pdev
->supported
);
330 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT
, pdev
->supported
);
331 linkmode_copy(pdev
->advertising
, pdev
->supported
);
333 mutex_init(&priv
->reg_mutex
);
334 priv
->read
= psb6970_mii_read
;
335 priv
->write
= psb6970_mii_write
;
340 swdev
->cpu_port
= PSB6970_DEFAULT_PORT_CPU
;
341 swdev
->ops
= &psb6970_ops
;
343 swdev
->name
= "Lantiq PSB6970";
344 swdev
->vlans
= PSB6970_MAX_VLANS
;
345 swdev
->ports
= PSB6970_NUM_PORTS
;
347 if ((ret
= register_switch(&priv
->dev
, pdev
->attached_dev
)) < 0) {
352 ret
= psb6970_reset_switch(&priv
->dev
);
362 static int psb6970_read_status(struct phy_device
*phydev
)
364 phydev
->speed
= SPEED_100
;
365 phydev
->duplex
= DUPLEX_FULL
;
368 phydev
->state
= PHY_RUNNING
;
369 netif_carrier_on(phydev
->attached_dev
);
370 phydev
->adjust_link(phydev
->attached_dev
);
375 static int psb6970_config_aneg(struct phy_device
*phydev
)
380 static int psb6970_probe(struct phy_device
*pdev
)
385 static void psb6970_remove(struct phy_device
*pdev
)
387 struct psb6970_priv
*priv
= pdev
->priv
;
392 if (pdev
->mdio
.addr
== 0)
393 unregister_switch(&priv
->dev
);
397 static int psb6970_fixup(struct phy_device
*dev
)
399 struct mii_bus
*bus
= dev
->mdio
.bus
;
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
)
407 dev
->phy_id
= (reg
<< 16);
408 dev
->phy_id
|= bus
->read(bus
, PHYADDR(PSB6970_CI0
)) & PSB6970_CI0_MASK
;
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
,
425 int __init
psb6970_init(void)
427 phy_register_fixup_for_id(PHY_ANY_ID
, psb6970_fixup
);
428 return phy_driver_register(&psb6970_driver
, THIS_MODULE
);
431 module_init(psb6970_init
);
433 void __exit
psb6970_exit(void)
435 phy_driver_unregister(&psb6970_driver
);
438 module_exit(psb6970_exit
);
440 MODULE_DESCRIPTION("Lantiq PSB6970 Switch");
441 MODULE_AUTHOR("Ithamar R. Adema <ithamar.adema@team-embedded.nl>");
442 MODULE_LICENSE("GPL");