xref: /openbmc/linux/include/net/dsa.h (revision 3e8a72d1)
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>
18cf50dcc2SBen Hutchings 
19e84665c9SLennert Buytenhek #define DSA_MAX_SWITCHES	4
2091da11f8SLennert Buytenhek #define DSA_MAX_PORTS		12
2191da11f8SLennert Buytenhek 
22e84665c9SLennert Buytenhek struct dsa_chip_data {
23e84665c9SLennert Buytenhek 	/*
24e84665c9SLennert Buytenhek 	 * How to access the switch configuration registers.
25e84665c9SLennert Buytenhek 	 */
26e84665c9SLennert Buytenhek 	struct device	*mii_bus;
27e84665c9SLennert Buytenhek 	int		sw_addr;
28e84665c9SLennert Buytenhek 
29e84665c9SLennert Buytenhek 	/*
30e84665c9SLennert Buytenhek 	 * The names of the switch's ports.  Use "cpu" to
31e84665c9SLennert Buytenhek 	 * designate the switch port that the cpu is connected to,
32e84665c9SLennert Buytenhek 	 * "dsa" to indicate that this port is a DSA link to
33e84665c9SLennert Buytenhek 	 * another switch, NULL to indicate the port is unused,
34e84665c9SLennert Buytenhek 	 * or any other string to indicate this is a physical port.
35e84665c9SLennert Buytenhek 	 */
36e84665c9SLennert Buytenhek 	char		*port_names[DSA_MAX_PORTS];
37e84665c9SLennert Buytenhek 
38e84665c9SLennert Buytenhek 	/*
39e84665c9SLennert Buytenhek 	 * An array (with nr_chips elements) of which element [a]
40e84665c9SLennert Buytenhek 	 * indicates which port on this switch should be used to
41e84665c9SLennert Buytenhek 	 * send packets to that are destined for switch a.  Can be
42e84665c9SLennert Buytenhek 	 * NULL if there is only one switch chip.
43e84665c9SLennert Buytenhek 	 */
44e84665c9SLennert Buytenhek 	s8		*rtable;
45e84665c9SLennert Buytenhek };
46e84665c9SLennert Buytenhek 
4791da11f8SLennert Buytenhek struct dsa_platform_data {
4891da11f8SLennert Buytenhek 	/*
4991da11f8SLennert Buytenhek 	 * Reference to a Linux network interface that connects
50e84665c9SLennert Buytenhek 	 * to the root switch chip of the tree.
5191da11f8SLennert Buytenhek 	 */
5291da11f8SLennert Buytenhek 	struct device	*netdev;
5391da11f8SLennert Buytenhek 
5491da11f8SLennert Buytenhek 	/*
55e84665c9SLennert Buytenhek 	 * Info structs describing each of the switch chips
56e84665c9SLennert Buytenhek 	 * connected via this network interface.
5791da11f8SLennert Buytenhek 	 */
58e84665c9SLennert Buytenhek 	int		nr_chips;
59e84665c9SLennert Buytenhek 	struct dsa_chip_data	*chip;
6091da11f8SLennert Buytenhek };
6191da11f8SLennert Buytenhek 
623e8a72d1SFlorian Fainelli struct dsa_device_ops;
633e8a72d1SFlorian Fainelli 
64cf50dcc2SBen Hutchings struct dsa_switch_tree {
65cf50dcc2SBen Hutchings 	/*
66cf50dcc2SBen Hutchings 	 * Configuration data for the platform device that owns
67cf50dcc2SBen Hutchings 	 * this dsa switch tree instance.
68cf50dcc2SBen Hutchings 	 */
69cf50dcc2SBen Hutchings 	struct dsa_platform_data	*pd;
70cf85d08fSLennert Buytenhek 
71cf50dcc2SBen Hutchings 	/*
72cf50dcc2SBen Hutchings 	 * Reference to network device to use, and which tagging
73cf50dcc2SBen Hutchings 	 * protocol to use.
74cf50dcc2SBen Hutchings 	 */
75cf50dcc2SBen Hutchings 	struct net_device	*master_netdev;
763e8a72d1SFlorian Fainelli 	const struct dsa_device_ops	*ops;
77cf50dcc2SBen Hutchings 	__be16			tag_protocol;
78cf50dcc2SBen Hutchings 
79cf50dcc2SBen Hutchings 	/*
80cf50dcc2SBen Hutchings 	 * The switch and port to which the CPU is attached.
81cf50dcc2SBen Hutchings 	 */
82cf50dcc2SBen Hutchings 	s8			cpu_switch;
83cf50dcc2SBen Hutchings 	s8			cpu_port;
84cf50dcc2SBen Hutchings 
85cf50dcc2SBen Hutchings 	/*
86cf50dcc2SBen Hutchings 	 * Link state polling.
87cf50dcc2SBen Hutchings 	 */
88cf50dcc2SBen Hutchings 	int			link_poll_needed;
89cf50dcc2SBen Hutchings 	struct work_struct	link_poll_work;
90cf50dcc2SBen Hutchings 	struct timer_list	link_poll_timer;
91cf50dcc2SBen Hutchings 
92cf50dcc2SBen Hutchings 	/*
93cf50dcc2SBen Hutchings 	 * Data for the individual switch chips.
94cf50dcc2SBen Hutchings 	 */
95cf50dcc2SBen Hutchings 	struct dsa_switch	*ds[DSA_MAX_SWITCHES];
96cf50dcc2SBen Hutchings };
97cf50dcc2SBen Hutchings 
98c8f0b869SBen Hutchings struct dsa_switch {
99c8f0b869SBen Hutchings 	/*
100c8f0b869SBen Hutchings 	 * Parent switch tree, and switch index.
101c8f0b869SBen Hutchings 	 */
102c8f0b869SBen Hutchings 	struct dsa_switch_tree	*dst;
103c8f0b869SBen Hutchings 	int			index;
104c8f0b869SBen Hutchings 
105c8f0b869SBen Hutchings 	/*
106c8f0b869SBen Hutchings 	 * Configuration data for this switch.
107c8f0b869SBen Hutchings 	 */
108c8f0b869SBen Hutchings 	struct dsa_chip_data	*pd;
109c8f0b869SBen Hutchings 
110c8f0b869SBen Hutchings 	/*
111c8f0b869SBen Hutchings 	 * The used switch driver.
112c8f0b869SBen Hutchings 	 */
113c8f0b869SBen Hutchings 	struct dsa_switch_driver	*drv;
114c8f0b869SBen Hutchings 
115c8f0b869SBen Hutchings 	/*
116c8f0b869SBen Hutchings 	 * Reference to mii bus to use.
117c8f0b869SBen Hutchings 	 */
118c8f0b869SBen Hutchings 	struct mii_bus		*master_mii_bus;
119c8f0b869SBen Hutchings 
120c8f0b869SBen Hutchings 	/*
121c8f0b869SBen Hutchings 	 * Slave mii_bus and devices for the individual ports.
122c8f0b869SBen Hutchings 	 */
123c8f0b869SBen Hutchings 	u32			dsa_port_mask;
124c8f0b869SBen Hutchings 	u32			phys_port_mask;
125c8f0b869SBen Hutchings 	struct mii_bus		*slave_mii_bus;
126c8f0b869SBen Hutchings 	struct net_device	*ports[DSA_MAX_PORTS];
127c8f0b869SBen Hutchings };
128c8f0b869SBen Hutchings 
129c8f0b869SBen Hutchings static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
130c8f0b869SBen Hutchings {
131c8f0b869SBen Hutchings 	return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port);
132c8f0b869SBen Hutchings }
133c8f0b869SBen Hutchings 
134c8f0b869SBen Hutchings static inline u8 dsa_upstream_port(struct dsa_switch *ds)
135c8f0b869SBen Hutchings {
136c8f0b869SBen Hutchings 	struct dsa_switch_tree *dst = ds->dst;
137c8f0b869SBen Hutchings 
138c8f0b869SBen Hutchings 	/*
139c8f0b869SBen Hutchings 	 * If this is the root switch (i.e. the switch that connects
140c8f0b869SBen Hutchings 	 * to the CPU), return the cpu port number on this switch.
141c8f0b869SBen Hutchings 	 * Else return the (DSA) port number that connects to the
142c8f0b869SBen Hutchings 	 * switch that is one hop closer to the cpu.
143c8f0b869SBen Hutchings 	 */
144c8f0b869SBen Hutchings 	if (dst->cpu_switch == ds->index)
145c8f0b869SBen Hutchings 		return dst->cpu_port;
146c8f0b869SBen Hutchings 	else
147c8f0b869SBen Hutchings 		return ds->pd->rtable[dst->cpu_switch];
148c8f0b869SBen Hutchings }
149c8f0b869SBen Hutchings 
150c8f0b869SBen Hutchings struct dsa_switch_driver {
151c8f0b869SBen Hutchings 	struct list_head	list;
152c8f0b869SBen Hutchings 
153c8f0b869SBen Hutchings 	__be16			tag_protocol;
154c8f0b869SBen Hutchings 	int			priv_size;
155c8f0b869SBen Hutchings 
156c8f0b869SBen Hutchings 	/*
157c8f0b869SBen Hutchings 	 * Probing and setup.
158c8f0b869SBen Hutchings 	 */
159c8f0b869SBen Hutchings 	char	*(*probe)(struct mii_bus *bus, int sw_addr);
160c8f0b869SBen Hutchings 	int	(*setup)(struct dsa_switch *ds);
161c8f0b869SBen Hutchings 	int	(*set_addr)(struct dsa_switch *ds, u8 *addr);
162c8f0b869SBen Hutchings 
163c8f0b869SBen Hutchings 	/*
164c8f0b869SBen Hutchings 	 * Access to the switch's PHY registers.
165c8f0b869SBen Hutchings 	 */
166c8f0b869SBen Hutchings 	int	(*phy_read)(struct dsa_switch *ds, int port, int regnum);
167c8f0b869SBen Hutchings 	int	(*phy_write)(struct dsa_switch *ds, int port,
168c8f0b869SBen Hutchings 			     int regnum, u16 val);
169c8f0b869SBen Hutchings 
170c8f0b869SBen Hutchings 	/*
171c8f0b869SBen Hutchings 	 * Link state polling and IRQ handling.
172c8f0b869SBen Hutchings 	 */
173c8f0b869SBen Hutchings 	void	(*poll_link)(struct dsa_switch *ds);
174c8f0b869SBen Hutchings 
175c8f0b869SBen Hutchings 	/*
176c8f0b869SBen Hutchings 	 * ethtool hardware statistics.
177c8f0b869SBen Hutchings 	 */
178c8f0b869SBen Hutchings 	void	(*get_strings)(struct dsa_switch *ds, int port, uint8_t *data);
179c8f0b869SBen Hutchings 	void	(*get_ethtool_stats)(struct dsa_switch *ds,
180c8f0b869SBen Hutchings 				     int port, uint64_t *data);
181c8f0b869SBen Hutchings 	int	(*get_sset_count)(struct dsa_switch *ds);
182c8f0b869SBen Hutchings };
183c8f0b869SBen Hutchings 
184c8f0b869SBen Hutchings void register_switch_driver(struct dsa_switch_driver *type);
185c8f0b869SBen Hutchings void unregister_switch_driver(struct dsa_switch_driver *type);
186c8f0b869SBen Hutchings 
1877fa857edSFlorian Fainelli static inline void *ds_to_priv(struct dsa_switch *ds)
1887fa857edSFlorian Fainelli {
1897fa857edSFlorian Fainelli 	return (void *)(ds + 1);
1907fa857edSFlorian Fainelli }
1917fa857edSFlorian Fainelli 
19291da11f8SLennert Buytenhek #endif
193