xref: /openbmc/linux/include/net/dsa.h (revision 7fa857ed)
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 
62cf50dcc2SBen Hutchings struct dsa_switch_tree {
63cf50dcc2SBen Hutchings 	/*
64cf50dcc2SBen Hutchings 	 * Configuration data for the platform device that owns
65cf50dcc2SBen Hutchings 	 * this dsa switch tree instance.
66cf50dcc2SBen Hutchings 	 */
67cf50dcc2SBen Hutchings 	struct dsa_platform_data	*pd;
68cf85d08fSLennert Buytenhek 
69cf50dcc2SBen Hutchings 	/*
70cf50dcc2SBen Hutchings 	 * Reference to network device to use, and which tagging
71cf50dcc2SBen Hutchings 	 * protocol to use.
72cf50dcc2SBen Hutchings 	 */
73cf50dcc2SBen Hutchings 	struct net_device	*master_netdev;
74cf50dcc2SBen Hutchings 	__be16			tag_protocol;
75cf50dcc2SBen Hutchings 
76cf50dcc2SBen Hutchings 	/*
77cf50dcc2SBen Hutchings 	 * The switch and port to which the CPU is attached.
78cf50dcc2SBen Hutchings 	 */
79cf50dcc2SBen Hutchings 	s8			cpu_switch;
80cf50dcc2SBen Hutchings 	s8			cpu_port;
81cf50dcc2SBen Hutchings 
82cf50dcc2SBen Hutchings 	/*
83cf50dcc2SBen Hutchings 	 * Link state polling.
84cf50dcc2SBen Hutchings 	 */
85cf50dcc2SBen Hutchings 	int			link_poll_needed;
86cf50dcc2SBen Hutchings 	struct work_struct	link_poll_work;
87cf50dcc2SBen Hutchings 	struct timer_list	link_poll_timer;
88cf50dcc2SBen Hutchings 
89cf50dcc2SBen Hutchings 	/*
90cf50dcc2SBen Hutchings 	 * Data for the individual switch chips.
91cf50dcc2SBen Hutchings 	 */
92cf50dcc2SBen Hutchings 	struct dsa_switch	*ds[DSA_MAX_SWITCHES];
93cf50dcc2SBen Hutchings };
94cf50dcc2SBen Hutchings 
95c8f0b869SBen Hutchings struct dsa_switch {
96c8f0b869SBen Hutchings 	/*
97c8f0b869SBen Hutchings 	 * Parent switch tree, and switch index.
98c8f0b869SBen Hutchings 	 */
99c8f0b869SBen Hutchings 	struct dsa_switch_tree	*dst;
100c8f0b869SBen Hutchings 	int			index;
101c8f0b869SBen Hutchings 
102c8f0b869SBen Hutchings 	/*
103c8f0b869SBen Hutchings 	 * Configuration data for this switch.
104c8f0b869SBen Hutchings 	 */
105c8f0b869SBen Hutchings 	struct dsa_chip_data	*pd;
106c8f0b869SBen Hutchings 
107c8f0b869SBen Hutchings 	/*
108c8f0b869SBen Hutchings 	 * The used switch driver.
109c8f0b869SBen Hutchings 	 */
110c8f0b869SBen Hutchings 	struct dsa_switch_driver	*drv;
111c8f0b869SBen Hutchings 
112c8f0b869SBen Hutchings 	/*
113c8f0b869SBen Hutchings 	 * Reference to mii bus to use.
114c8f0b869SBen Hutchings 	 */
115c8f0b869SBen Hutchings 	struct mii_bus		*master_mii_bus;
116c8f0b869SBen Hutchings 
117c8f0b869SBen Hutchings 	/*
118c8f0b869SBen Hutchings 	 * Slave mii_bus and devices for the individual ports.
119c8f0b869SBen Hutchings 	 */
120c8f0b869SBen Hutchings 	u32			dsa_port_mask;
121c8f0b869SBen Hutchings 	u32			phys_port_mask;
122c8f0b869SBen Hutchings 	struct mii_bus		*slave_mii_bus;
123c8f0b869SBen Hutchings 	struct net_device	*ports[DSA_MAX_PORTS];
124c8f0b869SBen Hutchings };
125c8f0b869SBen Hutchings 
126c8f0b869SBen Hutchings static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
127c8f0b869SBen Hutchings {
128c8f0b869SBen Hutchings 	return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port);
129c8f0b869SBen Hutchings }
130c8f0b869SBen Hutchings 
131c8f0b869SBen Hutchings static inline u8 dsa_upstream_port(struct dsa_switch *ds)
132c8f0b869SBen Hutchings {
133c8f0b869SBen Hutchings 	struct dsa_switch_tree *dst = ds->dst;
134c8f0b869SBen Hutchings 
135c8f0b869SBen Hutchings 	/*
136c8f0b869SBen Hutchings 	 * If this is the root switch (i.e. the switch that connects
137c8f0b869SBen Hutchings 	 * to the CPU), return the cpu port number on this switch.
138c8f0b869SBen Hutchings 	 * Else return the (DSA) port number that connects to the
139c8f0b869SBen Hutchings 	 * switch that is one hop closer to the cpu.
140c8f0b869SBen Hutchings 	 */
141c8f0b869SBen Hutchings 	if (dst->cpu_switch == ds->index)
142c8f0b869SBen Hutchings 		return dst->cpu_port;
143c8f0b869SBen Hutchings 	else
144c8f0b869SBen Hutchings 		return ds->pd->rtable[dst->cpu_switch];
145c8f0b869SBen Hutchings }
146c8f0b869SBen Hutchings 
147c8f0b869SBen Hutchings struct dsa_switch_driver {
148c8f0b869SBen Hutchings 	struct list_head	list;
149c8f0b869SBen Hutchings 
150c8f0b869SBen Hutchings 	__be16			tag_protocol;
151c8f0b869SBen Hutchings 	int			priv_size;
152c8f0b869SBen Hutchings 
153c8f0b869SBen Hutchings 	/*
154c8f0b869SBen Hutchings 	 * Probing and setup.
155c8f0b869SBen Hutchings 	 */
156c8f0b869SBen Hutchings 	char	*(*probe)(struct mii_bus *bus, int sw_addr);
157c8f0b869SBen Hutchings 	int	(*setup)(struct dsa_switch *ds);
158c8f0b869SBen Hutchings 	int	(*set_addr)(struct dsa_switch *ds, u8 *addr);
159c8f0b869SBen Hutchings 
160c8f0b869SBen Hutchings 	/*
161c8f0b869SBen Hutchings 	 * Access to the switch's PHY registers.
162c8f0b869SBen Hutchings 	 */
163c8f0b869SBen Hutchings 	int	(*phy_read)(struct dsa_switch *ds, int port, int regnum);
164c8f0b869SBen Hutchings 	int	(*phy_write)(struct dsa_switch *ds, int port,
165c8f0b869SBen Hutchings 			     int regnum, u16 val);
166c8f0b869SBen Hutchings 
167c8f0b869SBen Hutchings 	/*
168c8f0b869SBen Hutchings 	 * Link state polling and IRQ handling.
169c8f0b869SBen Hutchings 	 */
170c8f0b869SBen Hutchings 	void	(*poll_link)(struct dsa_switch *ds);
171c8f0b869SBen Hutchings 
172c8f0b869SBen Hutchings 	/*
173c8f0b869SBen Hutchings 	 * ethtool hardware statistics.
174c8f0b869SBen Hutchings 	 */
175c8f0b869SBen Hutchings 	void	(*get_strings)(struct dsa_switch *ds, int port, uint8_t *data);
176c8f0b869SBen Hutchings 	void	(*get_ethtool_stats)(struct dsa_switch *ds,
177c8f0b869SBen Hutchings 				     int port, uint64_t *data);
178c8f0b869SBen Hutchings 	int	(*get_sset_count)(struct dsa_switch *ds);
179c8f0b869SBen Hutchings };
180c8f0b869SBen Hutchings 
181c8f0b869SBen Hutchings void register_switch_driver(struct dsa_switch_driver *type);
182c8f0b869SBen Hutchings void unregister_switch_driver(struct dsa_switch_driver *type);
183c8f0b869SBen Hutchings 
1847fa857edSFlorian Fainelli static inline void *ds_to_priv(struct dsa_switch *ds)
1857fa857edSFlorian Fainelli {
1867fa857edSFlorian Fainelli 	return (void *)(ds + 1);
1877fa857edSFlorian Fainelli }
1887fa857edSFlorian Fainelli 
189cf50dcc2SBen Hutchings /*
190cf50dcc2SBen Hutchings  * The original DSA tag format and some other tag formats have no
191cf50dcc2SBen Hutchings  * ethertype, which means that we need to add a little hack to the
192cf50dcc2SBen Hutchings  * networking receive path to make sure that received frames get
193cf50dcc2SBen Hutchings  * the right ->protocol assigned to them when one of those tag
194cf50dcc2SBen Hutchings  * formats is in use.
195cf50dcc2SBen Hutchings  */
196cf50dcc2SBen Hutchings static inline bool dsa_uses_dsa_tags(struct dsa_switch_tree *dst)
197cf50dcc2SBen Hutchings {
198cf50dcc2SBen Hutchings 	return !!(dst->tag_protocol == htons(ETH_P_DSA));
199cf50dcc2SBen Hutchings }
200cf50dcc2SBen Hutchings 
201cf50dcc2SBen Hutchings static inline bool dsa_uses_trailer_tags(struct dsa_switch_tree *dst)
202cf50dcc2SBen Hutchings {
203cf50dcc2SBen Hutchings 	return !!(dst->tag_protocol == htons(ETH_P_TRAILER));
204cf50dcc2SBen Hutchings }
20591da11f8SLennert Buytenhek 
20691da11f8SLennert Buytenhek #endif
207