xref: /linux/include/net/dsa.h (revision c8f0b86996c88081095124d16b869e8d8a1c02c5)
191da11f8SLennert Buytenhek /*
291da11f8SLennert Buytenhek  * include/net/dsa.h - Driver for Distributed Switch Architecture switch chips
3e84665c9SLennert Buytenhek  * Copyright (c) 2008-2009 Marvell Semiconductor
491da11f8SLennert Buytenhek  *
591da11f8SLennert Buytenhek  * This program is free software; you can redistribute it and/or modify
691da11f8SLennert Buytenhek  * it under the terms of the GNU General Public License as published by
791da11f8SLennert Buytenhek  * the Free Software Foundation; either version 2 of the License, or
891da11f8SLennert Buytenhek  * (at your option) any later version.
991da11f8SLennert Buytenhek  */
1091da11f8SLennert Buytenhek 
1191da11f8SLennert Buytenhek #ifndef __LINUX_NET_DSA_H
1291da11f8SLennert Buytenhek #define __LINUX_NET_DSA_H
1391da11f8SLennert Buytenhek 
14*c8f0b869SBen Hutchings #include <linux/list.h>
15cf50dcc2SBen Hutchings #include <linux/timer.h>
16cf50dcc2SBen Hutchings #include <linux/workqueue.h>
17cf50dcc2SBen Hutchings 
18e84665c9SLennert Buytenhek #define DSA_MAX_SWITCHES	4
1991da11f8SLennert Buytenhek #define DSA_MAX_PORTS		12
2091da11f8SLennert Buytenhek 
21e84665c9SLennert Buytenhek struct dsa_chip_data {
22e84665c9SLennert Buytenhek 	/*
23e84665c9SLennert Buytenhek 	 * How to access the switch configuration registers.
24e84665c9SLennert Buytenhek 	 */
25e84665c9SLennert Buytenhek 	struct device	*mii_bus;
26e84665c9SLennert Buytenhek 	int		sw_addr;
27e84665c9SLennert Buytenhek 
28e84665c9SLennert Buytenhek 	/*
29e84665c9SLennert Buytenhek 	 * The names of the switch's ports.  Use "cpu" to
30e84665c9SLennert Buytenhek 	 * designate the switch port that the cpu is connected to,
31e84665c9SLennert Buytenhek 	 * "dsa" to indicate that this port is a DSA link to
32e84665c9SLennert Buytenhek 	 * another switch, NULL to indicate the port is unused,
33e84665c9SLennert Buytenhek 	 * or any other string to indicate this is a physical port.
34e84665c9SLennert Buytenhek 	 */
35e84665c9SLennert Buytenhek 	char		*port_names[DSA_MAX_PORTS];
36e84665c9SLennert Buytenhek 
37e84665c9SLennert Buytenhek 	/*
38e84665c9SLennert Buytenhek 	 * An array (with nr_chips elements) of which element [a]
39e84665c9SLennert Buytenhek 	 * indicates which port on this switch should be used to
40e84665c9SLennert Buytenhek 	 * send packets to that are destined for switch a.  Can be
41e84665c9SLennert Buytenhek 	 * NULL if there is only one switch chip.
42e84665c9SLennert Buytenhek 	 */
43e84665c9SLennert Buytenhek 	s8		*rtable;
44e84665c9SLennert Buytenhek };
45e84665c9SLennert Buytenhek 
4691da11f8SLennert Buytenhek struct dsa_platform_data {
4791da11f8SLennert Buytenhek 	/*
4891da11f8SLennert Buytenhek 	 * Reference to a Linux network interface that connects
49e84665c9SLennert Buytenhek 	 * to the root switch chip of the tree.
5091da11f8SLennert Buytenhek 	 */
5191da11f8SLennert Buytenhek 	struct device	*netdev;
5291da11f8SLennert Buytenhek 
5391da11f8SLennert Buytenhek 	/*
54e84665c9SLennert Buytenhek 	 * Info structs describing each of the switch chips
55e84665c9SLennert Buytenhek 	 * connected via this network interface.
5691da11f8SLennert Buytenhek 	 */
57e84665c9SLennert Buytenhek 	int		nr_chips;
58e84665c9SLennert Buytenhek 	struct dsa_chip_data	*chip;
5991da11f8SLennert Buytenhek };
6091da11f8SLennert Buytenhek 
61cf50dcc2SBen Hutchings struct dsa_switch_tree {
62cf50dcc2SBen Hutchings 	/*
63cf50dcc2SBen Hutchings 	 * Configuration data for the platform device that owns
64cf50dcc2SBen Hutchings 	 * this dsa switch tree instance.
65cf50dcc2SBen Hutchings 	 */
66cf50dcc2SBen Hutchings 	struct dsa_platform_data	*pd;
67cf85d08fSLennert Buytenhek 
68cf50dcc2SBen Hutchings 	/*
69cf50dcc2SBen Hutchings 	 * Reference to network device to use, and which tagging
70cf50dcc2SBen Hutchings 	 * protocol to use.
71cf50dcc2SBen Hutchings 	 */
72cf50dcc2SBen Hutchings 	struct net_device	*master_netdev;
73cf50dcc2SBen Hutchings 	__be16			tag_protocol;
74cf50dcc2SBen Hutchings 
75cf50dcc2SBen Hutchings 	/*
76cf50dcc2SBen Hutchings 	 * The switch and port to which the CPU is attached.
77cf50dcc2SBen Hutchings 	 */
78cf50dcc2SBen Hutchings 	s8			cpu_switch;
79cf50dcc2SBen Hutchings 	s8			cpu_port;
80cf50dcc2SBen Hutchings 
81cf50dcc2SBen Hutchings 	/*
82cf50dcc2SBen Hutchings 	 * Link state polling.
83cf50dcc2SBen Hutchings 	 */
84cf50dcc2SBen Hutchings 	int			link_poll_needed;
85cf50dcc2SBen Hutchings 	struct work_struct	link_poll_work;
86cf50dcc2SBen Hutchings 	struct timer_list	link_poll_timer;
87cf50dcc2SBen Hutchings 
88cf50dcc2SBen Hutchings 	/*
89cf50dcc2SBen Hutchings 	 * Data for the individual switch chips.
90cf50dcc2SBen Hutchings 	 */
91cf50dcc2SBen Hutchings 	struct dsa_switch	*ds[DSA_MAX_SWITCHES];
92cf50dcc2SBen Hutchings };
93cf50dcc2SBen Hutchings 
94*c8f0b869SBen Hutchings struct dsa_switch {
95*c8f0b869SBen Hutchings 	/*
96*c8f0b869SBen Hutchings 	 * Parent switch tree, and switch index.
97*c8f0b869SBen Hutchings 	 */
98*c8f0b869SBen Hutchings 	struct dsa_switch_tree	*dst;
99*c8f0b869SBen Hutchings 	int			index;
100*c8f0b869SBen Hutchings 
101*c8f0b869SBen Hutchings 	/*
102*c8f0b869SBen Hutchings 	 * Configuration data for this switch.
103*c8f0b869SBen Hutchings 	 */
104*c8f0b869SBen Hutchings 	struct dsa_chip_data	*pd;
105*c8f0b869SBen Hutchings 
106*c8f0b869SBen Hutchings 	/*
107*c8f0b869SBen Hutchings 	 * The used switch driver.
108*c8f0b869SBen Hutchings 	 */
109*c8f0b869SBen Hutchings 	struct dsa_switch_driver	*drv;
110*c8f0b869SBen Hutchings 
111*c8f0b869SBen Hutchings 	/*
112*c8f0b869SBen Hutchings 	 * Reference to mii bus to use.
113*c8f0b869SBen Hutchings 	 */
114*c8f0b869SBen Hutchings 	struct mii_bus		*master_mii_bus;
115*c8f0b869SBen Hutchings 
116*c8f0b869SBen Hutchings 	/*
117*c8f0b869SBen Hutchings 	 * Slave mii_bus and devices for the individual ports.
118*c8f0b869SBen Hutchings 	 */
119*c8f0b869SBen Hutchings 	u32			dsa_port_mask;
120*c8f0b869SBen Hutchings 	u32			phys_port_mask;
121*c8f0b869SBen Hutchings 	struct mii_bus		*slave_mii_bus;
122*c8f0b869SBen Hutchings 	struct net_device	*ports[DSA_MAX_PORTS];
123*c8f0b869SBen Hutchings };
124*c8f0b869SBen Hutchings 
125*c8f0b869SBen Hutchings static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
126*c8f0b869SBen Hutchings {
127*c8f0b869SBen Hutchings 	return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port);
128*c8f0b869SBen Hutchings }
129*c8f0b869SBen Hutchings 
130*c8f0b869SBen Hutchings static inline u8 dsa_upstream_port(struct dsa_switch *ds)
131*c8f0b869SBen Hutchings {
132*c8f0b869SBen Hutchings 	struct dsa_switch_tree *dst = ds->dst;
133*c8f0b869SBen Hutchings 
134*c8f0b869SBen Hutchings 	/*
135*c8f0b869SBen Hutchings 	 * If this is the root switch (i.e. the switch that connects
136*c8f0b869SBen Hutchings 	 * to the CPU), return the cpu port number on this switch.
137*c8f0b869SBen Hutchings 	 * Else return the (DSA) port number that connects to the
138*c8f0b869SBen Hutchings 	 * switch that is one hop closer to the cpu.
139*c8f0b869SBen Hutchings 	 */
140*c8f0b869SBen Hutchings 	if (dst->cpu_switch == ds->index)
141*c8f0b869SBen Hutchings 		return dst->cpu_port;
142*c8f0b869SBen Hutchings 	else
143*c8f0b869SBen Hutchings 		return ds->pd->rtable[dst->cpu_switch];
144*c8f0b869SBen Hutchings }
145*c8f0b869SBen Hutchings 
146*c8f0b869SBen Hutchings struct dsa_switch_driver {
147*c8f0b869SBen Hutchings 	struct list_head	list;
148*c8f0b869SBen Hutchings 
149*c8f0b869SBen Hutchings 	__be16			tag_protocol;
150*c8f0b869SBen Hutchings 	int			priv_size;
151*c8f0b869SBen Hutchings 
152*c8f0b869SBen Hutchings 	/*
153*c8f0b869SBen Hutchings 	 * Probing and setup.
154*c8f0b869SBen Hutchings 	 */
155*c8f0b869SBen Hutchings 	char	*(*probe)(struct mii_bus *bus, int sw_addr);
156*c8f0b869SBen Hutchings 	int	(*setup)(struct dsa_switch *ds);
157*c8f0b869SBen Hutchings 	int	(*set_addr)(struct dsa_switch *ds, u8 *addr);
158*c8f0b869SBen Hutchings 
159*c8f0b869SBen Hutchings 	/*
160*c8f0b869SBen Hutchings 	 * Access to the switch's PHY registers.
161*c8f0b869SBen Hutchings 	 */
162*c8f0b869SBen Hutchings 	int	(*phy_read)(struct dsa_switch *ds, int port, int regnum);
163*c8f0b869SBen Hutchings 	int	(*phy_write)(struct dsa_switch *ds, int port,
164*c8f0b869SBen Hutchings 			     int regnum, u16 val);
165*c8f0b869SBen Hutchings 
166*c8f0b869SBen Hutchings 	/*
167*c8f0b869SBen Hutchings 	 * Link state polling and IRQ handling.
168*c8f0b869SBen Hutchings 	 */
169*c8f0b869SBen Hutchings 	void	(*poll_link)(struct dsa_switch *ds);
170*c8f0b869SBen Hutchings 
171*c8f0b869SBen Hutchings 	/*
172*c8f0b869SBen Hutchings 	 * ethtool hardware statistics.
173*c8f0b869SBen Hutchings 	 */
174*c8f0b869SBen Hutchings 	void	(*get_strings)(struct dsa_switch *ds, int port, uint8_t *data);
175*c8f0b869SBen Hutchings 	void	(*get_ethtool_stats)(struct dsa_switch *ds,
176*c8f0b869SBen Hutchings 				     int port, uint64_t *data);
177*c8f0b869SBen Hutchings 	int	(*get_sset_count)(struct dsa_switch *ds);
178*c8f0b869SBen Hutchings };
179*c8f0b869SBen Hutchings 
180*c8f0b869SBen Hutchings void register_switch_driver(struct dsa_switch_driver *type);
181*c8f0b869SBen Hutchings void unregister_switch_driver(struct dsa_switch_driver *type);
182*c8f0b869SBen Hutchings 
183cf50dcc2SBen Hutchings /*
184cf50dcc2SBen Hutchings  * The original DSA tag format and some other tag formats have no
185cf50dcc2SBen Hutchings  * ethertype, which means that we need to add a little hack to the
186cf50dcc2SBen Hutchings  * networking receive path to make sure that received frames get
187cf50dcc2SBen Hutchings  * the right ->protocol assigned to them when one of those tag
188cf50dcc2SBen Hutchings  * formats is in use.
189cf50dcc2SBen Hutchings  */
190cf50dcc2SBen Hutchings static inline bool dsa_uses_dsa_tags(struct dsa_switch_tree *dst)
191cf50dcc2SBen Hutchings {
192cf50dcc2SBen Hutchings 	return !!(dst->tag_protocol == htons(ETH_P_DSA));
193cf50dcc2SBen Hutchings }
194cf50dcc2SBen Hutchings 
195cf50dcc2SBen Hutchings static inline bool dsa_uses_trailer_tags(struct dsa_switch_tree *dst)
196cf50dcc2SBen Hutchings {
197cf50dcc2SBen Hutchings 	return !!(dst->tag_protocol == htons(ETH_P_TRAILER));
198cf50dcc2SBen Hutchings }
19991da11f8SLennert Buytenhek 
20091da11f8SLennert Buytenhek #endif
201