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