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> 16f515f192SVivien Didelot #include <linux/notifier.h> 17cf50dcc2SBen Hutchings #include <linux/timer.h> 18cf50dcc2SBen Hutchings #include <linux/workqueue.h> 19fa981d9aSFlorian Fainelli #include <linux/of.h> 20ec9436baSFlorian Fainelli #include <linux/phy.h> 21ce31b31cSFlorian Fainelli #include <linux/phy_fixed.h> 22a2820543SFlorian Fainelli #include <linux/ethtool.h> 23cf50dcc2SBen Hutchings 24f50f2127SFlorian Fainelli struct tc_action; 25f50f2127SFlorian Fainelli 26ac7a04c3SFlorian Fainelli enum dsa_tag_protocol { 27ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_NONE = 0, 28ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_DSA, 29ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_TRAILER, 30ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_EDSA, 31ac7a04c3SFlorian Fainelli DSA_TAG_PROTO_BRCM, 32cafdc45cSJohn Crispin DSA_TAG_PROTO_QCA, 3339a7f2a4SAndrew Lunn DSA_TAG_LAST, /* MUST BE LAST */ 34ac7a04c3SFlorian Fainelli }; 355037d532SFlorian Fainelli 36e84665c9SLennert Buytenhek #define DSA_MAX_SWITCHES 4 3791da11f8SLennert Buytenhek #define DSA_MAX_PORTS 12 3891da11f8SLennert Buytenhek 39d390238cSVivien Didelot #define DSA_RTABLE_NONE -1 40d390238cSVivien Didelot 41e84665c9SLennert Buytenhek struct dsa_chip_data { 42e84665c9SLennert Buytenhek /* 43e84665c9SLennert Buytenhek * How to access the switch configuration registers. 44e84665c9SLennert Buytenhek */ 45b4d2394dSAlexander Duyck struct device *host_dev; 46e84665c9SLennert Buytenhek int sw_addr; 47e84665c9SLennert Buytenhek 486793abb4SGuenter Roeck /* set to size of eeprom if supported by the switch */ 496793abb4SGuenter Roeck int eeprom_len; 506793abb4SGuenter Roeck 51fa981d9aSFlorian Fainelli /* Device tree node pointer for this specific switch chip 52fa981d9aSFlorian Fainelli * used during switch setup in case additional properties 53fa981d9aSFlorian Fainelli * and resources needs to be used 54fa981d9aSFlorian Fainelli */ 55fa981d9aSFlorian Fainelli struct device_node *of_node; 56fa981d9aSFlorian Fainelli 57e84665c9SLennert Buytenhek /* 58e84665c9SLennert Buytenhek * The names of the switch's ports. Use "cpu" to 59e84665c9SLennert Buytenhek * designate the switch port that the cpu is connected to, 60e84665c9SLennert Buytenhek * "dsa" to indicate that this port is a DSA link to 61e84665c9SLennert Buytenhek * another switch, NULL to indicate the port is unused, 62e84665c9SLennert Buytenhek * or any other string to indicate this is a physical port. 63e84665c9SLennert Buytenhek */ 64e84665c9SLennert Buytenhek char *port_names[DSA_MAX_PORTS]; 65bd47497aSFlorian Fainelli struct device_node *port_dn[DSA_MAX_PORTS]; 66e84665c9SLennert Buytenhek 67e84665c9SLennert Buytenhek /* 684a7704ffSAndrew Lunn * An array of which element [a] indicates which port on this 694a7704ffSAndrew Lunn * switch should be used to send packets to that are destined 704a7704ffSAndrew Lunn * for switch a. Can be NULL if there is only one switch chip. 71e84665c9SLennert Buytenhek */ 724a7704ffSAndrew Lunn s8 rtable[DSA_MAX_SWITCHES]; 73e84665c9SLennert Buytenhek }; 74e84665c9SLennert Buytenhek 7591da11f8SLennert Buytenhek struct dsa_platform_data { 7691da11f8SLennert Buytenhek /* 7791da11f8SLennert Buytenhek * Reference to a Linux network interface that connects 78e84665c9SLennert Buytenhek * to the root switch chip of the tree. 7991da11f8SLennert Buytenhek */ 8091da11f8SLennert Buytenhek struct device *netdev; 81769a0202SFlorian Fainelli struct net_device *of_netdev; 8291da11f8SLennert Buytenhek 8391da11f8SLennert Buytenhek /* 84e84665c9SLennert Buytenhek * Info structs describing each of the switch chips 85e84665c9SLennert Buytenhek * connected via this network interface. 8691da11f8SLennert Buytenhek */ 87e84665c9SLennert Buytenhek int nr_chips; 88e84665c9SLennert Buytenhek struct dsa_chip_data *chip; 8991da11f8SLennert Buytenhek }; 9091da11f8SLennert Buytenhek 915075314eSAlexander Duyck struct packet_type; 923e8a72d1SFlorian Fainelli 93cf50dcc2SBen Hutchings struct dsa_switch_tree { 9483c0afaeSAndrew Lunn struct list_head list; 9583c0afaeSAndrew Lunn 96f515f192SVivien Didelot /* Notifier chain for switch-wide events */ 97f515f192SVivien Didelot struct raw_notifier_head nh; 98f515f192SVivien Didelot 9983c0afaeSAndrew Lunn /* Tree identifier */ 10083c0afaeSAndrew Lunn u32 tree; 10183c0afaeSAndrew Lunn 10283c0afaeSAndrew Lunn /* Number of switches attached to this tree */ 10383c0afaeSAndrew Lunn struct kref refcount; 10483c0afaeSAndrew Lunn 10583c0afaeSAndrew Lunn /* Has this tree been applied to the hardware? */ 10683c0afaeSAndrew Lunn bool applied; 10783c0afaeSAndrew Lunn 108cf50dcc2SBen Hutchings /* 109cf50dcc2SBen Hutchings * Configuration data for the platform device that owns 110cf50dcc2SBen Hutchings * this dsa switch tree instance. 111cf50dcc2SBen Hutchings */ 112cf50dcc2SBen Hutchings struct dsa_platform_data *pd; 113cf85d08fSLennert Buytenhek 114cf50dcc2SBen Hutchings /* 115cf50dcc2SBen Hutchings * Reference to network device to use, and which tagging 116cf50dcc2SBen Hutchings * protocol to use. 117cf50dcc2SBen Hutchings */ 118cf50dcc2SBen Hutchings struct net_device *master_netdev; 1195075314eSAlexander Duyck int (*rcv)(struct sk_buff *skb, 1205075314eSAlexander Duyck struct net_device *dev, 1215075314eSAlexander Duyck struct packet_type *pt, 1225075314eSAlexander Duyck struct net_device *orig_dev); 123cf50dcc2SBen Hutchings 124cf50dcc2SBen Hutchings /* 125badf3adaSFlorian Fainelli * Original copy of the master netdev ethtool_ops 126badf3adaSFlorian Fainelli */ 127badf3adaSFlorian Fainelli struct ethtool_ops master_ethtool_ops; 1280c73c523SFlorian Fainelli const struct ethtool_ops *master_orig_ethtool_ops; 129badf3adaSFlorian Fainelli 130badf3adaSFlorian Fainelli /* 131cf50dcc2SBen Hutchings * The switch and port to which the CPU is attached. 132cf50dcc2SBen Hutchings */ 133b22de490SVivien Didelot struct dsa_switch *cpu_switch; 134cf50dcc2SBen Hutchings s8 cpu_port; 135cf50dcc2SBen Hutchings 136cf50dcc2SBen Hutchings /* 137cf50dcc2SBen Hutchings * Data for the individual switch chips. 138cf50dcc2SBen Hutchings */ 139cf50dcc2SBen Hutchings struct dsa_switch *ds[DSA_MAX_SWITCHES]; 14039a7f2a4SAndrew Lunn 14139a7f2a4SAndrew Lunn /* 14239a7f2a4SAndrew Lunn * Tagging protocol operations for adding and removing an 14339a7f2a4SAndrew Lunn * encapsulation tag. 14439a7f2a4SAndrew Lunn */ 14539a7f2a4SAndrew Lunn const struct dsa_device_ops *tag_ops; 146cf50dcc2SBen Hutchings }; 147cf50dcc2SBen Hutchings 148f50f2127SFlorian Fainelli /* TC matchall action types, only mirroring for now */ 149f50f2127SFlorian Fainelli enum dsa_port_mall_action_type { 150f50f2127SFlorian Fainelli DSA_PORT_MALL_MIRROR, 151f50f2127SFlorian Fainelli }; 152f50f2127SFlorian Fainelli 153f50f2127SFlorian Fainelli /* TC mirroring entry */ 154f50f2127SFlorian Fainelli struct dsa_mall_mirror_tc_entry { 155f50f2127SFlorian Fainelli u8 to_local_port; 156f50f2127SFlorian Fainelli bool ingress; 157f50f2127SFlorian Fainelli }; 158f50f2127SFlorian Fainelli 159f50f2127SFlorian Fainelli /* TC matchall entry */ 160f50f2127SFlorian Fainelli struct dsa_mall_tc_entry { 161f50f2127SFlorian Fainelli struct list_head list; 162f50f2127SFlorian Fainelli unsigned long cookie; 163f50f2127SFlorian Fainelli enum dsa_port_mall_action_type type; 164f50f2127SFlorian Fainelli union { 165f50f2127SFlorian Fainelli struct dsa_mall_mirror_tc_entry mirror; 166f50f2127SFlorian Fainelli }; 167f50f2127SFlorian Fainelli }; 168f50f2127SFlorian Fainelli 169f50f2127SFlorian Fainelli 170c8b09808SAndrew Lunn struct dsa_port { 171818be848SVivien Didelot struct dsa_switch *ds; 172818be848SVivien Didelot unsigned int index; 173c8b09808SAndrew Lunn struct net_device *netdev; 174189b0d93SAndrew Lunn struct device_node *dn; 17534a79f63SVivien Didelot unsigned int ageing_time; 176732f794cSVivien Didelot u8 stp_state; 177a5e9a02eSVivien Didelot struct net_device *bridge_dev; 178c8b09808SAndrew Lunn }; 179c8b09808SAndrew Lunn 180c8f0b869SBen Hutchings struct dsa_switch { 181c33063d6SAndrew Lunn struct device *dev; 182c33063d6SAndrew Lunn 183c8f0b869SBen Hutchings /* 184c8f0b869SBen Hutchings * Parent switch tree, and switch index. 185c8f0b869SBen Hutchings */ 186c8f0b869SBen Hutchings struct dsa_switch_tree *dst; 187c8f0b869SBen Hutchings int index; 188c8f0b869SBen Hutchings 189f515f192SVivien Didelot /* Listener for switch fabric events */ 190f515f192SVivien Didelot struct notifier_block nb; 191f515f192SVivien Didelot 192c8f0b869SBen Hutchings /* 1937543a6d5SAndrew Lunn * Give the switch driver somewhere to hang its private data 1947543a6d5SAndrew Lunn * structure. 1957543a6d5SAndrew Lunn */ 1967543a6d5SAndrew Lunn void *priv; 1977543a6d5SAndrew Lunn 1987543a6d5SAndrew Lunn /* 199c8f0b869SBen Hutchings * Configuration data for this switch. 200c8f0b869SBen Hutchings */ 201ff04955cSAndrew Lunn struct dsa_chip_data *cd; 202c8f0b869SBen Hutchings 203c8f0b869SBen Hutchings /* 2049d490b4eSVivien Didelot * The switch operations. 205c8f0b869SBen Hutchings */ 206a82f67afSFlorian Fainelli const struct dsa_switch_ops *ops; 207c8f0b869SBen Hutchings 20866472fc0SAndrew Lunn /* 20966472fc0SAndrew Lunn * An array of which element [a] indicates which port on this 21066472fc0SAndrew Lunn * switch should be used to send packets to that are destined 21166472fc0SAndrew Lunn * for switch a. Can be NULL if there is only one switch chip. 21266472fc0SAndrew Lunn */ 21366472fc0SAndrew Lunn s8 rtable[DSA_MAX_SWITCHES]; 21466472fc0SAndrew Lunn 215c8f0b869SBen Hutchings /* 21683c0afaeSAndrew Lunn * The lower device this switch uses to talk to the host 21783c0afaeSAndrew Lunn */ 21883c0afaeSAndrew Lunn struct net_device *master_netdev; 21983c0afaeSAndrew Lunn 22083c0afaeSAndrew Lunn /* 221c8f0b869SBen Hutchings * Slave mii_bus and devices for the individual ports. 222c8f0b869SBen Hutchings */ 223c8f0b869SBen Hutchings u32 dsa_port_mask; 22483c0afaeSAndrew Lunn u32 cpu_port_mask; 22574c3e2a5SAndrew Lunn u32 enabled_port_mask; 2260d8bcdd3SFlorian Fainelli u32 phys_mii_mask; 227c8f0b869SBen Hutchings struct mii_bus *slave_mii_bus; 228a0c02161SVivien Didelot 229a0c02161SVivien Didelot /* Dynamically allocated ports, keep last */ 230a0c02161SVivien Didelot size_t num_ports; 231a0c02161SVivien Didelot struct dsa_port ports[]; 232c8f0b869SBen Hutchings }; 233c8f0b869SBen Hutchings 234c8f0b869SBen Hutchings static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p) 235c8f0b869SBen Hutchings { 236b22de490SVivien Didelot return !!(ds == ds->dst->cpu_switch && p == ds->dst->cpu_port); 237c8f0b869SBen Hutchings } 238c8f0b869SBen Hutchings 23960045cbfSAndrew Lunn static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p) 24060045cbfSAndrew Lunn { 24160045cbfSAndrew Lunn return !!((ds->dsa_port_mask) & (1 << p)); 24260045cbfSAndrew Lunn } 24360045cbfSAndrew Lunn 244d79d2107SGuenter Roeck static inline bool dsa_is_port_initialized(struct dsa_switch *ds, int p) 245d79d2107SGuenter Roeck { 246c8b09808SAndrew Lunn return ds->enabled_port_mask & (1 << p) && ds->ports[p].netdev; 247d79d2107SGuenter Roeck } 248d79d2107SGuenter Roeck 249c8f0b869SBen Hutchings static inline u8 dsa_upstream_port(struct dsa_switch *ds) 250c8f0b869SBen Hutchings { 251c8f0b869SBen Hutchings struct dsa_switch_tree *dst = ds->dst; 252c8f0b869SBen Hutchings 253c8f0b869SBen Hutchings /* 254c8f0b869SBen Hutchings * If this is the root switch (i.e. the switch that connects 255c8f0b869SBen Hutchings * to the CPU), return the cpu port number on this switch. 256c8f0b869SBen Hutchings * Else return the (DSA) port number that connects to the 257c8f0b869SBen Hutchings * switch that is one hop closer to the cpu. 258c8f0b869SBen Hutchings */ 259b22de490SVivien Didelot if (dst->cpu_switch == ds) 260c8f0b869SBen Hutchings return dst->cpu_port; 261c8f0b869SBen Hutchings else 262b22de490SVivien Didelot return ds->rtable[dst->cpu_switch->index]; 263c8f0b869SBen Hutchings } 264c8f0b869SBen Hutchings 265146a3206SVivien Didelot struct switchdev_trans; 266ea70ba98SVivien Didelot struct switchdev_obj; 267146a3206SVivien Didelot struct switchdev_obj_port_fdb; 2688df30255SVivien Didelot struct switchdev_obj_port_mdb; 26976e398a6SVivien Didelot struct switchdev_obj_port_vlan; 270146a3206SVivien Didelot 27104d3a4c6SVivien Didelot #define DSA_NOTIFIER_BRIDGE_JOIN 1 27204d3a4c6SVivien Didelot #define DSA_NOTIFIER_BRIDGE_LEAVE 2 27304d3a4c6SVivien Didelot 27404d3a4c6SVivien Didelot /* DSA_NOTIFIER_BRIDGE_* */ 27504d3a4c6SVivien Didelot struct dsa_notifier_bridge_info { 27604d3a4c6SVivien Didelot struct net_device *br; 27704d3a4c6SVivien Didelot int sw_index; 27804d3a4c6SVivien Didelot int port; 27904d3a4c6SVivien Didelot }; 28004d3a4c6SVivien Didelot 2819d490b4eSVivien Didelot struct dsa_switch_ops { 282c8f0b869SBen Hutchings /* 283c8f0b869SBen Hutchings * Probing and setup. 284c8f0b869SBen Hutchings */ 2850209d144SVivien Didelot const char *(*probe)(struct device *dsa_dev, 2860209d144SVivien Didelot struct device *host_dev, int sw_addr, 2870209d144SVivien Didelot void **priv); 2887b314362SAndrew Lunn 2897b314362SAndrew Lunn enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds); 2907b314362SAndrew Lunn 291c8f0b869SBen Hutchings int (*setup)(struct dsa_switch *ds); 292c8f0b869SBen Hutchings int (*set_addr)(struct dsa_switch *ds, u8 *addr); 2936819563eSFlorian Fainelli u32 (*get_phy_flags)(struct dsa_switch *ds, int port); 294c8f0b869SBen Hutchings 295c8f0b869SBen Hutchings /* 296c8f0b869SBen Hutchings * Access to the switch's PHY registers. 297c8f0b869SBen Hutchings */ 298c8f0b869SBen Hutchings int (*phy_read)(struct dsa_switch *ds, int port, int regnum); 299c8f0b869SBen Hutchings int (*phy_write)(struct dsa_switch *ds, int port, 300c8f0b869SBen Hutchings int regnum, u16 val); 301c8f0b869SBen Hutchings 302c8f0b869SBen Hutchings /* 303ec9436baSFlorian Fainelli * Link state adjustment (called from libphy) 304ec9436baSFlorian Fainelli */ 305ec9436baSFlorian Fainelli void (*adjust_link)(struct dsa_switch *ds, int port, 306ec9436baSFlorian Fainelli struct phy_device *phydev); 307ce31b31cSFlorian Fainelli void (*fixed_link_update)(struct dsa_switch *ds, int port, 308ce31b31cSFlorian Fainelli struct fixed_phy_status *st); 309ec9436baSFlorian Fainelli 310ec9436baSFlorian Fainelli /* 311c8f0b869SBen Hutchings * ethtool hardware statistics. 312c8f0b869SBen Hutchings */ 313c8f0b869SBen Hutchings void (*get_strings)(struct dsa_switch *ds, int port, uint8_t *data); 314c8f0b869SBen Hutchings void (*get_ethtool_stats)(struct dsa_switch *ds, 315c8f0b869SBen Hutchings int port, uint64_t *data); 316c8f0b869SBen Hutchings int (*get_sset_count)(struct dsa_switch *ds); 31724462549SFlorian Fainelli 31824462549SFlorian Fainelli /* 31919e57c4eSFlorian Fainelli * ethtool Wake-on-LAN 32019e57c4eSFlorian Fainelli */ 32119e57c4eSFlorian Fainelli void (*get_wol)(struct dsa_switch *ds, int port, 32219e57c4eSFlorian Fainelli struct ethtool_wolinfo *w); 32319e57c4eSFlorian Fainelli int (*set_wol)(struct dsa_switch *ds, int port, 32419e57c4eSFlorian Fainelli struct ethtool_wolinfo *w); 32519e57c4eSFlorian Fainelli 32619e57c4eSFlorian Fainelli /* 32724462549SFlorian Fainelli * Suspend and resume 32824462549SFlorian Fainelli */ 32924462549SFlorian Fainelli int (*suspend)(struct dsa_switch *ds); 33024462549SFlorian Fainelli int (*resume)(struct dsa_switch *ds); 331b2f2af21SFlorian Fainelli 332b2f2af21SFlorian Fainelli /* 333b2f2af21SFlorian Fainelli * Port enable/disable 334b2f2af21SFlorian Fainelli */ 335b2f2af21SFlorian Fainelli int (*port_enable)(struct dsa_switch *ds, int port, 336b2f2af21SFlorian Fainelli struct phy_device *phy); 337b2f2af21SFlorian Fainelli void (*port_disable)(struct dsa_switch *ds, int port, 338b2f2af21SFlorian Fainelli struct phy_device *phy); 3397905288fSFlorian Fainelli 3407905288fSFlorian Fainelli /* 3417905288fSFlorian Fainelli * EEE setttings 3427905288fSFlorian Fainelli */ 3437905288fSFlorian Fainelli int (*set_eee)(struct dsa_switch *ds, int port, 3447905288fSFlorian Fainelli struct phy_device *phydev, 3457905288fSFlorian Fainelli struct ethtool_eee *e); 3467905288fSFlorian Fainelli int (*get_eee)(struct dsa_switch *ds, int port, 3477905288fSFlorian Fainelli struct ethtool_eee *e); 34851579c3fSGuenter Roeck 3496793abb4SGuenter Roeck /* EEPROM access */ 3506793abb4SGuenter Roeck int (*get_eeprom_len)(struct dsa_switch *ds); 3516793abb4SGuenter Roeck int (*get_eeprom)(struct dsa_switch *ds, 3526793abb4SGuenter Roeck struct ethtool_eeprom *eeprom, u8 *data); 3536793abb4SGuenter Roeck int (*set_eeprom)(struct dsa_switch *ds, 3546793abb4SGuenter Roeck struct ethtool_eeprom *eeprom, u8 *data); 3553d762a0fSGuenter Roeck 3563d762a0fSGuenter Roeck /* 3573d762a0fSGuenter Roeck * Register access. 3583d762a0fSGuenter Roeck */ 3593d762a0fSGuenter Roeck int (*get_regs_len)(struct dsa_switch *ds, int port); 3603d762a0fSGuenter Roeck void (*get_regs)(struct dsa_switch *ds, int port, 3613d762a0fSGuenter Roeck struct ethtool_regs *regs, void *p); 362b73adef6SFlorian Fainelli 363b73adef6SFlorian Fainelli /* 364b73adef6SFlorian Fainelli * Bridge integration 365b73adef6SFlorian Fainelli */ 36634a79f63SVivien Didelot int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs); 36771327a4eSVivien Didelot int (*port_bridge_join)(struct dsa_switch *ds, int port, 368a6692754SVivien Didelot struct net_device *bridge); 369f123f2fbSVivien Didelot void (*port_bridge_leave)(struct dsa_switch *ds, int port, 370f123f2fbSVivien Didelot struct net_device *bridge); 37143c44a9fSVivien Didelot void (*port_stp_state_set)(struct dsa_switch *ds, int port, 372b73adef6SFlorian Fainelli u8 state); 373732f794cSVivien Didelot void (*port_fast_age)(struct dsa_switch *ds, int port); 3742a778e1bSVivien Didelot 3752a778e1bSVivien Didelot /* 37611149536SVivien Didelot * VLAN support 37711149536SVivien Didelot */ 378fb2dabadSVivien Didelot int (*port_vlan_filtering)(struct dsa_switch *ds, int port, 379fb2dabadSVivien Didelot bool vlan_filtering); 38076e398a6SVivien Didelot int (*port_vlan_prepare)(struct dsa_switch *ds, int port, 38176e398a6SVivien Didelot const struct switchdev_obj_port_vlan *vlan, 38276e398a6SVivien Didelot struct switchdev_trans *trans); 3834d5770b3SVivien Didelot void (*port_vlan_add)(struct dsa_switch *ds, int port, 38476e398a6SVivien Didelot const struct switchdev_obj_port_vlan *vlan, 38576e398a6SVivien Didelot struct switchdev_trans *trans); 38676e398a6SVivien Didelot int (*port_vlan_del)(struct dsa_switch *ds, int port, 38776e398a6SVivien Didelot const struct switchdev_obj_port_vlan *vlan); 38865aebfc0SVivien Didelot int (*port_vlan_dump)(struct dsa_switch *ds, int port, 38965aebfc0SVivien Didelot struct switchdev_obj_port_vlan *vlan, 39065aebfc0SVivien Didelot int (*cb)(struct switchdev_obj *obj)); 39111149536SVivien Didelot 39211149536SVivien Didelot /* 3932a778e1bSVivien Didelot * Forwarding database 3942a778e1bSVivien Didelot */ 395146a3206SVivien Didelot int (*port_fdb_prepare)(struct dsa_switch *ds, int port, 396146a3206SVivien Didelot const struct switchdev_obj_port_fdb *fdb, 397146a3206SVivien Didelot struct switchdev_trans *trans); 3988497aa61SVivien Didelot void (*port_fdb_add)(struct dsa_switch *ds, int port, 3991f36faf2SVivien Didelot const struct switchdev_obj_port_fdb *fdb, 4001f36faf2SVivien Didelot struct switchdev_trans *trans); 4012a778e1bSVivien Didelot int (*port_fdb_del)(struct dsa_switch *ds, int port, 4028057b3e7SVivien Didelot const struct switchdev_obj_port_fdb *fdb); 403ea70ba98SVivien Didelot int (*port_fdb_dump)(struct dsa_switch *ds, int port, 404ea70ba98SVivien Didelot struct switchdev_obj_port_fdb *fdb, 405ea70ba98SVivien Didelot int (*cb)(struct switchdev_obj *obj)); 4068df30255SVivien Didelot 4078df30255SVivien Didelot /* 4088df30255SVivien Didelot * Multicast database 4098df30255SVivien Didelot */ 4108df30255SVivien Didelot int (*port_mdb_prepare)(struct dsa_switch *ds, int port, 4118df30255SVivien Didelot const struct switchdev_obj_port_mdb *mdb, 4128df30255SVivien Didelot struct switchdev_trans *trans); 4138df30255SVivien Didelot void (*port_mdb_add)(struct dsa_switch *ds, int port, 4148df30255SVivien Didelot const struct switchdev_obj_port_mdb *mdb, 4158df30255SVivien Didelot struct switchdev_trans *trans); 4168df30255SVivien Didelot int (*port_mdb_del)(struct dsa_switch *ds, int port, 4178df30255SVivien Didelot const struct switchdev_obj_port_mdb *mdb); 4188df30255SVivien Didelot int (*port_mdb_dump)(struct dsa_switch *ds, int port, 4198df30255SVivien Didelot struct switchdev_obj_port_mdb *mdb, 4208df30255SVivien Didelot int (*cb)(struct switchdev_obj *obj)); 421bf9f2648SFlorian Fainelli 422bf9f2648SFlorian Fainelli /* 423bf9f2648SFlorian Fainelli * RXNFC 424bf9f2648SFlorian Fainelli */ 425bf9f2648SFlorian Fainelli int (*get_rxnfc)(struct dsa_switch *ds, int port, 426bf9f2648SFlorian Fainelli struct ethtool_rxnfc *nfc, u32 *rule_locs); 427bf9f2648SFlorian Fainelli int (*set_rxnfc)(struct dsa_switch *ds, int port, 428bf9f2648SFlorian Fainelli struct ethtool_rxnfc *nfc); 429f50f2127SFlorian Fainelli 430f50f2127SFlorian Fainelli /* 431f50f2127SFlorian Fainelli * TC integration 432f50f2127SFlorian Fainelli */ 433f50f2127SFlorian Fainelli int (*port_mirror_add)(struct dsa_switch *ds, int port, 434f50f2127SFlorian Fainelli struct dsa_mall_mirror_tc_entry *mirror, 435f50f2127SFlorian Fainelli bool ingress); 436f50f2127SFlorian Fainelli void (*port_mirror_del)(struct dsa_switch *ds, int port, 437f50f2127SFlorian Fainelli struct dsa_mall_mirror_tc_entry *mirror); 438c8f0b869SBen Hutchings }; 439c8f0b869SBen Hutchings 440ab3d408dSFlorian Fainelli struct dsa_switch_driver { 441ab3d408dSFlorian Fainelli struct list_head list; 442a82f67afSFlorian Fainelli const struct dsa_switch_ops *ops; 443ab3d408dSFlorian Fainelli }; 444ab3d408dSFlorian Fainelli 445ab3d408dSFlorian Fainelli void register_switch_driver(struct dsa_switch_driver *type); 446ab3d408dSFlorian Fainelli void unregister_switch_driver(struct dsa_switch_driver *type); 447b4d2394dSAlexander Duyck struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev); 448c8f0b869SBen Hutchings 4495aed85ceSFlorian Fainelli static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst) 4505aed85ceSFlorian Fainelli { 4515075314eSAlexander Duyck return dst->rcv != NULL; 4525aed85ceSFlorian Fainelli } 45383c0afaeSAndrew Lunn 454a0c02161SVivien Didelot struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n); 45583c0afaeSAndrew Lunn void dsa_unregister_switch(struct dsa_switch *ds); 45655ed0ce0SFlorian Fainelli int dsa_register_switch(struct dsa_switch *ds, struct device *dev); 457ea825e70SFlorian Fainelli #ifdef CONFIG_PM_SLEEP 458ea825e70SFlorian Fainelli int dsa_switch_suspend(struct dsa_switch *ds); 459ea825e70SFlorian Fainelli int dsa_switch_resume(struct dsa_switch *ds); 460ea825e70SFlorian Fainelli #else 461ea825e70SFlorian Fainelli static inline int dsa_switch_suspend(struct dsa_switch *ds) 462ea825e70SFlorian Fainelli { 463ea825e70SFlorian Fainelli return 0; 464ea825e70SFlorian Fainelli } 465ea825e70SFlorian Fainelli static inline int dsa_switch_resume(struct dsa_switch *ds) 466ea825e70SFlorian Fainelli { 467ea825e70SFlorian Fainelli return 0; 468ea825e70SFlorian Fainelli } 469ea825e70SFlorian Fainelli #endif /* CONFIG_PM_SLEEP */ 470ea825e70SFlorian Fainelli 47191da11f8SLennert Buytenhek #endif 472