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> 16*f515f192SVivien 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 96*f515f192SVivien Didelot /* Notifier chain for switch-wide events */ 97*f515f192SVivien Didelot struct raw_notifier_head nh; 98*f515f192SVivien 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 189*f515f192SVivien Didelot /* Listener for switch fabric events */ 190*f515f192SVivien Didelot struct notifier_block nb; 191*f515f192SVivien 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 2719d490b4eSVivien Didelot struct dsa_switch_ops { 272c8f0b869SBen Hutchings /* 273c8f0b869SBen Hutchings * Probing and setup. 274c8f0b869SBen Hutchings */ 2750209d144SVivien Didelot const char *(*probe)(struct device *dsa_dev, 2760209d144SVivien Didelot struct device *host_dev, int sw_addr, 2770209d144SVivien Didelot void **priv); 2787b314362SAndrew Lunn 2797b314362SAndrew Lunn enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds); 2807b314362SAndrew Lunn 281c8f0b869SBen Hutchings int (*setup)(struct dsa_switch *ds); 282c8f0b869SBen Hutchings int (*set_addr)(struct dsa_switch *ds, u8 *addr); 2836819563eSFlorian Fainelli u32 (*get_phy_flags)(struct dsa_switch *ds, int port); 284c8f0b869SBen Hutchings 285c8f0b869SBen Hutchings /* 286c8f0b869SBen Hutchings * Access to the switch's PHY registers. 287c8f0b869SBen Hutchings */ 288c8f0b869SBen Hutchings int (*phy_read)(struct dsa_switch *ds, int port, int regnum); 289c8f0b869SBen Hutchings int (*phy_write)(struct dsa_switch *ds, int port, 290c8f0b869SBen Hutchings int regnum, u16 val); 291c8f0b869SBen Hutchings 292c8f0b869SBen Hutchings /* 293ec9436baSFlorian Fainelli * Link state adjustment (called from libphy) 294ec9436baSFlorian Fainelli */ 295ec9436baSFlorian Fainelli void (*adjust_link)(struct dsa_switch *ds, int port, 296ec9436baSFlorian Fainelli struct phy_device *phydev); 297ce31b31cSFlorian Fainelli void (*fixed_link_update)(struct dsa_switch *ds, int port, 298ce31b31cSFlorian Fainelli struct fixed_phy_status *st); 299ec9436baSFlorian Fainelli 300ec9436baSFlorian Fainelli /* 301c8f0b869SBen Hutchings * ethtool hardware statistics. 302c8f0b869SBen Hutchings */ 303c8f0b869SBen Hutchings void (*get_strings)(struct dsa_switch *ds, int port, uint8_t *data); 304c8f0b869SBen Hutchings void (*get_ethtool_stats)(struct dsa_switch *ds, 305c8f0b869SBen Hutchings int port, uint64_t *data); 306c8f0b869SBen Hutchings int (*get_sset_count)(struct dsa_switch *ds); 30724462549SFlorian Fainelli 30824462549SFlorian Fainelli /* 30919e57c4eSFlorian Fainelli * ethtool Wake-on-LAN 31019e57c4eSFlorian Fainelli */ 31119e57c4eSFlorian Fainelli void (*get_wol)(struct dsa_switch *ds, int port, 31219e57c4eSFlorian Fainelli struct ethtool_wolinfo *w); 31319e57c4eSFlorian Fainelli int (*set_wol)(struct dsa_switch *ds, int port, 31419e57c4eSFlorian Fainelli struct ethtool_wolinfo *w); 31519e57c4eSFlorian Fainelli 31619e57c4eSFlorian Fainelli /* 31724462549SFlorian Fainelli * Suspend and resume 31824462549SFlorian Fainelli */ 31924462549SFlorian Fainelli int (*suspend)(struct dsa_switch *ds); 32024462549SFlorian Fainelli int (*resume)(struct dsa_switch *ds); 321b2f2af21SFlorian Fainelli 322b2f2af21SFlorian Fainelli /* 323b2f2af21SFlorian Fainelli * Port enable/disable 324b2f2af21SFlorian Fainelli */ 325b2f2af21SFlorian Fainelli int (*port_enable)(struct dsa_switch *ds, int port, 326b2f2af21SFlorian Fainelli struct phy_device *phy); 327b2f2af21SFlorian Fainelli void (*port_disable)(struct dsa_switch *ds, int port, 328b2f2af21SFlorian Fainelli struct phy_device *phy); 3297905288fSFlorian Fainelli 3307905288fSFlorian Fainelli /* 3317905288fSFlorian Fainelli * EEE setttings 3327905288fSFlorian Fainelli */ 3337905288fSFlorian Fainelli int (*set_eee)(struct dsa_switch *ds, int port, 3347905288fSFlorian Fainelli struct phy_device *phydev, 3357905288fSFlorian Fainelli struct ethtool_eee *e); 3367905288fSFlorian Fainelli int (*get_eee)(struct dsa_switch *ds, int port, 3377905288fSFlorian Fainelli struct ethtool_eee *e); 33851579c3fSGuenter Roeck 3396793abb4SGuenter Roeck /* EEPROM access */ 3406793abb4SGuenter Roeck int (*get_eeprom_len)(struct dsa_switch *ds); 3416793abb4SGuenter Roeck int (*get_eeprom)(struct dsa_switch *ds, 3426793abb4SGuenter Roeck struct ethtool_eeprom *eeprom, u8 *data); 3436793abb4SGuenter Roeck int (*set_eeprom)(struct dsa_switch *ds, 3446793abb4SGuenter Roeck struct ethtool_eeprom *eeprom, u8 *data); 3453d762a0fSGuenter Roeck 3463d762a0fSGuenter Roeck /* 3473d762a0fSGuenter Roeck * Register access. 3483d762a0fSGuenter Roeck */ 3493d762a0fSGuenter Roeck int (*get_regs_len)(struct dsa_switch *ds, int port); 3503d762a0fSGuenter Roeck void (*get_regs)(struct dsa_switch *ds, int port, 3513d762a0fSGuenter Roeck struct ethtool_regs *regs, void *p); 352b73adef6SFlorian Fainelli 353b73adef6SFlorian Fainelli /* 354b73adef6SFlorian Fainelli * Bridge integration 355b73adef6SFlorian Fainelli */ 35634a79f63SVivien Didelot int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs); 35771327a4eSVivien Didelot int (*port_bridge_join)(struct dsa_switch *ds, int port, 358a6692754SVivien Didelot struct net_device *bridge); 359f123f2fbSVivien Didelot void (*port_bridge_leave)(struct dsa_switch *ds, int port, 360f123f2fbSVivien Didelot struct net_device *bridge); 36143c44a9fSVivien Didelot void (*port_stp_state_set)(struct dsa_switch *ds, int port, 362b73adef6SFlorian Fainelli u8 state); 363732f794cSVivien Didelot void (*port_fast_age)(struct dsa_switch *ds, int port); 3642a778e1bSVivien Didelot 3652a778e1bSVivien Didelot /* 36611149536SVivien Didelot * VLAN support 36711149536SVivien Didelot */ 368fb2dabadSVivien Didelot int (*port_vlan_filtering)(struct dsa_switch *ds, int port, 369fb2dabadSVivien Didelot bool vlan_filtering); 37076e398a6SVivien Didelot int (*port_vlan_prepare)(struct dsa_switch *ds, int port, 37176e398a6SVivien Didelot const struct switchdev_obj_port_vlan *vlan, 37276e398a6SVivien Didelot struct switchdev_trans *trans); 3734d5770b3SVivien Didelot void (*port_vlan_add)(struct dsa_switch *ds, int port, 37476e398a6SVivien Didelot const struct switchdev_obj_port_vlan *vlan, 37576e398a6SVivien Didelot struct switchdev_trans *trans); 37676e398a6SVivien Didelot int (*port_vlan_del)(struct dsa_switch *ds, int port, 37776e398a6SVivien Didelot const struct switchdev_obj_port_vlan *vlan); 37865aebfc0SVivien Didelot int (*port_vlan_dump)(struct dsa_switch *ds, int port, 37965aebfc0SVivien Didelot struct switchdev_obj_port_vlan *vlan, 38065aebfc0SVivien Didelot int (*cb)(struct switchdev_obj *obj)); 38111149536SVivien Didelot 38211149536SVivien Didelot /* 3832a778e1bSVivien Didelot * Forwarding database 3842a778e1bSVivien Didelot */ 385146a3206SVivien Didelot int (*port_fdb_prepare)(struct dsa_switch *ds, int port, 386146a3206SVivien Didelot const struct switchdev_obj_port_fdb *fdb, 387146a3206SVivien Didelot struct switchdev_trans *trans); 3888497aa61SVivien Didelot void (*port_fdb_add)(struct dsa_switch *ds, int port, 3891f36faf2SVivien Didelot const struct switchdev_obj_port_fdb *fdb, 3901f36faf2SVivien Didelot struct switchdev_trans *trans); 3912a778e1bSVivien Didelot int (*port_fdb_del)(struct dsa_switch *ds, int port, 3928057b3e7SVivien Didelot const struct switchdev_obj_port_fdb *fdb); 393ea70ba98SVivien Didelot int (*port_fdb_dump)(struct dsa_switch *ds, int port, 394ea70ba98SVivien Didelot struct switchdev_obj_port_fdb *fdb, 395ea70ba98SVivien Didelot int (*cb)(struct switchdev_obj *obj)); 3968df30255SVivien Didelot 3978df30255SVivien Didelot /* 3988df30255SVivien Didelot * Multicast database 3998df30255SVivien Didelot */ 4008df30255SVivien Didelot int (*port_mdb_prepare)(struct dsa_switch *ds, int port, 4018df30255SVivien Didelot const struct switchdev_obj_port_mdb *mdb, 4028df30255SVivien Didelot struct switchdev_trans *trans); 4038df30255SVivien Didelot void (*port_mdb_add)(struct dsa_switch *ds, int port, 4048df30255SVivien Didelot const struct switchdev_obj_port_mdb *mdb, 4058df30255SVivien Didelot struct switchdev_trans *trans); 4068df30255SVivien Didelot int (*port_mdb_del)(struct dsa_switch *ds, int port, 4078df30255SVivien Didelot const struct switchdev_obj_port_mdb *mdb); 4088df30255SVivien Didelot int (*port_mdb_dump)(struct dsa_switch *ds, int port, 4098df30255SVivien Didelot struct switchdev_obj_port_mdb *mdb, 4108df30255SVivien Didelot int (*cb)(struct switchdev_obj *obj)); 411bf9f2648SFlorian Fainelli 412bf9f2648SFlorian Fainelli /* 413bf9f2648SFlorian Fainelli * RXNFC 414bf9f2648SFlorian Fainelli */ 415bf9f2648SFlorian Fainelli int (*get_rxnfc)(struct dsa_switch *ds, int port, 416bf9f2648SFlorian Fainelli struct ethtool_rxnfc *nfc, u32 *rule_locs); 417bf9f2648SFlorian Fainelli int (*set_rxnfc)(struct dsa_switch *ds, int port, 418bf9f2648SFlorian Fainelli struct ethtool_rxnfc *nfc); 419f50f2127SFlorian Fainelli 420f50f2127SFlorian Fainelli /* 421f50f2127SFlorian Fainelli * TC integration 422f50f2127SFlorian Fainelli */ 423f50f2127SFlorian Fainelli int (*port_mirror_add)(struct dsa_switch *ds, int port, 424f50f2127SFlorian Fainelli struct dsa_mall_mirror_tc_entry *mirror, 425f50f2127SFlorian Fainelli bool ingress); 426f50f2127SFlorian Fainelli void (*port_mirror_del)(struct dsa_switch *ds, int port, 427f50f2127SFlorian Fainelli struct dsa_mall_mirror_tc_entry *mirror); 428c8f0b869SBen Hutchings }; 429c8f0b869SBen Hutchings 430ab3d408dSFlorian Fainelli struct dsa_switch_driver { 431ab3d408dSFlorian Fainelli struct list_head list; 432a82f67afSFlorian Fainelli const struct dsa_switch_ops *ops; 433ab3d408dSFlorian Fainelli }; 434ab3d408dSFlorian Fainelli 435ab3d408dSFlorian Fainelli void register_switch_driver(struct dsa_switch_driver *type); 436ab3d408dSFlorian Fainelli void unregister_switch_driver(struct dsa_switch_driver *type); 437b4d2394dSAlexander Duyck struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev); 438c8f0b869SBen Hutchings 4395aed85ceSFlorian Fainelli static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst) 4405aed85ceSFlorian Fainelli { 4415075314eSAlexander Duyck return dst->rcv != NULL; 4425aed85ceSFlorian Fainelli } 44383c0afaeSAndrew Lunn 444a0c02161SVivien Didelot struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n); 44583c0afaeSAndrew Lunn void dsa_unregister_switch(struct dsa_switch *ds); 44655ed0ce0SFlorian Fainelli int dsa_register_switch(struct dsa_switch *ds, struct device *dev); 447ea825e70SFlorian Fainelli #ifdef CONFIG_PM_SLEEP 448ea825e70SFlorian Fainelli int dsa_switch_suspend(struct dsa_switch *ds); 449ea825e70SFlorian Fainelli int dsa_switch_resume(struct dsa_switch *ds); 450ea825e70SFlorian Fainelli #else 451ea825e70SFlorian Fainelli static inline int dsa_switch_suspend(struct dsa_switch *ds) 452ea825e70SFlorian Fainelli { 453ea825e70SFlorian Fainelli return 0; 454ea825e70SFlorian Fainelli } 455ea825e70SFlorian Fainelli static inline int dsa_switch_resume(struct dsa_switch *ds) 456ea825e70SFlorian Fainelli { 457ea825e70SFlorian Fainelli return 0; 458ea825e70SFlorian Fainelli } 459ea825e70SFlorian Fainelli #endif /* CONFIG_PM_SLEEP */ 460ea825e70SFlorian Fainelli 46191da11f8SLennert Buytenhek #endif 462