xref: /openbmc/linux/include/net/dsa.h (revision 0d8bcdd3)
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 
14ea1f51beSAxel Lin #include <linux/if_ether.h>
15c8f0b869SBen Hutchings #include <linux/list.h>
16cf50dcc2SBen Hutchings #include <linux/timer.h>
17cf50dcc2SBen Hutchings #include <linux/workqueue.h>
18fa981d9aSFlorian Fainelli #include <linux/of.h>
19cf50dcc2SBen Hutchings 
20e84665c9SLennert Buytenhek #define DSA_MAX_SWITCHES	4
2191da11f8SLennert Buytenhek #define DSA_MAX_PORTS		12
2291da11f8SLennert Buytenhek 
23e84665c9SLennert Buytenhek struct dsa_chip_data {
24e84665c9SLennert Buytenhek 	/*
25e84665c9SLennert Buytenhek 	 * How to access the switch configuration registers.
26e84665c9SLennert Buytenhek 	 */
27e84665c9SLennert Buytenhek 	struct device	*mii_bus;
28e84665c9SLennert Buytenhek 	int		sw_addr;
29e84665c9SLennert Buytenhek 
30fa981d9aSFlorian Fainelli 	/* Device tree node pointer for this specific switch chip
31fa981d9aSFlorian Fainelli 	 * used during switch setup in case additional properties
32fa981d9aSFlorian Fainelli 	 * and resources needs to be used
33fa981d9aSFlorian Fainelli 	 */
34fa981d9aSFlorian Fainelli 	struct device_node *of_node;
35fa981d9aSFlorian Fainelli 
36e84665c9SLennert Buytenhek 	/*
37e84665c9SLennert Buytenhek 	 * The names of the switch's ports.  Use "cpu" to
38e84665c9SLennert Buytenhek 	 * designate the switch port that the cpu is connected to,
39e84665c9SLennert Buytenhek 	 * "dsa" to indicate that this port is a DSA link to
40e84665c9SLennert Buytenhek 	 * another switch, NULL to indicate the port is unused,
41e84665c9SLennert Buytenhek 	 * or any other string to indicate this is a physical port.
42e84665c9SLennert Buytenhek 	 */
43e84665c9SLennert Buytenhek 	char		*port_names[DSA_MAX_PORTS];
44bd47497aSFlorian Fainelli 	struct device_node *port_dn[DSA_MAX_PORTS];
45e84665c9SLennert Buytenhek 
46e84665c9SLennert Buytenhek 	/*
47e84665c9SLennert Buytenhek 	 * An array (with nr_chips elements) of which element [a]
48e84665c9SLennert Buytenhek 	 * indicates which port on this switch should be used to
49e84665c9SLennert Buytenhek 	 * send packets to that are destined for switch a.  Can be
50e84665c9SLennert Buytenhek 	 * NULL if there is only one switch chip.
51e84665c9SLennert Buytenhek 	 */
52e84665c9SLennert Buytenhek 	s8		*rtable;
53e84665c9SLennert Buytenhek };
54e84665c9SLennert Buytenhek 
5591da11f8SLennert Buytenhek struct dsa_platform_data {
5691da11f8SLennert Buytenhek 	/*
5791da11f8SLennert Buytenhek 	 * Reference to a Linux network interface that connects
58e84665c9SLennert Buytenhek 	 * to the root switch chip of the tree.
5991da11f8SLennert Buytenhek 	 */
6091da11f8SLennert Buytenhek 	struct device	*netdev;
6191da11f8SLennert Buytenhek 
6291da11f8SLennert Buytenhek 	/*
63e84665c9SLennert Buytenhek 	 * Info structs describing each of the switch chips
64e84665c9SLennert Buytenhek 	 * connected via this network interface.
6591da11f8SLennert Buytenhek 	 */
66e84665c9SLennert Buytenhek 	int		nr_chips;
67e84665c9SLennert Buytenhek 	struct dsa_chip_data	*chip;
6891da11f8SLennert Buytenhek };
6991da11f8SLennert Buytenhek 
703e8a72d1SFlorian Fainelli struct dsa_device_ops;
713e8a72d1SFlorian Fainelli 
72cf50dcc2SBen Hutchings struct dsa_switch_tree {
73cf50dcc2SBen Hutchings 	/*
74cf50dcc2SBen Hutchings 	 * Configuration data for the platform device that owns
75cf50dcc2SBen Hutchings 	 * this dsa switch tree instance.
76cf50dcc2SBen Hutchings 	 */
77cf50dcc2SBen Hutchings 	struct dsa_platform_data	*pd;
78cf85d08fSLennert Buytenhek 
79cf50dcc2SBen Hutchings 	/*
80cf50dcc2SBen Hutchings 	 * Reference to network device to use, and which tagging
81cf50dcc2SBen Hutchings 	 * protocol to use.
82cf50dcc2SBen Hutchings 	 */
83cf50dcc2SBen Hutchings 	struct net_device	*master_netdev;
843e8a72d1SFlorian Fainelli 	const struct dsa_device_ops	*ops;
85cf50dcc2SBen Hutchings 	__be16			tag_protocol;
86cf50dcc2SBen Hutchings 
87cf50dcc2SBen Hutchings 	/*
88cf50dcc2SBen Hutchings 	 * The switch and port to which the CPU is attached.
89cf50dcc2SBen Hutchings 	 */
90cf50dcc2SBen Hutchings 	s8			cpu_switch;
91cf50dcc2SBen Hutchings 	s8			cpu_port;
92cf50dcc2SBen Hutchings 
93cf50dcc2SBen Hutchings 	/*
94cf50dcc2SBen Hutchings 	 * Link state polling.
95cf50dcc2SBen Hutchings 	 */
96cf50dcc2SBen Hutchings 	int			link_poll_needed;
97cf50dcc2SBen Hutchings 	struct work_struct	link_poll_work;
98cf50dcc2SBen Hutchings 	struct timer_list	link_poll_timer;
99cf50dcc2SBen Hutchings 
100cf50dcc2SBen Hutchings 	/*
101cf50dcc2SBen Hutchings 	 * Data for the individual switch chips.
102cf50dcc2SBen Hutchings 	 */
103cf50dcc2SBen Hutchings 	struct dsa_switch	*ds[DSA_MAX_SWITCHES];
104cf50dcc2SBen Hutchings };
105cf50dcc2SBen Hutchings 
106c8f0b869SBen Hutchings struct dsa_switch {
107c8f0b869SBen Hutchings 	/*
108c8f0b869SBen Hutchings 	 * Parent switch tree, and switch index.
109c8f0b869SBen Hutchings 	 */
110c8f0b869SBen Hutchings 	struct dsa_switch_tree	*dst;
111c8f0b869SBen Hutchings 	int			index;
112c8f0b869SBen Hutchings 
113c8f0b869SBen Hutchings 	/*
114c8f0b869SBen Hutchings 	 * Configuration data for this switch.
115c8f0b869SBen Hutchings 	 */
116c8f0b869SBen Hutchings 	struct dsa_chip_data	*pd;
117c8f0b869SBen Hutchings 
118c8f0b869SBen Hutchings 	/*
119c8f0b869SBen Hutchings 	 * The used switch driver.
120c8f0b869SBen Hutchings 	 */
121c8f0b869SBen Hutchings 	struct dsa_switch_driver	*drv;
122c8f0b869SBen Hutchings 
123c8f0b869SBen Hutchings 	/*
124c8f0b869SBen Hutchings 	 * Reference to mii bus to use.
125c8f0b869SBen Hutchings 	 */
126c8f0b869SBen Hutchings 	struct mii_bus		*master_mii_bus;
127c8f0b869SBen Hutchings 
128c8f0b869SBen Hutchings 	/*
129c8f0b869SBen Hutchings 	 * Slave mii_bus and devices for the individual ports.
130c8f0b869SBen Hutchings 	 */
131c8f0b869SBen Hutchings 	u32			dsa_port_mask;
132c8f0b869SBen Hutchings 	u32			phys_port_mask;
1330d8bcdd3SFlorian Fainelli 	u32			phys_mii_mask;
134c8f0b869SBen Hutchings 	struct mii_bus		*slave_mii_bus;
135c8f0b869SBen Hutchings 	struct net_device	*ports[DSA_MAX_PORTS];
136c8f0b869SBen Hutchings };
137c8f0b869SBen Hutchings 
138c8f0b869SBen Hutchings static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
139c8f0b869SBen Hutchings {
140c8f0b869SBen Hutchings 	return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port);
141c8f0b869SBen Hutchings }
142c8f0b869SBen Hutchings 
143c8f0b869SBen Hutchings static inline u8 dsa_upstream_port(struct dsa_switch *ds)
144c8f0b869SBen Hutchings {
145c8f0b869SBen Hutchings 	struct dsa_switch_tree *dst = ds->dst;
146c8f0b869SBen Hutchings 
147c8f0b869SBen Hutchings 	/*
148c8f0b869SBen Hutchings 	 * If this is the root switch (i.e. the switch that connects
149c8f0b869SBen Hutchings 	 * to the CPU), return the cpu port number on this switch.
150c8f0b869SBen Hutchings 	 * Else return the (DSA) port number that connects to the
151c8f0b869SBen Hutchings 	 * switch that is one hop closer to the cpu.
152c8f0b869SBen Hutchings 	 */
153c8f0b869SBen Hutchings 	if (dst->cpu_switch == ds->index)
154c8f0b869SBen Hutchings 		return dst->cpu_port;
155c8f0b869SBen Hutchings 	else
156c8f0b869SBen Hutchings 		return ds->pd->rtable[dst->cpu_switch];
157c8f0b869SBen Hutchings }
158c8f0b869SBen Hutchings 
159c8f0b869SBen Hutchings struct dsa_switch_driver {
160c8f0b869SBen Hutchings 	struct list_head	list;
161c8f0b869SBen Hutchings 
162c8f0b869SBen Hutchings 	__be16			tag_protocol;
163c8f0b869SBen Hutchings 	int			priv_size;
164c8f0b869SBen Hutchings 
165c8f0b869SBen Hutchings 	/*
166c8f0b869SBen Hutchings 	 * Probing and setup.
167c8f0b869SBen Hutchings 	 */
168c8f0b869SBen Hutchings 	char	*(*probe)(struct mii_bus *bus, int sw_addr);
169c8f0b869SBen Hutchings 	int	(*setup)(struct dsa_switch *ds);
170c8f0b869SBen Hutchings 	int	(*set_addr)(struct dsa_switch *ds, u8 *addr);
171c8f0b869SBen Hutchings 
172c8f0b869SBen Hutchings 	/*
173c8f0b869SBen Hutchings 	 * Access to the switch's PHY registers.
174c8f0b869SBen Hutchings 	 */
175c8f0b869SBen Hutchings 	int	(*phy_read)(struct dsa_switch *ds, int port, int regnum);
176c8f0b869SBen Hutchings 	int	(*phy_write)(struct dsa_switch *ds, int port,
177c8f0b869SBen Hutchings 			     int regnum, u16 val);
178c8f0b869SBen Hutchings 
179c8f0b869SBen Hutchings 	/*
180c8f0b869SBen Hutchings 	 * Link state polling and IRQ handling.
181c8f0b869SBen Hutchings 	 */
182c8f0b869SBen Hutchings 	void	(*poll_link)(struct dsa_switch *ds);
183c8f0b869SBen Hutchings 
184c8f0b869SBen Hutchings 	/*
185c8f0b869SBen Hutchings 	 * ethtool hardware statistics.
186c8f0b869SBen Hutchings 	 */
187c8f0b869SBen Hutchings 	void	(*get_strings)(struct dsa_switch *ds, int port, uint8_t *data);
188c8f0b869SBen Hutchings 	void	(*get_ethtool_stats)(struct dsa_switch *ds,
189c8f0b869SBen Hutchings 				     int port, uint64_t *data);
190c8f0b869SBen Hutchings 	int	(*get_sset_count)(struct dsa_switch *ds);
191c8f0b869SBen Hutchings };
192c8f0b869SBen Hutchings 
193c8f0b869SBen Hutchings void register_switch_driver(struct dsa_switch_driver *type);
194c8f0b869SBen Hutchings void unregister_switch_driver(struct dsa_switch_driver *type);
195c8f0b869SBen Hutchings 
1967fa857edSFlorian Fainelli static inline void *ds_to_priv(struct dsa_switch *ds)
1977fa857edSFlorian Fainelli {
1987fa857edSFlorian Fainelli 	return (void *)(ds + 1);
1997fa857edSFlorian Fainelli }
2007fa857edSFlorian Fainelli 
20191da11f8SLennert Buytenhek #endif
202