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> 19ec9436baSFlorian Fainelli #include <linux/phy.h> 20ce31b31cSFlorian Fainelli #include <linux/phy_fixed.h> 21cf50dcc2SBen Hutchings 22ac7a04c3SFlorian Fainelli enum dsa_tag_protocol { 23ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_NONE = 0, 24ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_DSA, 25ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_TRAILER, 26ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_EDSA, 27ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_BRCM, 28ac7a04c3SFlorian Fainelli }; 295037d532SFlorian Fainelli 30e84665c9SLennert Buytenhek #define DSA_MAX_SWITCHES 4 3191da11f8SLennert Buytenhek #define DSA_MAX_PORTS 12 3291da11f8SLennert Buytenhek 33e84665c9SLennert Buytenhek struct dsa_chip_data { 34e84665c9SLennert Buytenhek /* 35e84665c9SLennert Buytenhek * How to access the switch configuration registers. 36e84665c9SLennert Buytenhek */ 37e84665c9SLennert Buytenhek struct device *mii_bus; 38e84665c9SLennert Buytenhek int sw_addr; 39e84665c9SLennert Buytenhek 40fa981d9aSFlorian Fainelli /* Device tree node pointer for this specific switch chip 41fa981d9aSFlorian Fainelli * used during switch setup in case additional properties 42fa981d9aSFlorian Fainelli * and resources needs to be used 43fa981d9aSFlorian Fainelli */ 44fa981d9aSFlorian Fainelli struct device_node *of_node; 45fa981d9aSFlorian Fainelli 46e84665c9SLennert Buytenhek /* 47e84665c9SLennert Buytenhek * The names of the switch's ports. Use "cpu" to 48e84665c9SLennert Buytenhek * designate the switch port that the cpu is connected to, 49e84665c9SLennert Buytenhek * "dsa" to indicate that this port is a DSA link to 50e84665c9SLennert Buytenhek * another switch, NULL to indicate the port is unused, 51e84665c9SLennert Buytenhek * or any other string to indicate this is a physical port. 52e84665c9SLennert Buytenhek */ 53e84665c9SLennert Buytenhek char *port_names[DSA_MAX_PORTS]; 54bd47497aSFlorian Fainelli struct device_node *port_dn[DSA_MAX_PORTS]; 55e84665c9SLennert Buytenhek 56e84665c9SLennert Buytenhek /* 57e84665c9SLennert Buytenhek * An array (with nr_chips elements) of which element [a] 58e84665c9SLennert Buytenhek * indicates which port on this switch should be used to 59e84665c9SLennert Buytenhek * send packets to that are destined for switch a. Can be 60e84665c9SLennert Buytenhek * NULL if there is only one switch chip. 61e84665c9SLennert Buytenhek */ 62e84665c9SLennert Buytenhek s8 *rtable; 63e84665c9SLennert Buytenhek }; 64e84665c9SLennert Buytenhek 6591da11f8SLennert Buytenhek struct dsa_platform_data { 6691da11f8SLennert Buytenhek /* 6791da11f8SLennert Buytenhek * Reference to a Linux network interface that connects 68e84665c9SLennert Buytenhek * to the root switch chip of the tree. 6991da11f8SLennert Buytenhek */ 7091da11f8SLennert Buytenhek struct device *netdev; 7191da11f8SLennert Buytenhek 7291da11f8SLennert Buytenhek /* 73e84665c9SLennert Buytenhek * Info structs describing each of the switch chips 74e84665c9SLennert Buytenhek * connected via this network interface. 7591da11f8SLennert Buytenhek */ 76e84665c9SLennert Buytenhek int nr_chips; 77e84665c9SLennert Buytenhek struct dsa_chip_data *chip; 7891da11f8SLennert Buytenhek }; 7991da11f8SLennert Buytenhek 80*5075314eSAlexander Duyck struct packet_type; 813e8a72d1SFlorian Fainelli 82cf50dcc2SBen Hutchings struct dsa_switch_tree { 83cf50dcc2SBen Hutchings /* 84cf50dcc2SBen Hutchings * Configuration data for the platform device that owns 85cf50dcc2SBen Hutchings * this dsa switch tree instance. 86cf50dcc2SBen Hutchings */ 87cf50dcc2SBen Hutchings struct dsa_platform_data *pd; 88cf85d08fSLennert Buytenhek 89cf50dcc2SBen Hutchings /* 90cf50dcc2SBen Hutchings * Reference to network device to use, and which tagging 91cf50dcc2SBen Hutchings * protocol to use. 92cf50dcc2SBen Hutchings */ 93cf50dcc2SBen Hutchings struct net_device *master_netdev; 94*5075314eSAlexander Duyck int (*rcv)(struct sk_buff *skb, 95*5075314eSAlexander Duyck struct net_device *dev, 96*5075314eSAlexander Duyck struct packet_type *pt, 97*5075314eSAlexander Duyck struct net_device *orig_dev); 98ac7a04c3SFlorian Fainelli enum dsa_tag_protocol tag_protocol; 99cf50dcc2SBen Hutchings 100cf50dcc2SBen Hutchings /* 101cf50dcc2SBen Hutchings * The switch and port to which the CPU is attached. 102cf50dcc2SBen Hutchings */ 103cf50dcc2SBen Hutchings s8 cpu_switch; 104cf50dcc2SBen Hutchings s8 cpu_port; 105cf50dcc2SBen Hutchings 106cf50dcc2SBen Hutchings /* 107cf50dcc2SBen Hutchings * Link state polling. 108cf50dcc2SBen Hutchings */ 109cf50dcc2SBen Hutchings int link_poll_needed; 110cf50dcc2SBen Hutchings struct work_struct link_poll_work; 111cf50dcc2SBen Hutchings struct timer_list link_poll_timer; 112cf50dcc2SBen Hutchings 113cf50dcc2SBen Hutchings /* 114cf50dcc2SBen Hutchings * Data for the individual switch chips. 115cf50dcc2SBen Hutchings */ 116cf50dcc2SBen Hutchings struct dsa_switch *ds[DSA_MAX_SWITCHES]; 117cf50dcc2SBen Hutchings }; 118cf50dcc2SBen Hutchings 119c8f0b869SBen Hutchings struct dsa_switch { 120c8f0b869SBen Hutchings /* 121c8f0b869SBen Hutchings * Parent switch tree, and switch index. 122c8f0b869SBen Hutchings */ 123c8f0b869SBen Hutchings struct dsa_switch_tree *dst; 124c8f0b869SBen Hutchings int index; 125c8f0b869SBen Hutchings 126c8f0b869SBen Hutchings /* 127c8f0b869SBen Hutchings * Configuration data for this switch. 128c8f0b869SBen Hutchings */ 129c8f0b869SBen Hutchings struct dsa_chip_data *pd; 130c8f0b869SBen Hutchings 131c8f0b869SBen Hutchings /* 132c8f0b869SBen Hutchings * The used switch driver. 133c8f0b869SBen Hutchings */ 134c8f0b869SBen Hutchings struct dsa_switch_driver *drv; 135c8f0b869SBen Hutchings 136c8f0b869SBen Hutchings /* 137c8f0b869SBen Hutchings * Reference to mii bus to use. 138c8f0b869SBen Hutchings */ 139c8f0b869SBen Hutchings struct mii_bus *master_mii_bus; 140c8f0b869SBen Hutchings 141c8f0b869SBen Hutchings /* 142c8f0b869SBen Hutchings * Slave mii_bus and devices for the individual ports. 143c8f0b869SBen Hutchings */ 144c8f0b869SBen Hutchings u32 dsa_port_mask; 145c8f0b869SBen Hutchings u32 phys_port_mask; 1460d8bcdd3SFlorian Fainelli u32 phys_mii_mask; 147c8f0b869SBen Hutchings struct mii_bus *slave_mii_bus; 148c8f0b869SBen Hutchings struct net_device *ports[DSA_MAX_PORTS]; 149c8f0b869SBen Hutchings }; 150c8f0b869SBen Hutchings 151c8f0b869SBen Hutchings static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p) 152c8f0b869SBen Hutchings { 153c8f0b869SBen Hutchings return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port); 154c8f0b869SBen Hutchings } 155c8f0b869SBen Hutchings 156c8f0b869SBen Hutchings static inline u8 dsa_upstream_port(struct dsa_switch *ds) 157c8f0b869SBen Hutchings { 158c8f0b869SBen Hutchings struct dsa_switch_tree *dst = ds->dst; 159c8f0b869SBen Hutchings 160c8f0b869SBen Hutchings /* 161c8f0b869SBen Hutchings * If this is the root switch (i.e. the switch that connects 162c8f0b869SBen Hutchings * to the CPU), return the cpu port number on this switch. 163c8f0b869SBen Hutchings * Else return the (DSA) port number that connects to the 164c8f0b869SBen Hutchings * switch that is one hop closer to the cpu. 165c8f0b869SBen Hutchings */ 166c8f0b869SBen Hutchings if (dst->cpu_switch == ds->index) 167c8f0b869SBen Hutchings return dst->cpu_port; 168c8f0b869SBen Hutchings else 169c8f0b869SBen Hutchings return ds->pd->rtable[dst->cpu_switch]; 170c8f0b869SBen Hutchings } 171c8f0b869SBen Hutchings 172c8f0b869SBen Hutchings struct dsa_switch_driver { 173c8f0b869SBen Hutchings struct list_head list; 174c8f0b869SBen Hutchings 175ac7a04c3SFlorian Fainelli enum dsa_tag_protocol tag_protocol; 176c8f0b869SBen Hutchings int priv_size; 177c8f0b869SBen Hutchings 178c8f0b869SBen Hutchings /* 179c8f0b869SBen Hutchings * Probing and setup. 180c8f0b869SBen Hutchings */ 181c8f0b869SBen Hutchings char *(*probe)(struct mii_bus *bus, int sw_addr); 182c8f0b869SBen Hutchings int (*setup)(struct dsa_switch *ds); 183c8f0b869SBen Hutchings int (*set_addr)(struct dsa_switch *ds, u8 *addr); 184c8f0b869SBen Hutchings 185c8f0b869SBen Hutchings /* 186c8f0b869SBen Hutchings * Access to the switch's PHY registers. 187c8f0b869SBen Hutchings */ 188c8f0b869SBen Hutchings int (*phy_read)(struct dsa_switch *ds, int port, int regnum); 189c8f0b869SBen Hutchings int (*phy_write)(struct dsa_switch *ds, int port, 190c8f0b869SBen Hutchings int regnum, u16 val); 191c8f0b869SBen Hutchings 192c8f0b869SBen Hutchings /* 193c8f0b869SBen Hutchings * Link state polling and IRQ handling. 194c8f0b869SBen Hutchings */ 195c8f0b869SBen Hutchings void (*poll_link)(struct dsa_switch *ds); 196c8f0b869SBen Hutchings 197c8f0b869SBen Hutchings /* 198ec9436baSFlorian Fainelli * Link state adjustment (called from libphy) 199ec9436baSFlorian Fainelli */ 200ec9436baSFlorian Fainelli void (*adjust_link)(struct dsa_switch *ds, int port, 201ec9436baSFlorian Fainelli struct phy_device *phydev); 202ce31b31cSFlorian Fainelli void (*fixed_link_update)(struct dsa_switch *ds, int port, 203ce31b31cSFlorian Fainelli struct fixed_phy_status *st); 204ec9436baSFlorian Fainelli 205ec9436baSFlorian Fainelli /* 206c8f0b869SBen Hutchings * ethtool hardware statistics. 207c8f0b869SBen Hutchings */ 208c8f0b869SBen Hutchings void (*get_strings)(struct dsa_switch *ds, int port, uint8_t *data); 209c8f0b869SBen Hutchings void (*get_ethtool_stats)(struct dsa_switch *ds, 210c8f0b869SBen Hutchings int port, uint64_t *data); 211c8f0b869SBen Hutchings int (*get_sset_count)(struct dsa_switch *ds); 212c8f0b869SBen Hutchings }; 213c8f0b869SBen Hutchings 214c8f0b869SBen Hutchings void register_switch_driver(struct dsa_switch_driver *type); 215c8f0b869SBen Hutchings void unregister_switch_driver(struct dsa_switch_driver *type); 216c8f0b869SBen Hutchings 2177fa857edSFlorian Fainelli static inline void *ds_to_priv(struct dsa_switch *ds) 2187fa857edSFlorian Fainelli { 2197fa857edSFlorian Fainelli return (void *)(ds + 1); 2207fa857edSFlorian Fainelli } 2217fa857edSFlorian Fainelli 2225aed85ceSFlorian Fainelli static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst) 2235aed85ceSFlorian Fainelli { 224*5075314eSAlexander Duyck return dst->rcv != NULL; 2255aed85ceSFlorian Fainelli } 22691da11f8SLennert Buytenhek #endif 227