{sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget&/translations/zh_CN/networking/dsa/dsamodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/zh_TW/networking/dsa/dsamodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/it_IT/networking/dsa/dsamodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/ja_JP/networking/dsa/dsamodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/ko_KR/networking/dsa/dsamodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget&/translations/sp_SP/networking/dsa/dsamodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhsection)}(hhh](htitle)}(h Architectureh]h Architecture}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhh@/var/lib/git/docbuild/linux/Documentation/networking/dsa/dsa.rsthKubh paragraph)}(hXThis document describes the **Distributed Switch Architecture (DSA)** subsystem design principles, limitations, interactions with other subsystems, and how to develop drivers for this subsystem as well as a TODO for developers interested in joining the effort.h](hThis document describes the }(hhhhhNhNubhstrong)}(h)**Distributed Switch Architecture (DSA)**h]h%Distributed Switch Architecture (DSA)}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh subsystem design principles, limitations, interactions with other subsystems, and how to develop drivers for this subsystem as well as a TODO for developers interested in joining the effort.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(hDesign principlesh]hDesign principles}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhK ubh)}(hThe Distributed Switch Architecture subsystem was primarily designed to support Marvell Ethernet switches (MV88E6xxx, a.k.a. Link Street product line) using Linux, but has since evolved to support other vendors as well.h]hThe Distributed Switch Architecture subsystem was primarily designed to support Marvell Ethernet switches (MV88E6xxx, a.k.a. Link Street product line) using Linux, but has since evolved to support other vendors as well.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hThe original philosophy behind this design was to be able to use unmodified Linux tools such as bridge, iproute2, ifconfig to work transparently whether they configured/queried a switch port network device or a regular network device.h]hThe original philosophy behind this design was to be able to use unmodified Linux tools such as bridge, iproute2, ifconfig to work transparently whether they configured/queried a switch port network device or a regular network device.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXAn Ethernet switch typically comprises multiple front-panel ports and one or more CPU or management ports. The DSA subsystem currently relies on the presence of a management port connected to an Ethernet controller capable of receiving Ethernet frames from the switch. This is a very common setup for all kinds of Ethernet switches found in Small Home and Office products: routers, gateways, or even top-of-rack switches. This host Ethernet controller will be later referred to as "conduit" and "cpu" in DSA terminology and code.h]hXAn Ethernet switch typically comprises multiple front-panel ports and one or more CPU or management ports. The DSA subsystem currently relies on the presence of a management port connected to an Ethernet controller capable of receiving Ethernet frames from the switch. This is a very common setup for all kinds of Ethernet switches found in Small Home and Office products: routers, gateways, or even top-of-rack switches. This host Ethernet controller will be later referred to as “conduit” and “cpu” in DSA terminology and code.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXThe D in DSA stands for Distributed, because the subsystem has been designed with the ability to configure and manage cascaded switches on top of each other using upstream and downstream Ethernet links between switches. These specific ports are referred to as "dsa" ports in DSA terminology and code. A collection of multiple switches connected to each other is called a "switch tree".h]hXThe D in DSA stands for Distributed, because the subsystem has been designed with the ability to configure and manage cascaded switches on top of each other using upstream and downstream Ethernet links between switches. These specific ports are referred to as “dsa” ports in DSA terminology and code. A collection of multiple switches connected to each other is called a “switch tree”.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXFor each front-panel port, DSA creates specialized network devices which are used as controlling and data-flowing endpoints for use by the Linux networking stack. These specialized network interfaces are referred to as "user" network interfaces in DSA terminology and code.h]hXFor each front-panel port, DSA creates specialized network devices which are used as controlling and data-flowing endpoints for use by the Linux networking stack. These specialized network interfaces are referred to as “user” network interfaces in DSA terminology and code.}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hhhhubh)}(hThe ideal case for using DSA is when an Ethernet switch supports a "switch tag" which is a hardware feature making the switch insert a specific tag for each Ethernet frame it receives to/from specific ports to help the management interface figure out:h]hThe ideal case for using DSA is when an Ethernet switch supports a “switch tag” which is a hardware feature making the switch insert a specific tag for each Ethernet frame it receives to/from specific ports to help the management interface figure out:}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK)hhhhubh bullet_list)}(hhh](h list_item)}(h#what port is this frame coming fromh]h)}(hjIh]h#what port is this frame coming from}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK.hjGubah}(h]h ]h"]h$]h&]uh1jEhjBhhhhhNubjF)}(h0what was the reason why this frame got forwardedh]h)}(hj`h]h0what was the reason why this frame got forwarded}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK/hj^ubah}(h]h ]h"]h$]h&]uh1jEhjBhhhhhNubjF)}(h5how to send CPU originated traffic to specific ports h]h)}(h4how to send CPU originated traffic to specific portsh]h4how to send CPU originated traffic to specific ports}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hjuubah}(h]h ]h"]h$]h&]uh1jEhjBhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1j@hhhK.hhhhubh)}(hThe subsystem does support switches not capable of inserting/stripping tags, but the features might be slightly limited in that case (traffic separation relies on Port-based VLAN IDs).h]hThe subsystem does support switches not capable of inserting/stripping tags, but the features might be slightly limited in that case (traffic separation relies on Port-based VLAN IDs).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK2hhhhubh)}(haNote that DSA does not currently create network interfaces for the "cpu" and "dsa" ports because:h]hiNote that DSA does not currently create network interfaces for the “cpu” and “dsa” ports because:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hhhhubjA)}(hhh](jF)}(hthe "cpu" port is the Ethernet switch facing side of the management controller, and as such, would create a duplication of feature, since you would get two interfaces for the same conduit: conduit netdev, and "cpu" netdev h]h)}(hthe "cpu" port is the Ethernet switch facing side of the management controller, and as such, would create a duplication of feature, since you would get two interfaces for the same conduit: conduit netdev, and "cpu" netdevh]hthe “cpu” port is the Ethernet switch facing side of the management controller, and as such, would create a duplication of feature, since you would get two interfaces for the same conduit: conduit netdev, and “cpu” netdev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK9hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hthe "dsa" port(s) are just conduits between two or more switches, and as such cannot really be used as proper network interfaces either, only the downstream, or the top-most upstream interface makes sense with that model h]h)}(hthe "dsa" port(s) are just conduits between two or more switches, and as such cannot really be used as proper network interfaces either, only the downstream, or the top-most upstream interface makes sense with that modelh]hthe “dsa” port(s) are just conduits between two or more switches, and as such cannot really be used as proper network interfaces either, only the downstream, or the top-most upstream interface makes sense with that model}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK=hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhK9hhhhubh)}(hNB: for the past 15 years, the DSA subsystem had been making use of the terms "master" (rather than "conduit") and "slave" (rather than "user"). These terms have been removed from the DSA codebase and phased out of the uAPI.h]hNB: for the past 15 years, the DSA subsystem had been making use of the terms “master” (rather than “conduit”) and “slave” (rather than “user”). These terms have been removed from the DSA codebase and phased out of the uAPI.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKAhhhhubh)}(hhh](h)}(hSwitch tagging protocolsh]hSwitch tagging protocols}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKFubh)}(hDSA supports many vendor-specific tagging protocols, one software-defined tagging protocol, and a tag-less mode as well (``DSA_TAG_PROTO_NONE``).h](hyDSA supports many vendor-specific tagging protocols, one software-defined tagging protocol, and a tag-less mode as well (}(hj hhhNhNubhliteral)}(h``DSA_TAG_PROTO_NONE``h]hDSA_TAG_PROTO_NONE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKHhjhhubh)}(hjThe exact format of the tag protocol is vendor specific, but in general, they all contain something which:h]hjThe exact format of the tag protocol is vendor specific, but in general, they all contain something which:}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKKhjhhubjA)}(hhh](jF)}(hDidentifies which port the Ethernet frame came from/should be sent toh]h)}(hj>h]hDidentifies which port the Ethernet frame came from/should be sent to}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKNhj<ubah}(h]h ]h"]h$]h&]uh1jEhj9hhhhhNubjF)}(hKprovides a reason why this frame was forwarded to the management interface h]h)}(hJprovides a reason why this frame was forwarded to the management interfaceh]hJprovides a reason why this frame was forwarded to the management interface}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKOhjSubah}(h]h ]h"]h$]h&]uh1jEhj9hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhKNhjhhubh)}(hAll tagging protocols are in ``net/dsa/tag_*.c`` files and implement the methods of the ``struct dsa_device_ops`` structure, which are detailed below.h](hAll tagging protocols are in }(hjqhhhNhNubj)}(h``net/dsa/tag_*.c``h]hnet/dsa/tag_*.c}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjqubh( files and implement the methods of the }(hjqhhhNhNubj)}(h``struct dsa_device_ops``h]hstruct dsa_device_ops}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjqubh% structure, which are detailed below.}(hjqhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKQhjhhubh)}(hdata`` pointing at ``skb_mac_header(skb)``, i.e. at the destination MAC address, and the passed ``struct net_device *dev`` represents the virtual DSA user network interface whose hardware counterpart the packet must be steered to (i.e. ``swp0``). The job of this method is to prepare the skb in a way that the switch will understand what egress port the packet is for (and not deliver it towards other ports). Typically this is fulfilled by pushing a frame header. Checking for insufficient size in the skb headroom or tailroom is unnecessary provided that the ``needed_headroom`` and ``needed_tailroom`` properties were filled out properly, because DSA ensures there is enough space before calling this method.h](h9The transmission of a packet goes through the tagger’s }(hj?hhhNhNubj)}(h``xmit``h]hxmit}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh function. The passed }(hj?hhhNhNubj)}(h``struct sk_buff *skb``h]hstruct sk_buff *skb}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh has }(hj?hhhNhNubj)}(h ``skb->data``h]h skb->data}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh pointing at }(hj?hhhNhNubj)}(h``skb_mac_header(skb)``h]hskb_mac_header(skb)}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh6, i.e. at the destination MAC address, and the passed }(hj?hhhNhNubj)}(h``struct net_device *dev``h]hstruct net_device *dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubhr represents the virtual DSA user network interface whose hardware counterpart the packet must be steered to (i.e. }(hj?hhhNhNubj)}(h``swp0``h]hswp0}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubhX=). The job of this method is to prepare the skb in a way that the switch will understand what egress port the packet is for (and not deliver it towards other ports). Typically this is fulfilled by pushing a frame header. Checking for insufficient size in the skb headroom or tailroom is unnecessary provided that the }(hj?hhhNhNubj)}(h``needed_headroom``h]hneeded_headroom}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh and }(hj?hhhNhNubj)}(h``needed_tailroom``h]hneeded_tailroom}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubhk properties were filled out properly, because DSA ensures there is enough space before calling this method.}(hj?hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX;The reception of a packet goes through the tagger's ``rcv`` function. The passed ``struct sk_buff *skb`` has ``skb->data`` pointing at ``skb_mac_header(skb) + ETH_ALEN`` octets, i.e. to where the first octet after the EtherType would have been, were this frame not tagged. The role of this method is to consume the frame header, adjust ``skb->data`` to really point at the first octet after the EtherType, and to change ``skb->dev`` to point to the virtual DSA user network interface corresponding to the physical front-facing switch port that the packet was received on.h](h6The reception of a packet goes through the tagger’s }(hjhhhNhNubj)}(h``rcv``h]hrcv}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh function. The passed }(hjhhhNhNubj)}(h``struct sk_buff *skb``h]hstruct sk_buff *skb}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh has }(hjhhhNhNubj)}(h ``skb->data``h]h skb->data}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh pointing at }(hjhhhNhNubj)}(h"``skb_mac_header(skb) + ETH_ALEN``h]hskb_mac_header(skb) + ETH_ALEN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh octets, i.e. to where the first octet after the EtherType would have been, were this frame not tagged. The role of this method is to consume the frame header, adjust }(hjhhhNhNubj)}(h ``skb->data``h]h skb->data}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhG to really point at the first octet after the EtherType, and to change }(hjhhhNhNubj)}(h ``skb->dev``h]hskb->dev}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh to point to the virtual DSA user network interface corresponding to the physical front-facing switch port that the packet was received on.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXSince tagging protocols in category 1 and 2 break software (and most often also hardware) packet dissection on the DSA conduit, features such as RPS (Receive Packet Steering) on the DSA conduit would be broken. The DSA framework deals with this by hooking into the flow dissector and shifting the offset at which the IP header is to be found in the tagged frame as seen by the DSA conduit. This behavior is automatic based on the ``overhead`` value of the tagging protocol. If not all packets are of equal size, the tagger can implement the ``flow_dissect`` method of the ``struct dsa_device_ops`` and override this default behavior by specifying the correct offset incurred by each individual RX packet. Tail taggers do not cause issues to the flow dissector.h](hXSince tagging protocols in category 1 and 2 break software (and most often also hardware) packet dissection on the DSA conduit, features such as RPS (Receive Packet Steering) on the DSA conduit would be broken. The DSA framework deals with this by hooking into the flow dissector and shifting the offset at which the IP header is to be found in the tagged frame as seen by the DSA conduit. This behavior is automatic based on the }(hjWhhhNhNubj)}(h ``overhead``h]hoverhead}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjWubhc value of the tagging protocol. If not all packets are of equal size, the tagger can implement the }(hjWhhhNhNubj)}(h``flow_dissect``h]h flow_dissect}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjWubh method of the }(hjWhhhNhNubj)}(h``struct dsa_device_ops``h]hstruct dsa_device_ops}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjWubh and override this default behavior by specifying the correct offset incurred by each individual RX packet. Tail taggers do not cause issues to the flow dissector.}(hjWhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXChecksum offload should work with category 1 and 2 taggers when the DSA conduit driver declares NETIF_F_HW_CSUM in vlan_features and looks at csum_start and csum_offset. For those cases, DSA will shift the checksum start and offset by the tag size. If the DSA conduit driver still uses the legacy NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM in vlan_features, the offload might only work if the offload hardware already expects that specific tag (perhaps due to matching vendors). DSA user ports inherit those flags from the conduit, and it is up to the driver to correctly fall back to software checksum when the IP header is not where the hardware expects. If that check is ineffective, the packets might go to the network without a proper checksum (the checksum field will have the pseudo IP header sum). For category 3, when the offload hardware does not already expect the switch tag in use, the checksum must be calculated before any tag is inserted (i.e. inside the tagger). Otherwise, the DSA conduit would include the tail tag in the (software or hardware) checksum calculation. Then, when the tag gets stripped by the switch during transmission, it will leave an incorrect IP checksum in place.h]hXChecksum offload should work with category 1 and 2 taggers when the DSA conduit driver declares NETIF_F_HW_CSUM in vlan_features and looks at csum_start and csum_offset. For those cases, DSA will shift the checksum start and offset by the tag size. If the DSA conduit driver still uses the legacy NETIF_F_IP_CSUM or NETIF_F_IPV6_CSUM in vlan_features, the offload might only work if the offload hardware already expects that specific tag (perhaps due to matching vendors). DSA user ports inherit those flags from the conduit, and it is up to the driver to correctly fall back to software checksum when the IP header is not where the hardware expects. If that check is ineffective, the packets might go to the network without a proper checksum (the checksum field will have the pseudo IP header sum). For category 3, when the offload hardware does not already expect the switch tag in use, the checksum must be calculated before any tag is inserted (i.e. inside the tagger). Otherwise, the DSA conduit would include the tail tag in the (software or hardware) checksum calculation. Then, when the tag gets stripped by the switch during transmission, it will leave an incorrect IP checksum in place.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXDue to various reasons (most common being category 1 taggers being associated with DSA-unaware conduits, mangling what the conduit perceives as MAC DA), the tagging protocol may require the DSA conduit to operate in promiscuous mode, to receive all frames regardless of the value of the MAC DA. This can be done by setting the ``promisc_on_conduit`` property of the ``struct dsa_device_ops``. Note that this assumes a DSA-unaware conduit driver, which is the norm.h](hXGDue to various reasons (most common being category 1 taggers being associated with DSA-unaware conduits, mangling what the conduit perceives as MAC DA), the tagging protocol may require the DSA conduit to operate in promiscuous mode, to receive all frames regardless of the value of the MAC DA. This can be done by setting the }(hjhhhNhNubj)}(h``promisc_on_conduit``h]hpromisc_on_conduit}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh property of the }(hjhhhNhNubj)}(h``struct dsa_device_ops``h]hstruct dsa_device_ops}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhI. Note that this assumes a DSA-unaware conduit driver, which is the norm.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]switch-tagging-protocolsah ]h"]switch tagging protocolsah$]h&]uh1hhhhhhhhKFubh)}(hhh](h)}(hConduit network devicesh]hConduit network devices}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hX=Conduit network devices are regular, unmodified Linux network device drivers for the CPU/management Ethernet interface. Such a driver might occasionally need to know whether DSA is enabled (e.g.: to enable/disable specific offload features), but the DSA subsystem has been proven to work with industry standard drivers: ``e1000e,`` ``mv643xx_eth`` etc. without having to introduce modifications to these drivers. Such network devices are also often referred to as conduit network devices since they act as a pipe between the host processor and the hardware Ethernet switch.h](hX@Conduit network devices are regular, unmodified Linux network device drivers for the CPU/management Ethernet interface. Such a driver might occasionally need to know whether DSA is enabled (e.g.: to enable/disable specific offload features), but the DSA subsystem has been proven to work with industry standard drivers: }(hjhhhNhNubj)}(h ``e1000e,``h]he1000e,}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }(hjhhhNhNubj)}(h``mv643xx_eth``h]h mv643xx_eth}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh etc. without having to introduce modifications to these drivers. Such network devices are also often referred to as conduit network devices since they act as a pipe between the host processor and the hardware Ethernet switch.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]conduit-network-devicesah ]h"]conduit network devicesah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hNetworking stack hooksh]hNetworking stack hooks}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj.hhhhhKubh)}(hXWhen a conduit netdev is used with DSA, a small hook is placed in the networking stack is in order to have the DSA subsystem process the Ethernet switch specific tagging protocol. DSA accomplishes this by registering a specific (and fake) Ethernet type (later becoming ``skb->protocol``) with the networking stack, this is also known as a ``ptype`` or ``packet_type``. A typical Ethernet Frame receive sequence looks like this:h](hX When a conduit netdev is used with DSA, a small hook is placed in the networking stack is in order to have the DSA subsystem process the Ethernet switch specific tagging protocol. DSA accomplishes this by registering a specific (and fake) Ethernet type (later becoming }(hj?hhhNhNubj)}(h``skb->protocol``h]h skb->protocol}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh5) with the networking stack, this is also known as a }(hj?hhhNhNubj)}(h ``ptype``h]hptype}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh or }(hj?hhhNhNubj)}(h``packet_type``h]h packet_type}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh<. A typical Ethernet Frame receive sequence looks like this:}(hj?hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj.hhubh)}(h&Conduit network device (e.g.: e1000e):h]h&Conduit network device (e.g.: e1000e):}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj.hhubj)}(hhh](jF)}(hReceive interrupt fires: - receive function is invoked - basic packet processing is done: getting length, status etc. - packet is prepared to be processed by the Ethernet layer by calling ``eth_type_trans`` h](h)}(hReceive interrupt fires:h]hReceive interrupt fires:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh block_quote)}(h- receive function is invoked - basic packet processing is done: getting length, status etc. - packet is prepared to be processed by the Ethernet layer by calling ``eth_type_trans`` h]jA)}(hhh](jF)}(hreceive function is invokedh]h)}(hjh]hreceive function is invoked}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jEhjubjF)}(hdsa_ptr != NULL) -> skb->protocol = ETH_P_XDSA h](h)}(hnet/ethernet/eth.c::h]hnet/ethernet/eth.c:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubj)}(hheth_type_trans(skb, dev) if (dev->dsa_ptr != NULL) -> skb->protocol = ETH_P_XDSAh]hheth_type_trans(skb, dev) if (dev->dsa_ptr != NULL) -> skb->protocol = ETH_P_XDSA}hj'sbah}(h]h ]h"]h$]h&]jjuh1jhhhMhjubeh}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hdrivers/net/ethernet/\*:: netif_receive_skb(skb) -> iterate over registered packet_type -> invoke handler for ETH_P_XDSA, calls dsa_switch_rcv() h](h)}(hdrivers/net/ethernet/\*::h]hdrivers/net/ethernet/*:}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj;ubj)}(hnetif_receive_skb(skb) -> iterate over registered packet_type -> invoke handler for ETH_P_XDSA, calls dsa_switch_rcv()h]hnetif_receive_skb(skb) -> iterate over registered packet_type -> invoke handler for ETH_P_XDSA, calls dsa_switch_rcv()}hjMsbah}(h]h ]h"]h$]h&]jjuh1jhhhMhj;ubeh}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hnet/dsa/dsa.c:: -> dsa_switch_rcv() -> invoke switch tag specific protocol handler in 'net/dsa/tag_*.c' h](h)}(hnet/dsa/dsa.c::h]hnet/dsa/dsa.c:}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjaubj)}(h_-> dsa_switch_rcv() -> invoke switch tag specific protocol handler in 'net/dsa/tag_*.c'h]h_-> dsa_switch_rcv() -> invoke switch tag specific protocol handler in 'net/dsa/tag_*.c'}hjssbah}(h]h ]h"]h$]h&]jjuh1jhhhM hjaubeh}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hnet/dsa/tag_*.c: - inspect and strip switch tag protocol to determine originating port - locate per-port network device - invoke ``eth_type_trans()`` with the DSA user network device - invoked ``netif_receive_skb()`` h](h)}(hnet/dsa/tag_*.c:h]hnet/dsa/tag_*.c:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubj)}(h- inspect and strip switch tag protocol to determine originating port - locate per-port network device - invoke ``eth_type_trans()`` with the DSA user network device - invoked ``netif_receive_skb()`` h]jA)}(hhh](jF)}(hCinspect and strip switch tag protocol to determine originating porth]h)}(hjh]hCinspect and strip switch tag protocol to determine originating port}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjubjF)}(hlocate per-port network deviceh]h)}(hjh]hlocate per-port network device}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjubjF)}(hdsa_ptr becomes non-NULL), and the switch behind it expects a tagging protocol, this network interface can only exclusively be used as a conduit interface. Sending packets directly through this interface (e.g.: opening a socket using this interface) will not make us go through the switch tagging protocol transmit function, so the Ethernet switch on the other end, expecting a tag will typically drop this frame.h]hXOnce a conduit network device is configured to use DSA (dev->dsa_ptr becomes non-NULL), and the switch behind it expects a tagging protocol, this network interface can only exclusively be used as a conduit interface. Sending packets directly through this interface (e.g.: opening a socket using this interface) will not make us go through the switch tagging protocol transmit function, so the Ethernet switch on the other end, expecting a tag will typically drop this frame.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h] common-pitfalls-using-dsa-setupsah ]h"] common pitfalls using dsa setupsah$]h&]uh1hhj! hhhhhMubeh}(h]design-limitationsah ]h"]design limitationsah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(h"Interactions with other subsystemsh]h"Interactions with other subsystems}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(h1DSA currently leverages the following subsystems:h]h1DSA currently leverages the following subsystems:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubjA)}(hhh](jF)}(h;MDIO/PHY library: ``drivers/net/phy/phy.c``, ``mdio_bus.c``h]h)}(hj h](hMDIO/PHY library: }(hj hhhNhNubj)}(h``drivers/net/phy/phy.c``h]hdrivers/net/phy/phy.c}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh, }(hj hhhNhNubj)}(h``mdio_bus.c``h]h mdio_bus.c}(hj) hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhj hhhhhNubjF)}(hSwitchdev:``net/switchdev/*``h]h)}(hjE h](h Switchdev:}(hjG hhhNhNubj)}(h``net/switchdev/*``h]hnet/switchdev/*}(hjN hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjG ubeh}(h]h ]h"]h$]h&]uh1hhhhMhjC ubah}(h]h ]h"]h$]h&]uh1jEhj hhhhhNubjF)}(h&Device Tree for various of_* functionsh]h)}(hjj h]h&Device Tree for various of_* functions}(hjl hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjh ubah}(h]h ]h"]h$]h&]uh1jEhj hhhhhNubjF)}(h Devlink: ``net/core/devlink.c`` h]h)}(hDevlink: ``net/core/devlink.c``h](h Devlink: }(hj hhhNhNubj)}(h``net/core/devlink.c``h]hnet/core/devlink.c}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhj hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhj hhubh)}(hhh](h)}(hMDIO/PHY libraryh]hMDIO/PHY library}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hUser network devices exposed by DSA may or may not be interfacing with PHY devices (``struct phy_device`` as defined in ``include/linux/phy.h)``, but the DSA subsystem deals with all possible combinations:h](hTUser network devices exposed by DSA may or may not be interfacing with PHY devices (}(hj hhhNhNubj)}(h``struct phy_device``h]hstruct phy_device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh as defined in }(hj hhhNhNubj)}(h``include/linux/phy.h)``h]hinclude/linux/phy.h)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh=, but the DSA subsystem deals with all possible combinations:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubjA)}(hhh](jF)}(h=internal PHY devices, built into the Ethernet switch hardwareh]h)}(hj h]h=internal PHY devices, built into the Ethernet switch hardware}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhj hhhhhNubjF)}(hDexternal PHY devices, connected via an internal or external MDIO bush]h)}(hj h]hDexternal PHY devices, connected via an internal or external MDIO bus}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhj hhhhhNubjF)}(h8internal PHY devices, connected via an internal MDIO bush]h)}(hj! h]h8internal PHY devices, connected via an internal MDIO bus}(hj# hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhj hhhhhNubjF)}(hZspecial, non-autonegotiated or non MDIO-managed PHY devices: SFPs, MoCA; a.k.a fixed PHYs h]h)}(hYspecial, non-autonegotiated or non MDIO-managed PHY devices: SFPs, MoCA; a.k.a fixed PHYsh]hYspecial, non-autonegotiated or non MDIO-managed PHY devices: SFPs, MoCA; a.k.a fixed PHYs}(hj: hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj6 ubah}(h]h ]h"]h$]h&]uh1jEhj hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhj hhubh)}(hoThe PHY configuration is done by the ``dsa_user_phy_setup()`` function and the logic basically looks like this:h](h%The PHY configuration is done by the }(hjT hhhNhNubj)}(h``dsa_user_phy_setup()``h]hdsa_user_phy_setup()}(hj\ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjT ubh2 function and the logic basically looks like this:}(hjT hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubjA)}(hhh](jF)}(hif Device Tree is used, the PHY device is looked up using the standard "phy-handle" property, if found, this PHY device is created and registered using ``of_phy_connect()`` h]h)}(hif Device Tree is used, the PHY device is looked up using the standard "phy-handle" property, if found, this PHY device is created and registered using ``of_phy_connect()``h](hif Device Tree is used, the PHY device is looked up using the standard “phy-handle” property, if found, this PHY device is created and registered using }(hj{ hhhNhNubj)}(h``of_phy_connect()``h]hof_phy_connect()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj{ ubeh}(h]h ]h"]h$]h&]uh1hhhhMhjw ubah}(h]h ]h"]h$]h&]uh1jEhjt hhhhhNubjF)}(hXif Device Tree is used and the PHY device is "fixed", that is, conforms to the definition of a non-MDIO managed PHY as defined in ``Documentation/devicetree/bindings/net/fixed-link.txt``, the PHY is registered and connected transparently using the special fixed MDIO bus driver h]h)}(hXif Device Tree is used and the PHY device is "fixed", that is, conforms to the definition of a non-MDIO managed PHY as defined in ``Documentation/devicetree/bindings/net/fixed-link.txt``, the PHY is registered and connected transparently using the special fixed MDIO bus driverh](hif Device Tree is used and the PHY device is “fixed”, that is, conforms to the definition of a non-MDIO managed PHY as defined in }(hj hhhNhNubj)}(h8``Documentation/devicetree/bindings/net/fixed-link.txt``h]h4Documentation/devicetree/bindings/net/fixed-link.txt}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh[, the PHY is registered and connected transparently using the special fixed MDIO bus driver}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhjt hhhhhNubjF)}(hfinally, if the PHY is built into the switch, as is very common with standalone switch packages, the PHY is probed using the user MII bus created by DSA h]h)}(hfinally, if the PHY is built into the switch, as is very common with standalone switch packages, the PHY is probed using the user MII bus created by DSAh]hfinally, if the PHY is built into the switch, as is very common with standalone switch packages, the PHY is probed using the user MII bus created by DSA}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhjt hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhj hhubeh}(h]mdio-phy-libraryah ]h"]mdio/phy libraryah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(h SWITCHDEVh]h SWITCHDEV}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hXDSA directly utilizes SWITCHDEV when interfacing with the bridge layer, and more specifically with its VLAN filtering portion when configuring VLANs on top of per-port user network devices. As of today, the only SWITCHDEV objects supported by DSA are the FDB and VLAN objects.h]hXDSA directly utilizes SWITCHDEV when interfacing with the bridge layer, and more specifically with its VLAN filtering portion when configuring VLANs on top of per-port user network devices. As of today, the only SWITCHDEV objects supported by DSA are the FDB and VLAN objects.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h] switchdevah ]h"] switchdevah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(hDevlinkh]hDevlink}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hDSA registers one devlink device per physical switch in the fabric. For each devlink device, every physical port (i.e. user ports, CPU ports, DSA links or unused ports) is exposed as a devlink port.h]hDSA registers one devlink device per physical switch in the fabric. For each devlink device, every physical port (i.e. user ports, CPU ports, DSA links or unused ports) is exposed as a devlink port.}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h;DSA drivers can make use of the following devlink features:h]h;DSA drivers can make use of the following devlink features:}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubjA)}(hhh](jF)}(hXRegions: debugging feature which allows user space to dump driver-defined areas of hardware information in a low-level, binary format. Both global regions as well as per-port regions are supported. It is possible to export devlink regions even for pieces of data that are already exposed in some way to the standard iproute2 user space programs (ip-link, bridge), like address tables and VLAN tables. For example, this might be useful if the tables contain additional hardware-specific details which are not visible through the iproute2 abstraction, or it might be useful to inspect these tables on the non-user ports too, which are invisible to iproute2 because no network interface is registered for them.h]h)}(hXRegions: debugging feature which allows user space to dump driver-defined areas of hardware information in a low-level, binary format. Both global regions as well as per-port regions are supported. It is possible to export devlink regions even for pieces of data that are already exposed in some way to the standard iproute2 user space programs (ip-link, bridge), like address tables and VLAN tables. For example, this might be useful if the tables contain additional hardware-specific details which are not visible through the iproute2 abstraction, or it might be useful to inspect these tables on the non-user ports too, which are invisible to iproute2 because no network interface is registered for them.h]hXRegions: debugging feature which allows user space to dump driver-defined areas of hardware information in a low-level, binary format. Both global regions as well as per-port regions are supported. It is possible to export devlink regions even for pieces of data that are already exposed in some way to the standard iproute2 user space programs (ip-link, bridge), like address tables and VLAN tables. For example, this might be useful if the tables contain additional hardware-specific details which are not visible through the iproute2 abstraction, or it might be useful to inspect these tables on the non-user ports too, which are invisible to iproute2 because no network interface is registered for them.}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjDubah}(h]h ]h"]h$]h&]uh1jEhjAhhhhhNubjF)}(hParams: a feature which enables user to configure certain low-level tunable knobs pertaining to the device. Drivers may implement applicable generic devlink params, or may add new device-specific devlink params.h]h)}(hParams: a feature which enables user to configure certain low-level tunable knobs pertaining to the device. Drivers may implement applicable generic devlink params, or may add new device-specific devlink params.h]hParams: a feature which enables user to configure certain low-level tunable knobs pertaining to the device. Drivers may implement applicable generic devlink params, or may add new device-specific devlink params.}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj\ubah}(h]h ]h"]h$]h&]uh1jEhjAhhhhhNubjF)}(hResources: a monitoring feature which enables users to see the degree of utilization of certain hardware tables in the device, such as FDB, VLAN, etc.h]h)}(hResources: a monitoring feature which enables users to see the degree of utilization of certain hardware tables in the device, such as FDB, VLAN, etc.h]hResources: a monitoring feature which enables users to see the degree of utilization of certain hardware tables in the device, such as FDB, VLAN, etc.}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjtubah}(h]h ]h"]h$]h&]uh1jEhjAhhhhhNubjF)}(hXShared buffers: a QoS feature for adjusting and partitioning memory and frame reservations per port and per traffic class, in the ingress and egress directions, such that low-priority bulk traffic does not impede the processing of high-priority critical traffic. h]h)}(hXShared buffers: a QoS feature for adjusting and partitioning memory and frame reservations per port and per traffic class, in the ingress and egress directions, such that low-priority bulk traffic does not impede the processing of high-priority critical traffic.h]hXShared buffers: a QoS feature for adjusting and partitioning memory and frame reservations per port and per traffic class, in the ingress and egress directions, such that low-priority bulk traffic does not impede the processing of high-priority critical traffic.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjAhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhjhhubh)}(h@For more details, consult ``Documentation/networking/devlink/``.h](hFor more details, consult }(hjhhhNhNubj)}(h%``Documentation/networking/devlink/``h]h!Documentation/networking/devlink/}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h]devlinkah ]h"]devlinkah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(h Device Treeh]h Device Tree}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hX+DSA features a standardized binding which is documented in ``Documentation/devicetree/bindings/net/dsa/dsa.txt``. PHY/MDIO library helper functions such as ``of_get_phy_mode()``, ``of_phy_connect()`` are also used to query per-port PHY specific details: interface connection, MDIO bus location, etc.h](h;DSA features a standardized binding which is documented in }(hjhhhNhNubj)}(h5``Documentation/devicetree/bindings/net/dsa/dsa.txt``h]h1Documentation/devicetree/bindings/net/dsa/dsa.txt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh,. PHY/MDIO library helper functions such as }(hjhhhNhNubj)}(h``of_get_phy_mode()``h]hof_get_phy_mode()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h``of_phy_connect()``h]hof_phy_connect()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhd are also used to query per-port PHY specific details: interface connection, MDIO bus location, etc.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h] device-treeah ]h"] device treeah$]h&]uh1hhj hhhhhMubeh}(h]"interactions-with-other-subsystemsah ]h"]"interactions with other subsystemsah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(hDriver developmenth]hDriver development}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj7hhhhhM ubh)}(h{DSA switch drivers need to implement a ``dsa_switch_ops`` structure which will contain the various members described below.h](h'DSA switch drivers need to implement a }(hjHhhhNhNubj)}(h``dsa_switch_ops``h]hdsa_switch_ops}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubhB structure which will contain the various members described below.}(hjHhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj7hhubh)}(hhh](h)}(h)Probing, registration and device lifetimeh]h)Probing, registration and device lifetime}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhhMubh)}(hDSA switches are regular ``device`` structures on buses (be they platform, SPI, I2C, MDIO or otherwise). The DSA framework is not involved in their probing with the device core.h](hDSA switches are regular }(hjyhhhNhNubj)}(h ``device``h]hdevice}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjyubh structures on buses (be they platform, SPI, I2C, MDIO or otherwise). The DSA framework is not involved in their probing with the device core.}(hjyhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhhubh)}(hSwitch registration from the perspective of a driver means passing a valid ``struct dsa_switch`` pointer to ``dsa_register_switch()``, usually from the switch driver's probing function. The following members must be valid in the provided structure:h](hKSwitch registration from the perspective of a driver means passing a valid }(hjhhhNhNubj)}(h``struct dsa_switch``h]hstruct dsa_switch}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh pointer to }(hjhhhNhNubj)}(h``dsa_register_switch()``h]hdsa_register_switch()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhu, usually from the switch driver’s probing function. The following members must be valid in the provided structure:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhhubjA)}(hhh](jF)}(hJ``ds->dev``: will be used to parse the switch's OF node or platform data. h]h)}(hI``ds->dev``: will be used to parse the switch's OF node or platform data.h](j)}(h ``ds->dev``h]hds->dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh@: will be used to parse the switch’s OF node or platform data.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h``ds->num_ports``: will be used to create the port list for this switch, and to validate the port indices provided in the OF node. h]h)}(h``ds->num_ports``: will be used to create the port list for this switch, and to validate the port indices provided in the OF node.h](j)}(h``ds->num_ports``h]h ds->num_ports}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhq: will be used to create the port list for this switch, and to validate the port indices provided in the OF node.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hc``ds->ops``: a pointer to the ``dsa_switch_ops`` structure holding the DSA method implementations. h]h)}(hb``ds->ops``: a pointer to the ``dsa_switch_ops`` structure holding the DSA method implementations.h](j)}(h ``ds->ops``h]hds->ops}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: a pointer to the }(hjhhhNhNubj)}(h``dsa_switch_ops``h]hdsa_switch_ops}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh2 structure holding the DSA method implementations.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hy``ds->priv``: backpointer to a driver-private data structure which can be retrieved in all further DSA method callbacks. h]h)}(hx``ds->priv``: backpointer to a driver-private data structure which can be retrieved in all further DSA method callbacks.h](j)}(h ``ds->priv``h]hds->priv}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjVubhl: backpointer to a driver-private data structure which can be retrieved in all further DSA method callbacks.}(hjVhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM#hjRubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhjhhhubh)}(hIn addition, the following flags in the ``dsa_switch`` structure may optionally be configured to obtain driver-specific behavior from the DSA core. Their behavior when set is documented through comments in ``include/net/dsa.h``.h](h(In addition, the following flags in the }(hj~hhhNhNubj)}(h``dsa_switch``h]h dsa_switch}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ubh structure may optionally be configured to obtain driver-specific behavior from the DSA core. Their behavior when set is documented through comments in }(hj~hhhNhNubj)}(h``include/net/dsa.h``h]hinclude/net/dsa.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ubh.}(hj~hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM&hjhhhubjA)}(hhh](jF)}(h!``ds->vlan_filtering_is_global`` h]h)}(h ``ds->vlan_filtering_is_global``h]j)}(hjh]hds->vlan_filtering_is_global}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhM*hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h(``ds->needs_standalone_vlan_filtering`` h]h)}(h'``ds->needs_standalone_vlan_filtering``h]j)}(hjh]h#ds->needs_standalone_vlan_filtering}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhM,hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h+``ds->configure_vlan_while_not_filtering`` h]h)}(h*``ds->configure_vlan_while_not_filtering``h]j)}(hjh]h&ds->configure_vlan_while_not_filtering}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhM.hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h``ds->untag_bridge_pvid`` h]h)}(h``ds->untag_bridge_pvid``h]j)}(hjh]hds->untag_bridge_pvid}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhM0hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h&``ds->assisted_learning_on_cpu_port`` h]h)}(h%``ds->assisted_learning_on_cpu_port``h]j)}(hj=h]h!ds->assisted_learning_on_cpu_port}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj;ubah}(h]h ]h"]h$]h&]uh1hhhhM2hj7ubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h ``ds->mtu_enforcement_ingress`` h]h)}(h``ds->mtu_enforcement_ingress``h]j)}(hj^h]hds->mtu_enforcement_ingress}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubah}(h]h ]h"]h$]h&]uh1hhhhM4hjXubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h``ds->fdb_isolation`` h]h)}(h``ds->fdb_isolation``h]j)}(hjh]hds->fdb_isolation}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj}ubah}(h]h ]h"]h$]h&]uh1hhhhM6hjyubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhM*hjhhhubh)}(hXSInternally, DSA keeps an array of switch trees (group of switches) global to the kernel, and attaches a ``dsa_switch`` structure to a tree on registration. The tree ID to which the switch is attached is determined by the first u32 number of the ``dsa,member`` property of the switch's OF node (0 if missing). The switch ID within the tree is determined by the second u32 number of the same OF property (0 if missing). Registering multiple switches with the same switch ID and tree ID is illegal and will cause an error. Using platform data, a single switch and a single switch tree is permitted.h](hhInternally, DSA keeps an array of switch trees (group of switches) global to the kernel, and attaches a }(hjhhhNhNubj)}(h``dsa_switch``h]h dsa_switch}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh structure to a tree on registration. The tree ID to which the switch is attached is determined by the first u32 number of the }(hjhhhNhNubj)}(h``dsa,member``h]h dsa,member}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhXR property of the switch’s OF node (0 if missing). The switch ID within the tree is determined by the second u32 number of the same OF property (0 if missing). Registering multiple switches with the same switch ID and tree ID is illegal and will cause an error. Using platform data, a single switch and a single switch tree is permitted.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM8hjhhhubh)}(hX In case of a tree with multiple switches, probing takes place asymmetrically. The first N-1 callers of ``dsa_register_switch()`` only add their ports to the port list of the tree (``dst->ports``), each port having a backpointer to its associated switch (``dp->ds``). Then, these switches exit their ``dsa_register_switch()`` call early, because ``dsa_tree_setup_routing_table()`` has determined that the tree is not yet complete (not all ports referenced by DSA links are present in the tree's port list). The tree becomes complete when the last switch calls ``dsa_register_switch()``, and this triggers the effective continuation of initialization (including the call to ``ds->ops->setup()``) for all switches within that tree, all as part of the calling context of the last switch's probe function.h](hgIn case of a tree with multiple switches, probing takes place asymmetrically. The first N-1 callers of }(hjhhhNhNubj)}(h``dsa_register_switch()``h]hdsa_register_switch()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh4 only add their ports to the port list of the tree (}(hjhhhNhNubj)}(h``dst->ports``h]h dst->ports}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh<), each port having a backpointer to its associated switch (}(hjhhhNhNubj)}(h ``dp->ds``h]hdp->ds}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh#). Then, these switches exit their }(hjhhhNhNubj)}(h``dsa_register_switch()``h]hdsa_register_switch()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh call early, because }(hjhhhNhNubj)}(h"``dsa_tree_setup_routing_table()``h]hdsa_tree_setup_routing_table()}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh has determined that the tree is not yet complete (not all ports referenced by DSA links are present in the tree’s port list). The tree becomes complete when the last switch calls }(hjhhhNhNubj)}(h``dsa_register_switch()``h]hdsa_register_switch()}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX, and this triggers the effective continuation of initialization (including the call to }(hjhhhNhNubj)}(h``ds->ops->setup()``h]hds->ops->setup()}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhn) for all switches within that tree, all as part of the calling context of the last switch’s probe function.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMAhjhhhubh)}(hThe opposite of registration takes place when calling ``dsa_unregister_switch()``, which removes a switch's ports from the port list of the tree. The entire tree is torn down when the first switch unregisters.h](h6The opposite of registration takes place when calling }(hj^hhhNhNubj)}(h``dsa_unregister_switch()``h]hdsa_unregister_switch()}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj^ubh, which removes a switch’s ports from the port list of the tree. The entire tree is torn down when the first switch unregisters.}(hj^hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMMhjhhhubh)}(hXIt is mandatory for DSA switch drivers to implement the ``shutdown()`` callback of their respective bus, and call ``dsa_switch_shutdown()`` from it (a minimal version of the full teardown performed by ``dsa_unregister_switch()``). The reason is that DSA keeps a reference on the conduit net device, and if the driver for the conduit device decides to unbind on shutdown, DSA's reference will block that operation from finalizing.h](h8It is mandatory for DSA switch drivers to implement the }(hj~hhhNhNubj)}(h``shutdown()``h]h shutdown()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ubh, callback of their respective bus, and call }(hj~hhhNhNubj)}(h``dsa_switch_shutdown()``h]hdsa_switch_shutdown()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ubh> from it (a minimal version of the full teardown performed by }(hj~hhhNhNubj)}(h``dsa_unregister_switch()``h]hdsa_unregister_switch()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ubh). The reason is that DSA keeps a reference on the conduit net device, and if the driver for the conduit device decides to unbind on shutdown, DSA’s reference will block that operation from finalizing.}(hj~hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMQhjhhhubh)}(hXEither ``dsa_switch_shutdown()`` or ``dsa_unregister_switch()`` must be called, but not both, and the device driver model permits the bus' ``remove()`` method to be called even if ``shutdown()`` was already called. Therefore, drivers are expected to implement a mutual exclusion method between ``remove()`` and ``shutdown()`` by setting their drvdata to NULL after any of these has run, and checking whether the drvdata is NULL before proceeding to take any action.h](hEither }(hjhhhNhNubj)}(h``dsa_switch_shutdown()``h]hdsa_switch_shutdown()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh or }(hjhhhNhNubj)}(h``dsa_unregister_switch()``h]hdsa_unregister_switch()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhN must be called, but not both, and the device driver model permits the bus’ }(hjhhhNhNubj)}(h ``remove()``h]hremove()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh method to be called even if }(hjhhhNhNubj)}(h``shutdown()``h]h shutdown()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhd was already called. Therefore, drivers are expected to implement a mutual exclusion method between }(hjhhhNhNubj)}(h ``remove()``h]hremove()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and }(hjhhhNhNubj)}(h``shutdown()``h]h shutdown()}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh by setting their drvdata to NULL after any of these has run, and checking whether the drvdata is NULL before proceeding to take any action.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMXhjhhhubh)}(hAfter ``dsa_switch_shutdown()`` or ``dsa_unregister_switch()`` was called, no further callbacks via the provided ``dsa_switch_ops`` may take place, and the driver may free the data structures associated with the ``dsa_switch``.h](hAfter }(hj<hhhNhNubj)}(h``dsa_switch_shutdown()``h]hdsa_switch_shutdown()}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj<ubh or }(hj<hhhNhNubj)}(h``dsa_unregister_switch()``h]hdsa_unregister_switch()}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj<ubh3 was called, no further callbacks via the provided }(hj<hhhNhNubj)}(h``dsa_switch_ops``h]hdsa_switch_ops}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj<ubhQ may take place, and the driver may free the data structures associated with the }(hj<hhhNhNubj)}(h``dsa_switch``h]h dsa_switch}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj<ubh.}(hj<hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM_hjhhhubeh}(h](probing-registration-and-device-lifetimeah ]h"])probing, registration and device lifetimeah$]h&]uh1hhj7hhhhhMubh)}(hhh](h)}(hSwitch configurationh]hSwitch configuration}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMdubjA)}(hhh](jF)}(hX``get_tag_protocol``: this is to indicate what kind of tagging protocol is supported, should be a valid value from the ``dsa_tag_protocol`` enum. The returned information does not have to be static; the driver is passed the CPU port number, as well as the tagging protocol of a possibly stacked upstream switch, in case there are hardware limitations in terms of supported tag formats. h]h)}(hX``get_tag_protocol``: this is to indicate what kind of tagging protocol is supported, should be a valid value from the ``dsa_tag_protocol`` enum. The returned information does not have to be static; the driver is passed the CPU port number, as well as the tagging protocol of a possibly stacked upstream switch, in case there are hardware limitations in terms of supported tag formats.h](j)}(h``get_tag_protocol``h]hget_tag_protocol}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhc: this is to indicate what kind of tagging protocol is supported, should be a valid value from the }(hjhhhNhNubj)}(h``dsa_tag_protocol``h]hdsa_tag_protocol}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh enum. The returned information does not have to be static; the driver is passed the CPU port number, as well as the tagging protocol of a possibly stacked upstream switch, in case there are hardware limitations in terms of supported tag formats.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMfhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX>``change_tag_protocol``: when the default tagging protocol has compatibility problems with the conduit or other issues, the driver may support changing it at runtime, either through a device tree property or through sysfs. In that case, further calls to ``get_tag_protocol`` should report the protocol in current use. h]h)}(hX=``change_tag_protocol``: when the default tagging protocol has compatibility problems with the conduit or other issues, the driver may support changing it at runtime, either through a device tree property or through sysfs. In that case, further calls to ``get_tag_protocol`` should report the protocol in current use.h](j)}(h``change_tag_protocol``h]hchange_tag_protocol}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: when the default tagging protocol has compatibility problems with the conduit or other issues, the driver may support changing it at runtime, either through a device tree property or through sysfs. In that case, further calls to }(hjhhhNhNubj)}(h``get_tag_protocol``h]hget_tag_protocol}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh+ should report the protocol in current use.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMmhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX``setup``: setup function for the switch, this function is responsible for setting up the ``dsa_switch_ops`` private structure with all it needs: register maps, interrupts, mutexes, locks, etc. This function is also expected to properly configure the switch to separate all network interfaces from each other, that is, they should be isolated by the switch hardware itself, typically by creating a Port-based VLAN ID for each port and allowing only the CPU port and the specific port to be in the forwarding vector. Ports that are unused by the platform should be disabled. Past this function, the switch is expected to be fully configured and ready to serve any kind of request. It is recommended to issue a software reset of the switch during this setup function in order to avoid relying on what a previous software agent such as a bootloader/firmware may have previously configured. The method responsible for undoing any applicable allocations or operations done here is ``teardown``. h]h)}(hX``setup``: setup function for the switch, this function is responsible for setting up the ``dsa_switch_ops`` private structure with all it needs: register maps, interrupts, mutexes, locks, etc. This function is also expected to properly configure the switch to separate all network interfaces from each other, that is, they should be isolated by the switch hardware itself, typically by creating a Port-based VLAN ID for each port and allowing only the CPU port and the specific port to be in the forwarding vector. Ports that are unused by the platform should be disabled. Past this function, the switch is expected to be fully configured and ready to serve any kind of request. It is recommended to issue a software reset of the switch during this setup function in order to avoid relying on what a previous software agent such as a bootloader/firmware may have previously configured. The method responsible for undoing any applicable allocations or operations done here is ``teardown``.h](j)}(h ``setup``h]hsetup}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubhQ: setup function for the switch, this function is responsible for setting up the }(hj"hhhNhNubj)}(h``dsa_switch_ops``h]hdsa_switch_ops}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubhXd private structure with all it needs: register maps, interrupts, mutexes, locks, etc. This function is also expected to properly configure the switch to separate all network interfaces from each other, that is, they should be isolated by the switch hardware itself, typically by creating a Port-based VLAN ID for each port and allowing only the CPU port and the specific port to be in the forwarding vector. Ports that are unused by the platform should be disabled. Past this function, the switch is expected to be fully configured and ready to serve any kind of request. It is recommended to issue a software reset of the switch during this setup function in order to avoid relying on what a previous software agent such as a bootloader/firmware may have previously configured. The method responsible for undoing any applicable allocations or operations done here is }(hj"hhhNhNubj)}(h ``teardown``h]hteardown}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh.}(hj"hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMshjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX)``port_setup`` and ``port_teardown``: methods for initialization and destruction of per-port data structures. It is mandatory for some operations such as registering and unregistering devlink port regions to be done from these methods, otherwise they are optional. A port will be torn down only if it has been previously set up. It is possible for a port to be set up during probing only to be torn down immediately afterwards, for example in case its PHY cannot be found. In this case, probing of the DSA switch continues without that particular port. h]h)}(hX(``port_setup`` and ``port_teardown``: methods for initialization and destruction of per-port data structures. It is mandatory for some operations such as registering and unregistering devlink port regions to be done from these methods, otherwise they are optional. A port will be torn down only if it has been previously set up. It is possible for a port to be set up during probing only to be torn down immediately afterwards, for example in case its PHY cannot be found. In this case, probing of the DSA switch continues without that particular port.h](j)}(h``port_setup``h]h port_setup}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubh and }(hjlhhhNhNubj)}(h``port_teardown``h]h port_teardown}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubhX: methods for initialization and destruction of per-port data structures. It is mandatory for some operations such as registering and unregistering devlink port regions to be done from these methods, otherwise they are optional. A port will be torn down only if it has been previously set up. It is possible for a port to be set up during probing only to be torn down immediately afterwards, for example in case its PHY cannot be found. In this case, probing of the DSA switch continues without that particular port.}(hjlhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX``port_change_conduit``: method through which the affinity (association used for traffic termination purposes) between a user port and a CPU port can be changed. By default all user ports from a tree are assigned to the first available CPU port that makes sense for them (most of the times this means the user ports of a tree are all assigned to the same CPU port, except for H topologies as described in commit 2c0b03258b8b). The ``port`` argument represents the index of the user port, and the ``conduit`` argument represents the new DSA conduit ``net_device``. The CPU port associated with the new conduit can be retrieved by looking at ``struct dsa_port *cpu_dp = conduit->dsa_ptr``. Additionally, the conduit can also be a LAG device where all the slave devices are physical DSA conduits. LAG DSA also have a valid ``conduit->dsa_ptr`` pointer, however this is not unique, but rather a duplicate of the first physical DSA conduit's (LAG slave) ``dsa_ptr``. In case of a LAG DSA conduit, a further call to ``port_lag_join`` will be emitted separately for the physical CPU ports associated with the physical DSA conduits, requesting them to create a hardware LAG associated with the LAG interface. h]h)}(hX``port_change_conduit``: method through which the affinity (association used for traffic termination purposes) between a user port and a CPU port can be changed. By default all user ports from a tree are assigned to the first available CPU port that makes sense for them (most of the times this means the user ports of a tree are all assigned to the same CPU port, except for H topologies as described in commit 2c0b03258b8b). The ``port`` argument represents the index of the user port, and the ``conduit`` argument represents the new DSA conduit ``net_device``. The CPU port associated with the new conduit can be retrieved by looking at ``struct dsa_port *cpu_dp = conduit->dsa_ptr``. Additionally, the conduit can also be a LAG device where all the slave devices are physical DSA conduits. LAG DSA also have a valid ``conduit->dsa_ptr`` pointer, however this is not unique, but rather a duplicate of the first physical DSA conduit's (LAG slave) ``dsa_ptr``. In case of a LAG DSA conduit, a further call to ``port_lag_join`` will be emitted separately for the physical CPU ports associated with the physical DSA conduits, requesting them to create a hardware LAG associated with the LAG interface.h](j)}(h``port_change_conduit``h]hport_change_conduit}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX: method through which the affinity (association used for traffic termination purposes) between a user port and a CPU port can be changed. By default all user ports from a tree are assigned to the first available CPU port that makes sense for them (most of the times this means the user ports of a tree are all assigned to the same CPU port, except for H topologies as described in commit 2c0b03258b8b). The }(hjhhhNhNubj)}(h``port``h]hport}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh9 argument represents the index of the user port, and the }(hjhhhNhNubj)}(h ``conduit``h]hconduit}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh) argument represents the new DSA conduit }(hjhhhNhNubj)}(h``net_device``h]h net_device}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhN. The CPU port associated with the new conduit can be retrieved by looking at }(hjhhhNhNubj)}(h.``struct dsa_port *cpu_dp = conduit->dsa_ptr``h]h*struct dsa_port *cpu_dp = conduit->dsa_ptr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. Additionally, the conduit can also be a LAG device where all the slave devices are physical DSA conduits. LAG DSA also have a valid }(hjhhhNhNubj)}(h``conduit->dsa_ptr``h]hconduit->dsa_ptr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubho pointer, however this is not unique, but rather a duplicate of the first physical DSA conduit’s (LAG slave) }(hjhhhNhNubj)}(h ``dsa_ptr``h]hdsa_ptr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh2. In case of a LAG DSA conduit, a further call to }(hjhhhNhNubj)}(h``port_lag_join``h]h port_lag_join}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh will be emitted separately for the physical CPU ports associated with the physical DSA conduits, requesting them to create a hardware LAG associated with the LAG interface.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMfhjhhubeh}(h]switch-configurationah ]h"]switch configurationah$]h&]uh1hhj7hhhhhMdubh)}(hhh](h)}(hPHY devices and link managementh]hPHY devices and link management}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjRhhhhhMubjA)}(hhh](jF)}(hXz``get_phy_flags``: Some switches are interfaced to various kinds of Ethernet PHYs, if the PHY library PHY driver needs to know about information it cannot obtain on its own (e.g.: coming from switch memory mapped registers), this function should return a 32-bit bitmask of "flags" that is private between the switch driver and the Ethernet PHY driver in ``drivers/net/phy/\*``. h]h)}(hXy``get_phy_flags``: Some switches are interfaced to various kinds of Ethernet PHYs, if the PHY library PHY driver needs to know about information it cannot obtain on its own (e.g.: coming from switch memory mapped registers), this function should return a 32-bit bitmask of "flags" that is private between the switch driver and the Ethernet PHY driver in ``drivers/net/phy/\*``.h](j)}(h``get_phy_flags``h]h get_phy_flags}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjjubhXU: Some switches are interfaced to various kinds of Ethernet PHYs, if the PHY library PHY driver needs to know about information it cannot obtain on its own (e.g.: coming from switch memory mapped registers), this function should return a 32-bit bitmask of “flags” that is private between the switch driver and the Ethernet PHY driver in }(hjjhhhNhNubj)}(h``drivers/net/phy/\*``h]hdrivers/net/phy/\*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjjubh.}(hjjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjfubah}(h]h ]h"]h$]h&]uh1jEhjchhhhhNubjF)}(hX&``phy_read``: Function invoked by the DSA user MDIO bus when attempting to read the switch port MDIO registers. If unavailable, return 0xffff for each read. For builtin switch Ethernet PHYs, this function should allow reading the link status, auto-negotiation results, link partner pages, etc. h]h)}(hX%``phy_read``: Function invoked by the DSA user MDIO bus when attempting to read the switch port MDIO registers. If unavailable, return 0xffff for each read. For builtin switch Ethernet PHYs, this function should allow reading the link status, auto-negotiation results, link partner pages, etc.h](j)}(h ``phy_read``h]hphy_read}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX: Function invoked by the DSA user MDIO bus when attempting to read the switch port MDIO registers. If unavailable, return 0xffff for each read. For builtin switch Ethernet PHYs, this function should allow reading the link status, auto-negotiation results, link partner pages, etc.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjchhhhhNubjF)}(h``phy_write``: Function invoked by the DSA user MDIO bus when attempting to write to the switch port MDIO registers. If unavailable return a negative error code. h]h)}(h``phy_write``: Function invoked by the DSA user MDIO bus when attempting to write to the switch port MDIO registers. If unavailable return a negative error code.h](j)}(h ``phy_write``h]h phy_write}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: Function invoked by the DSA user MDIO bus when attempting to write to the switch port MDIO registers. If unavailable return a negative error code.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjchhhhhNubjF)}(hX ``adjust_link``: Function invoked by the PHY library when a user network device is attached to a PHY device. This function is responsible for appropriately configuring the switch port link parameters: speed, duplex, pause based on what the ``phy_device`` is providing. h]h)}(hX ``adjust_link``: Function invoked by the PHY library when a user network device is attached to a PHY device. This function is responsible for appropriately configuring the switch port link parameters: speed, duplex, pause based on what the ``phy_device`` is providing.h](j)}(h``adjust_link``h]h adjust_link}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: Function invoked by the PHY library when a user network device is attached to a PHY device. This function is responsible for appropriately configuring the switch port link parameters: speed, duplex, pause based on what the }(hjhhhNhNubj)}(h``phy_device``h]h phy_device}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is providing.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjchhhhhNubjF)}(hX``fixed_link_update``: Function invoked by the PHY library, and specifically by the fixed PHY driver asking the switch driver for link parameters that could not be auto-negotiated, or obtained by reading the PHY registers through MDIO. This is particularly useful for specific kinds of hardware such as QSGMII, MoCA or other kinds of non-MDIO managed PHYs where out of band link information is obtained h]h)}(hX``fixed_link_update``: Function invoked by the PHY library, and specifically by the fixed PHY driver asking the switch driver for link parameters that could not be auto-negotiated, or obtained by reading the PHY registers through MDIO. This is particularly useful for specific kinds of hardware such as QSGMII, MoCA or other kinds of non-MDIO managed PHYs where out of band link information is obtainedh](j)}(h``fixed_link_update``h]hfixed_link_update}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj&ubhX}: Function invoked by the PHY library, and specifically by the fixed PHY driver asking the switch driver for link parameters that could not be auto-negotiated, or obtained by reading the PHY registers through MDIO. This is particularly useful for specific kinds of hardware such as QSGMII, MoCA or other kinds of non-MDIO managed PHYs where out of band link information is obtained}(hj&hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj"ubah}(h]h ]h"]h$]h&]uh1jEhjchhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhjRhhubeh}(h]phy-devices-and-link-managementah ]h"]phy devices and link managementah$]h&]uh1hhj7hhhhhMubh)}(hhh](h)}(hEthtool operationsh]hEthtool operations}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjVhhhhhMubjA)}(hhh](jF)}(h``get_strings``: ethtool function used to query the driver's strings, will typically return statistics strings, private flags strings, etc. h]h)}(h``get_strings``: ethtool function used to query the driver's strings, will typically return statistics strings, private flags strings, etc.h](j)}(h``get_strings``h]h get_strings}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjnubh~: ethtool function used to query the driver’s strings, will typically return statistics strings, private flags strings, etc.}(hjnhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjjubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(h``get_ethtool_stats``: ethtool function used to query per-port statistics and return their values. DSA overlays user network devices general statistics: RX/TX counters from the network device, with switch driver specific statistics per port h]h)}(h``get_ethtool_stats``: ethtool function used to query per-port statistics and return their values. DSA overlays user network devices general statistics: RX/TX counters from the network device, with switch driver specific statistics per porth](j)}(h``get_ethtool_stats``h]hget_ethtool_stats}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: ethtool function used to query per-port statistics and return their values. DSA overlays user network devices general statistics: RX/TX counters from the network device, with switch driver specific statistics per port}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(hR``get_sset_count``: ethtool function used to query the number of statistics items h]h)}(hQ``get_sset_count``: ethtool function used to query the number of statistics itemsh](j)}(h``get_sset_count``h]hget_sset_count}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh?: ethtool function used to query the number of statistics items}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(h``get_wol``: ethtool function used to obtain Wake-on-LAN settings per-port, this function may for certain implementations also query the conduit network device Wake-on-LAN settings if this interface needs to participate in Wake-on-LAN h]h)}(h``get_wol``: ethtool function used to obtain Wake-on-LAN settings per-port, this function may for certain implementations also query the conduit network device Wake-on-LAN settings if this interface needs to participate in Wake-on-LANh](j)}(h ``get_wol``h]hget_wol}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: ethtool function used to obtain Wake-on-LAN settings per-port, this function may for certain implementations also query the conduit network device Wake-on-LAN settings if this interface needs to participate in Wake-on-LAN}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(h``set_wol``: ethtool function used to configure Wake-on-LAN settings per-port, direct counterpart to set_wol with similar restrictions h]h)}(h``set_wol``: ethtool function used to configure Wake-on-LAN settings per-port, direct counterpart to set_wol with similar restrictionsh](j)}(h ``set_wol``h]hset_wol}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh{: ethtool function used to configure Wake-on-LAN settings per-port, direct counterpart to set_wol with similar restrictions}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(hX``set_eee``: ethtool function which is used to configure a switch port EEE (Green Ethernet) settings, can optionally invoke the PHY library to enable EEE at the PHY level if relevant. This function should enable EEE at the switch port MAC controller and data-processing logic h]h)}(hX``set_eee``: ethtool function which is used to configure a switch port EEE (Green Ethernet) settings, can optionally invoke the PHY library to enable EEE at the PHY level if relevant. This function should enable EEE at the switch port MAC controller and data-processing logich](j)}(h ``set_eee``h]hset_eee}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj,ubhX: ethtool function which is used to configure a switch port EEE (Green Ethernet) settings, can optionally invoke the PHY library to enable EEE at the PHY level if relevant. This function should enable EEE at the switch port MAC controller and data-processing logic}(hj,hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj(ubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(h``get_eee``: ethtool function which is used to query a switch port EEE settings, this function should return the EEE state of the switch port MAC controller and data-processing logic as well as query the PHY for its currently configured EEE settings h]h)}(h``get_eee``: ethtool function which is used to query a switch port EEE settings, this function should return the EEE state of the switch port MAC controller and data-processing logic as well as query the PHY for its currently configured EEE settingsh](j)}(h ``get_eee``h]hget_eee}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRubh: ethtool function which is used to query a switch port EEE settings, this function should return the EEE state of the switch port MAC controller and data-processing logic as well as query the PHY for its currently configured EEE settings}(hjRhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjNubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(hb``get_eeprom_len``: ethtool function returning for a given switch the EEPROM length/size in bytes h]h)}(ha``get_eeprom_len``: ethtool function returning for a given switch the EEPROM length/size in bytesh](j)}(h``get_eeprom_len``h]hget_eeprom_len}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjxubhO: ethtool function returning for a given switch the EEPROM length/size in bytes}(hjxhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjtubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(hR``get_eeprom``: ethtool function returning for a given switch the EEPROM contents h]h)}(hQ``get_eeprom``: ethtool function returning for a given switch the EEPROM contentsh](j)}(h``get_eeprom``h]h get_eeprom}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhC: ethtool function returning for a given switch the EEPROM contents}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(hQ``set_eeprom``: ethtool function writing specified data to a given switch EEPROM h]h)}(hP``set_eeprom``: ethtool function writing specified data to a given switch EEPROMh](j)}(h``set_eeprom``h]h set_eeprom}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhB: ethtool function writing specified data to a given switch EEPROM}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(hT``get_regs_len``: ethtool function returning the register length for a given switch h]h)}(hS``get_regs_len``: ethtool function returning the register length for a given switchh](j)}(h``get_regs_len``h]h get_regs_len}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhC: ethtool function returning the register length for a given switch}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubjF)}(h``get_regs``: ethtool function returning the Ethernet switch internal register contents. This function might require user-land code in ethtool to pretty-print register values and registers h]h)}(h``get_regs``: ethtool function returning the Ethernet switch internal register contents. This function might require user-land code in ethtool to pretty-print register values and registersh](j)}(h ``get_regs``h]hget_regs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: ethtool function returning the Ethernet switch internal register contents. This function might require user-land code in ethtool to pretty-print register values and registers}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhjghhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhjVhhubeh}(h]ethtool-operationsah ]h"]ethtool operationsah$]h&]uh1hhj7hhhhhMubh)}(hhh](h)}(hPower managementh]hPower management}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhj@hhhhhMubjA)}(hhh](jF)}(h``suspend``: function invoked by the DSA platform device when the system goes to suspend, should quiesce all Ethernet switch activities, but keep ports participating in Wake-on-LAN active as well as additional wake-up logic if supported h]h)}(h``suspend``: function invoked by the DSA platform device when the system goes to suspend, should quiesce all Ethernet switch activities, but keep ports participating in Wake-on-LAN active as well as additional wake-up logic if supportedh](j)}(h ``suspend``h]hsuspend}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjXubh: function invoked by the DSA platform device when the system goes to suspend, should quiesce all Ethernet switch activities, but keep ports participating in Wake-on-LAN active as well as additional wake-up logic if supported}(hjXhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjTubah}(h]h ]h"]h$]h&]uh1jEhjQhhhhhNubjF)}(h``resume``: function invoked by the DSA platform device when the system resumes, should resume all Ethernet switch activities and re-configure the switch to be in a fully active state h]h)}(h``resume``: function invoked by the DSA platform device when the system resumes, should resume all Ethernet switch activities and re-configure the switch to be in a fully active stateh](j)}(h ``resume``h]hresume}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ubh: function invoked by the DSA platform device when the system resumes, should resume all Ethernet switch activities and re-configure the switch to be in a fully active state}(hj~hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjzubah}(h]h ]h"]h$]h&]uh1jEhjQhhhhhNubjF)}(hXq``port_enable``: function invoked by the DSA user network device ndo_open function when a port is administratively brought up, this function should fully enable a given switch port. DSA takes care of marking the port with ``BR_STATE_BLOCKING`` if the port is a bridge member, or ``BR_STATE_FORWARDING`` if it was not, and propagating these changes down to the hardware h]h)}(hXp``port_enable``: function invoked by the DSA user network device ndo_open function when a port is administratively brought up, this function should fully enable a given switch port. DSA takes care of marking the port with ``BR_STATE_BLOCKING`` if the port is a bridge member, or ``BR_STATE_FORWARDING`` if it was not, and propagating these changes down to the hardwareh](j)}(h``port_enable``h]h port_enable}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: function invoked by the DSA user network device ndo_open function when a port is administratively brought up, this function should fully enable a given switch port. DSA takes care of marking the port with }(hjhhhNhNubj)}(h``BR_STATE_BLOCKING``h]hBR_STATE_BLOCKING}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh$ if the port is a bridge member, or }(hjhhhNhNubj)}(h``BR_STATE_FORWARDING``h]hBR_STATE_FORWARDING}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhB if it was not, and propagating these changes down to the hardware}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjQhhhhhNubjF)}(hXV``port_disable``: function invoked by the DSA user network device ndo_close function when a port is administratively brought down, this function should fully disable a given switch port. DSA takes care of marking the port with ``BR_STATE_DISABLED`` and propagating changes to the hardware if this port is disabled while being a bridge member h]h)}(hXU``port_disable``: function invoked by the DSA user network device ndo_close function when a port is administratively brought down, this function should fully disable a given switch port. DSA takes care of marking the port with ``BR_STATE_DISABLED`` and propagating changes to the hardware if this port is disabled while being a bridge memberh](j)}(h``port_disable``h]h port_disable}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: function invoked by the DSA user network device ndo_close function when a port is administratively brought down, this function should fully disable a given switch port. DSA takes care of marking the port with }(hjhhhNhNubj)}(h``BR_STATE_DISABLED``h]hBR_STATE_DISABLED}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh] and propagating changes to the hardware if this port is disabled while being a bridge member}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjQhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhj@hhubeh}(h]power-managementah ]h"]power managementah$]h&]uh1hhj7hhhhhMubh)}(hhh](h)}(hAddress databasesh]hAddress databases}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj0hhhhhMubh)}(hXSwitching hardware is expected to have a table for FDB entries, however not all of them are active at the same time. An address database is the subset (partition) of FDB entries that is active (can be matched by address learning on RX, or FDB lookup on TX) depending on the state of the port. An address database may occasionally be called "FID" (Filtering ID) in this document, although the underlying implementation may choose whatever is available to the hardware.h]hXSwitching hardware is expected to have a table for FDB entries, however not all of them are active at the same time. An address database is the subset (partition) of FDB entries that is active (can be matched by address learning on RX, or FDB lookup on TX) depending on the state of the port. An address database may occasionally be called “FID” (Filtering ID) in this document, although the underlying implementation may choose whatever is available to the hardware.}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj0hhubh)}(hXFor example, all ports that belong to a VLAN-unaware bridge (which is *currently* VLAN-unaware) are expected to learn source addresses in the database associated by the driver with that bridge (and not with other VLAN-unaware bridges). During forwarding and FDB lookup, a packet received on a VLAN-unaware bridge port should be able to find a VLAN-unaware FDB entry having the same MAC DA as the packet, which is present on another port member of the same bridge. At the same time, the FDB lookup process must be able to not find an FDB entry having the same MAC DA as the packet, if that entry points towards a port which is a member of a different VLAN-unaware bridge (and is therefore associated with a different address database).h](hFFor example, all ports that belong to a VLAN-unaware bridge (which is }(hjOhhhNhNubhemphasis)}(h *currently*h]h currently}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jWhjOubhX VLAN-unaware) are expected to learn source addresses in the database associated by the driver with that bridge (and not with other VLAN-unaware bridges). During forwarding and FDB lookup, a packet received on a VLAN-unaware bridge port should be able to find a VLAN-unaware FDB entry having the same MAC DA as the packet, which is present on another port member of the same bridge. At the same time, the FDB lookup process must be able to not find an FDB entry having the same MAC DA as the packet, if that entry points towards a port which is a member of a different VLAN-unaware bridge (and is therefore associated with a different address database).}(hjOhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj0hhubh)}(hSimilarly, each VLAN of each offloaded VLAN-aware bridge should have an associated address database, which is shared by all ports which are members of that VLAN, but not shared by ports belonging to different bridges that are members of the same VID.h]hSimilarly, each VLAN of each offloaded VLAN-aware bridge should have an associated address database, which is shared by all ports which are members of that VLAN, but not shared by ports belonging to different bridges that are members of the same VID.}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj0hhubh)}(hX'In this context, a VLAN-unaware database means that all packets are expected to match on it irrespective of VLAN ID (only MAC address lookup), whereas a VLAN-aware database means that packets are supposed to match based on the VLAN ID from the classified 802.1Q header (or the pvid if untagged).h]hX'In this context, a VLAN-unaware database means that all packets are expected to match on it irrespective of VLAN ID (only MAC address lookup), whereas a VLAN-aware database means that packets are supposed to match based on the VLAN ID from the classified 802.1Q header (or the pvid if untagged).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj0hhubh)}(hXAt the bridge layer, VLAN-unaware FDB entries have the special VID value of 0, whereas VLAN-aware FDB entries have non-zero VID values. Note that a VLAN-unaware bridge may have VLAN-aware (non-zero VID) FDB entries, and a VLAN-aware bridge may have VLAN-unaware FDB entries. As in hardware, the software bridge keeps separate address databases, and offloads to hardware the FDB entries belonging to these databases, through switchdev, asynchronously relative to the moment when the databases become active or inactive.h]hXAt the bridge layer, VLAN-unaware FDB entries have the special VID value of 0, whereas VLAN-aware FDB entries have non-zero VID values. Note that a VLAN-unaware bridge may have VLAN-aware (non-zero VID) FDB entries, and a VLAN-aware bridge may have VLAN-unaware FDB entries. As in hardware, the software bridge keeps separate address databases, and offloads to hardware the FDB entries belonging to these databases, through switchdev, asynchronously relative to the moment when the databases become active or inactive.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj0hhubh)}(hXWhen a user port operates in standalone mode, its driver should configure it to use a separate database called a port private database. This is different from the databases described above, and should impede operation as standalone port (packet in, packet out to the CPU port) as little as possible. For example, on ingress, it should not attempt to learn the MAC SA of ingress traffic, since learning is a bridging layer service and this is a standalone port, therefore it would consume useless space. With no address learning, the port private database should be empty in a naive implementation, and in this case, all received packets should be trivially flooded to the CPU port.h]hXWhen a user port operates in standalone mode, its driver should configure it to use a separate database called a port private database. This is different from the databases described above, and should impede operation as standalone port (packet in, packet out to the CPU port) as little as possible. For example, on ingress, it should not attempt to learn the MAC SA of ingress traffic, since learning is a bridging layer service and this is a standalone port, therefore it would consume useless space. With no address learning, the port private database should be empty in a naive implementation, and in this case, all received packets should be trivially flooded to the CPU port.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hj0hhubh)}(hXDSA (cascade) and CPU ports are also called "shared" ports because they service multiple address databases, and the database that a packet should be associated to is usually embedded in the DSA tag. This means that the CPU port may simultaneously transport packets coming from a standalone port (which were classified by hardware in one address database), and from a bridge port (which were classified to a different address database).h]hXDSA (cascade) and CPU ports are also called “shared” ports because they service multiple address databases, and the database that a packet should be associated to is usually embedded in the DSA tag. This means that the CPU port may simultaneously transport packets coming from a standalone port (which were classified by hardware in one address database), and from a bridge port (which were classified to a different address database).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM/hj0hhubh)}(hXSwitch drivers which satisfy certain criteria are able to optimize the naive configuration by removing the CPU port from the flooding domain of the switch, and just program the hardware with FDB entries pointing towards the CPU port for which it is known that software is interested in those MAC addresses. Packets which do not match a known FDB entry will not be delivered to the CPU, which will save CPU cycles required for creating an skb just to drop it.h]hXSwitch drivers which satisfy certain criteria are able to optimize the naive configuration by removing the CPU port from the flooding domain of the switch, and just program the hardware with FDB entries pointing towards the CPU port for which it is known that software is interested in those MAC addresses. Packets which do not match a known FDB entry will not be delivered to the CPU, which will save CPU cycles required for creating an skb just to drop it.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM6hj0hhubh)}(hSDSA is able to perform host address filtering for the following kinds of addresses:h]hSDSA is able to perform host address filtering for the following kinds of addresses:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM=hj0hhubjA)}(hhh](jF)}(hPrimary unicast MAC addresses of ports (``dev->dev_addr``). These are associated with the port private database of the respective user port, and the driver is notified to install them through ``port_fdb_add`` towards the CPU port. h]h)}(hPrimary unicast MAC addresses of ports (``dev->dev_addr``). These are associated with the port private database of the respective user port, and the driver is notified to install them through ``port_fdb_add`` towards the CPU port.h](h(Primary unicast MAC addresses of ports (}(hjhhhNhNubj)}(h``dev->dev_addr``h]h dev->dev_addr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh). These are associated with the port private database of the respective user port, and the driver is notified to install them through }(hjhhhNhNubj)}(h``port_fdb_add``h]h port_fdb_add}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh towards the CPU port.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM@hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hSecondary unicast and multicast MAC addresses of ports (addresses added through ``dev_uc_add()`` and ``dev_mc_add()``). These are also associated with the port private database of the respective user port. h]h)}(hSecondary unicast and multicast MAC addresses of ports (addresses added through ``dev_uc_add()`` and ``dev_mc_add()``). These are also associated with the port private database of the respective user port.h](hPSecondary unicast and multicast MAC addresses of ports (addresses added through }(hjhhhNhNubj)}(h``dev_uc_add()``h]h dev_uc_add()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and }(hjhhhNhNubj)}(h``dev_mc_add()``h]h dev_mc_add()}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX). These are also associated with the port private database of the respective user port.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMEhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hLocal/permanent bridge FDB entries (``BR_FDB_LOCAL``). These are the MAC addresses of the bridge ports, for which packets must be terminated locally and not forwarded. They are associated with the address database for that bridge. h]h)}(hLocal/permanent bridge FDB entries (``BR_FDB_LOCAL``). These are the MAC addresses of the bridge ports, for which packets must be terminated locally and not forwarded. They are associated with the address database for that bridge.h](h$Local/permanent bridge FDB entries (}(hjRhhhNhNubj)}(h``BR_FDB_LOCAL``h]h BR_FDB_LOCAL}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjRubh). These are the MAC addresses of the bridge ports, for which packets must be terminated locally and not forwarded. They are associated with the address database for that bridge.}(hjRhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMIhjNubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hStatic bridge FDB entries installed towards foreign (non-DSA) interfaces present in the same bridge as some DSA switch ports. These are also associated with the address database for that bridge. h]h)}(hStatic bridge FDB entries installed towards foreign (non-DSA) interfaces present in the same bridge as some DSA switch ports. These are also associated with the address database for that bridge.h]hStatic bridge FDB entries installed towards foreign (non-DSA) interfaces present in the same bridge as some DSA switch ports. These are also associated with the address database for that bridge.}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMNhjxubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hDynamically learned FDB entries on foreign interfaces present in the same bridge as some DSA switch ports, only if ``ds->assisted_learning_on_cpu_port`` is set to true by the driver. These are associated with the address database for that bridge. h]h)}(hDynamically learned FDB entries on foreign interfaces present in the same bridge as some DSA switch ports, only if ``ds->assisted_learning_on_cpu_port`` is set to true by the driver. These are associated with the address database for that bridge.h](hsDynamically learned FDB entries on foreign interfaces present in the same bridge as some DSA switch ports, only if }(hjhhhNhNubj)}(h%``ds->assisted_learning_on_cpu_port``h]h!ds->assisted_learning_on_cpu_port}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh^ is set to true by the driver. These are associated with the address database for that bridge.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMRhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhM@hj0hhubh)}(hoFor various operations detailed below, DSA provides a ``dsa_db`` structure which can be of the following types:h](h6For various operations detailed below, DSA provides a }(hjhhhNhNubj)}(h ``dsa_db``h]hdsa_db}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh/ structure which can be of the following types:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMWhj0hhubjA)}(hhh](jF)}(h``DSA_DB_PORT``: the FDB (or MDB) entry to be installed or deleted belongs to the port private database of user port ``db->dp``.h]h)}(h``DSA_DB_PORT``: the FDB (or MDB) entry to be installed or deleted belongs to the port private database of user port ``db->dp``.h](j)}(h``DSA_DB_PORT``h]h DSA_DB_PORT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhf: the FDB (or MDB) entry to be installed or deleted belongs to the port private database of user port }(hjhhhNhNubj)}(h ``db->dp``h]hdb->dp}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMZhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h``DSA_DB_BRIDGE``: the entry belongs to one of the address databases of bridge ``db->bridge``. Separation between the VLAN-unaware database and the per-VID databases of this bridge is expected to be done by the driver.h]h)}(h``DSA_DB_BRIDGE``: the entry belongs to one of the address databases of bridge ``db->bridge``. Separation between the VLAN-unaware database and the per-VID databases of this bridge is expected to be done by the driver.h](j)}(h``DSA_DB_BRIDGE``h]h DSA_DB_BRIDGE}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh>: the entry belongs to one of the address databases of bridge }(hjhhhNhNubj)}(h``db->bridge``h]h db->bridge}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh}. Separation between the VLAN-unaware database and the per-VID databases of this bridge is expected to be done by the driver.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM\hjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h``DSA_DB_LAG``: the entry belongs to the address database of LAG ``db->lag``. Note: ``DSA_DB_LAG`` is currently unused and may be removed in the future. h]h)}(h``DSA_DB_LAG``: the entry belongs to the address database of LAG ``db->lag``. Note: ``DSA_DB_LAG`` is currently unused and may be removed in the future.h](j)}(h``DSA_DB_LAG``h]h DSA_DB_LAG}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjWubh3: the entry belongs to the address database of LAG }(hjWhhhNhNubj)}(h ``db->lag``h]hdb->lag}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjWubh. Note: }(hjWhhhNhNubj)}(h``DSA_DB_LAG``h]h DSA_DB_LAG}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjWubh6 is currently unused and may be removed in the future.}(hjWhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM_hjSubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMZhj0hhubh)}(hThe drivers which act upon the ``dsa_db`` argument in ``port_fdb_add``, ``port_mdb_add`` etc should declare ``ds->fdb_isolation`` as true.h](hThe drivers which act upon the }(hjhhhNhNubj)}(h ``dsa_db``h]hdsa_db}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh argument in }(hjhhhNhNubj)}(h``port_fdb_add``h]h port_fdb_add}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h``port_mdb_add``h]h port_mdb_add}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh etc should declare }(hjhhhNhNubj)}(h``ds->fdb_isolation``h]hds->fdb_isolation}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh as true.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMbhj0hhubh)}(hXQDSA associates each offloaded bridge and each offloaded LAG with a one-based ID (``struct dsa_bridge :: num``, ``struct dsa_lag :: id``) for the purposes of refcounting addresses on shared ports. Drivers may piggyback on DSA's numbering scheme (the ID is readable through ``db->bridge.num`` and ``db->lag.id`` or may implement their own.h](hQDSA associates each offloaded bridge and each offloaded LAG with a one-based ID (}(hjhhhNhNubj)}(h``struct dsa_bridge :: num``h]hstruct dsa_bridge :: num}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h``struct dsa_lag :: id``h]hstruct dsa_lag :: id}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh) for the purposes of refcounting addresses on shared ports. Drivers may piggyback on DSA’s numbering scheme (the ID is readable through }(hjhhhNhNubj)}(h``db->bridge.num``h]hdb->bridge.num}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and }(hjhhhNhNubj)}(h``db->lag.id``h]h db->lag.id}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh or may implement their own.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMehj0hhubh)}(hXOnly the drivers which declare support for FDB isolation are notified of FDB entries on the CPU port belonging to ``DSA_DB_PORT`` databases. For compatibility/legacy reasons, ``DSA_DB_BRIDGE`` addresses are notified to drivers even if they do not support FDB isolation. However, ``db->bridge.num`` and ``db->lag.id`` are always set to 0 in that case (to denote the lack of isolation, for refcounting purposes).h](hrOnly the drivers which declare support for FDB isolation are notified of FDB entries on the CPU port belonging to }(hjOhhhNhNubj)}(h``DSA_DB_PORT``h]h DSA_DB_PORT}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjOubh. databases. For compatibility/legacy reasons, }(hjOhhhNhNubj)}(h``DSA_DB_BRIDGE``h]h DSA_DB_BRIDGE}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1jhjOubhW addresses are notified to drivers even if they do not support FDB isolation. However, }(hjOhhhNhNubj)}(h``db->bridge.num``h]hdb->bridge.num}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjOubh and }(hjOhhhNhNubj)}(h``db->lag.id``h]h db->lag.id}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjOubh^ are always set to 0 in that case (to denote the lack of isolation, for refcounting purposes).}(hjOhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMkhj0hhubh)}(hXNote that it is not mandatory for a switch driver to implement physically separate address databases for each standalone user port. Since FDB entries in the port private databases will always point to the CPU port, there is no risk for incorrect forwarding decisions. In this case, all standalone ports may share the same database, but the reference counting of host-filtered addresses (not deleting the FDB entry for a port's MAC address if it's still in use by another port) becomes the responsibility of the driver, because DSA is unaware that the port databases are in fact shared. This can be achieved by calling ``dsa_fdb_present_in_other_db()`` and ``dsa_mdb_present_in_other_db()``. The down side is that the RX filtering lists of each user port are in fact shared, which means that user port A may accept a packet with a MAC DA it shouldn't have, only because that MAC address was in the RX filtering list of user port B. These packets will still be dropped in software, however.h](hXnNote that it is not mandatory for a switch driver to implement physically separate address databases for each standalone user port. Since FDB entries in the port private databases will always point to the CPU port, there is no risk for incorrect forwarding decisions. In this case, all standalone ports may share the same database, but the reference counting of host-filtered addresses (not deleting the FDB entry for a port’s MAC address if it’s still in use by another port) becomes the responsibility of the driver, because DSA is unaware that the port databases are in fact shared. This can be achieved by calling }(hjhhhNhNubj)}(h!``dsa_fdb_present_in_other_db()``h]hdsa_fdb_present_in_other_db()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and }(hjhhhNhNubj)}(h!``dsa_mdb_present_in_other_db()``h]hdsa_mdb_present_in_other_db()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX-. The down side is that the RX filtering lists of each user port are in fact shared, which means that user port A may accept a packet with a MAC DA it shouldn’t have, only because that MAC address was in the RX filtering list of user port B. These packets will still be dropped in software, however.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMrhj0hhubeh}(h]address-databasesah ]h"]address databasesah$]h&]uh1hhj7hhhhhMubh)}(hhh](h)}(h Bridge layerh]h Bridge layer}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hXOffloading the bridge forwarding plane is optional and handled by the methods below. They may be absent, return -EOPNOTSUPP, or ``ds->max_num_bridges`` may be non-zero and exceeded, and in this case, joining a bridge port is still possible, but the packet forwarding will take place in software, and the ports under a software bridge must remain configured in the same way as for standalone operation, i.e. have all bridging service functions (address learning etc) disabled, and send all received packets to the CPU port only.h](hOffloading the bridge forwarding plane is optional and handled by the methods below. They may be absent, return -EOPNOTSUPP, or }(hjhhhNhNubj)}(h``ds->max_num_bridges``h]hds->max_num_bridges}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhXx may be non-zero and exceeded, and in this case, joining a bridge port is still possible, but the packet forwarding will take place in software, and the ports under a software bridge must remain configured in the same way as for standalone operation, i.e. have all bridging service functions (address learning etc) disabled, and send all received packets to the CPU port only.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXCConcretely, a port starts offloading the forwarding plane of a bridge once it returns success to the ``port_bridge_join`` method, and stops doing so after ``port_bridge_leave`` has been called. Offloading the bridge means autonomously learning FDB entries in accordance with the software bridge port's state, and autonomously forwarding (or flooding) received packets without CPU intervention. This is optional even when offloading a bridge port. Tagging protocol drivers are expected to call ``dsa_default_offload_fwd_mark(skb)`` for packets which have already been autonomously forwarded in the forwarding domain of the ingress switch port. DSA, through ``dsa_port_devlink_setup()``, considers all switch ports part of the same tree ID to be part of the same bridge forwarding domain (capable of autonomous forwarding to each other).h](heConcretely, a port starts offloading the forwarding plane of a bridge once it returns success to the }(hjhhhNhNubj)}(h``port_bridge_join``h]hport_bridge_join}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh" method, and stops doing so after }(hjhhhNhNubj)}(h``port_bridge_leave``h]hport_bridge_leave}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX? has been called. Offloading the bridge means autonomously learning FDB entries in accordance with the software bridge port’s state, and autonomously forwarding (or flooding) received packets without CPU intervention. This is optional even when offloading a bridge port. Tagging protocol drivers are expected to call }(hjhhhNhNubj)}(h%``dsa_default_offload_fwd_mark(skb)``h]h!dsa_default_offload_fwd_mark(skb)}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh~ for packets which have already been autonomously forwarded in the forwarding domain of the ingress switch port. DSA, through }(hjhhhNhNubj)}(h``dsa_port_devlink_setup()``h]hdsa_port_devlink_setup()}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, considers all switch ports part of the same tree ID to be part of the same bridge forwarding domain (capable of autonomous forwarding to each other).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXZOffloading the TX forwarding process of a bridge is a distinct concept from simply offloading its forwarding plane, and refers to the ability of certain driver and tag protocol combinations to transmit a single skb coming from the bridge device's transmit function to potentially multiple egress ports (and thereby avoid its cloning in software).h]hX\Offloading the TX forwarding process of a bridge is a distinct concept from simply offloading its forwarding plane, and refers to the ability of certain driver and tag protocol combinations to transmit a single skb coming from the bridge device’s transmit function to potentially multiple egress ports (and thereby avoid its cloning in software).}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXPackets for which the bridge requests this behavior are called data plane packets and have ``skb->offload_fwd_mark`` set to true in the tag protocol driver's ``xmit`` function. Data plane packets are subject to FDB lookup, hardware learning on the CPU port, and do not override the port STP state. Additionally, replication of data plane packets (multicast, flooding) is handled in hardware and the bridge driver will transmit a single skb for each packet that may or may not need replication.h](h[Packets for which the bridge requests this behavior are called data plane packets and have }(hjthhhNhNubj)}(h``skb->offload_fwd_mark``h]hskb->offload_fwd_mark}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjtubh, set to true in the tag protocol driver’s }(hjthhhNhNubj)}(h``xmit``h]hxmit}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjtubhXG function. Data plane packets are subject to FDB lookup, hardware learning on the CPU port, and do not override the port STP state. Additionally, replication of data plane packets (multicast, flooding) is handled in hardware and the bridge driver will transmit a single skb for each packet that may or may not need replication.}(hjthhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXWhen the TX forwarding offload is enabled, the tag protocol driver is responsible to inject packets into the data plane of the hardware towards the correct bridging domain (FID) that the port is a part of. The port may be VLAN-unaware, and in this case the FID must be equal to the FID used by the driver for its VLAN-unaware address database associated with that bridge. Alternatively, the bridge may be VLAN-aware, and in that case, it is guaranteed that the packet is also VLAN-tagged with the VLAN ID that the bridge processed this packet in. It is the responsibility of the hardware to untag the VID on the egress-untagged ports, or keep the tag on the egress-tagged ones.h]hXWhen the TX forwarding offload is enabled, the tag protocol driver is responsible to inject packets into the data plane of the hardware towards the correct bridging domain (FID) that the port is a part of. The port may be VLAN-unaware, and in this case the FID must be equal to the FID used by the driver for its VLAN-unaware address database associated with that bridge. Alternatively, the bridge may be VLAN-aware, and in that case, it is guaranteed that the packet is also VLAN-tagged with the VLAN ID that the bridge processed this packet in. It is the responsibility of the hardware to untag the VID on the egress-untagged ports, or keep the tag on the egress-tagged ones.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubjA)}(hhh](jF)}(hX``port_bridge_join``: bridge layer function invoked when a given switch port is added to a bridge, this function should do what's necessary at the switch level to permit the joining port to be added to the relevant logical domain for it to ingress/egress traffic with other members of the bridge. By setting the ``tx_fwd_offload`` argument to true, the TX forwarding process of this bridge is also offloaded. h]h)}(hX``port_bridge_join``: bridge layer function invoked when a given switch port is added to a bridge, this function should do what's necessary at the switch level to permit the joining port to be added to the relevant logical domain for it to ingress/egress traffic with other members of the bridge. By setting the ``tx_fwd_offload`` argument to true, the TX forwarding process of this bridge is also offloaded.h](j)}(h``port_bridge_join``h]hport_bridge_join}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX&: bridge layer function invoked when a given switch port is added to a bridge, this function should do what’s necessary at the switch level to permit the joining port to be added to the relevant logical domain for it to ingress/egress traffic with other members of the bridge. By setting the }(hjhhhNhNubj)}(h``tx_fwd_offload``h]htx_fwd_offload}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhN argument to true, the TX forwarding process of this bridge is also offloaded.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h``port_bridge_leave``: bridge layer function invoked when a given switch port is removed from a bridge, this function should do what's necessary at the switch level to deny the leaving port from ingress/egress traffic from the remaining bridge members. h]h)}(h``port_bridge_leave``: bridge layer function invoked when a given switch port is removed from a bridge, this function should do what's necessary at the switch level to deny the leaving port from ingress/egress traffic from the remaining bridge members.h](j)}(h``port_bridge_leave``h]hport_bridge_leave}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: bridge layer function invoked when a given switch port is removed from a bridge, this function should do what’s necessary at the switch level to deny the leaving port from ingress/egress traffic from the remaining bridge members.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(h``port_stp_state_set``: bridge layer function invoked when a given switch port STP state is computed by the bridge layer and should be propagated to switch hardware to forward/block/learn traffic. h]h)}(h``port_stp_state_set``: bridge layer function invoked when a given switch port STP state is computed by the bridge layer and should be propagated to switch hardware to forward/block/learn traffic.h](j)}(h``port_stp_state_set``h]hport_stp_state_set}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: bridge layer function invoked when a given switch port STP state is computed by the bridge layer and should be propagated to switch hardware to forward/block/learn traffic.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX``port_bridge_flags``: bridge layer function invoked when a port must configure its settings for e.g. flooding of unknown traffic or source address learning. The switch driver is responsible for initial setup of the standalone ports with address learning disabled and egress flooding of all types of traffic, then the DSA core notifies of any change to the bridge port flags when the port joins and leaves a bridge. DSA does not currently manage the bridge port flags for the CPU port. The assumption is that address learning should be statically enabled (if supported by the hardware) on the CPU port, and flooding towards the CPU port should also be enabled, due to a lack of an explicit address filtering mechanism in the DSA core. h]h)}(hX``port_bridge_flags``: bridge layer function invoked when a port must configure its settings for e.g. flooding of unknown traffic or source address learning. The switch driver is responsible for initial setup of the standalone ports with address learning disabled and egress flooding of all types of traffic, then the DSA core notifies of any change to the bridge port flags when the port joins and leaves a bridge. DSA does not currently manage the bridge port flags for the CPU port. The assumption is that address learning should be statically enabled (if supported by the hardware) on the CPU port, and flooding towards the CPU port should also be enabled, due to a lack of an explicit address filtering mechanism in the DSA core.h](j)}(h``port_bridge_flags``h]hport_bridge_flags}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubhX: bridge layer function invoked when a port must configure its settings for e.g. flooding of unknown traffic or source address learning. The switch driver is responsible for initial setup of the standalone ports with address learning disabled and egress flooding of all types of traffic, then the DSA core notifies of any change to the bridge port flags when the port joins and leaves a bridge. DSA does not currently manage the bridge port flags for the CPU port. The assumption is that address learning should be statically enabled (if supported by the hardware) on the CPU port, and flooding towards the CPU port should also be enabled, due to a lack of an explicit address filtering mechanism in the DSA core.}(hj?hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj;ubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hXR``port_fast_age``: bridge layer function invoked when flushing the dynamically learned FDB entries on the port is necessary. This is called when transitioning from an STP state where learning should take place to an STP state where it shouldn't, or when leaving a bridge, or when address learning is turned off via ``port_bridge_flags``. h]h)}(hXQ``port_fast_age``: bridge layer function invoked when flushing the dynamically learned FDB entries on the port is necessary. This is called when transitioning from an STP state where learning should take place to an STP state where it shouldn't, or when leaving a bridge, or when address learning is turned off via ``port_bridge_flags``.h](j)}(h``port_fast_age``h]h port_fast_age}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1jhjeubhX,: bridge layer function invoked when flushing the dynamically learned FDB entries on the port is necessary. This is called when transitioning from an STP state where learning should take place to an STP state where it shouldn’t, or when leaving a bridge, or when address learning is turned off via }(hjehhhNhNubj)}(h``port_bridge_flags``h]hport_bridge_flags}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjeubh.}(hjehhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjaubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhjhhubeh}(h] bridge-layerah ]h"] bridge layerah$]h&]uh1hhj7hhhhhMubh)}(hhh](h)}(hBridge VLAN filteringh]hBridge VLAN filtering}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubjA)}(hhh](jF)}(hXi``port_vlan_filtering``: bridge layer function invoked when the bridge gets configured for turning on or off VLAN filtering. If nothing specific needs to be done at the hardware level, this callback does not need to be implemented. When VLAN filtering is turned on, the hardware must be programmed with rejecting 802.1Q frames which have VLAN IDs outside of the programmed allowed VLAN ID map/rules. If there is no PVID programmed into the switch port, untagged frames must be rejected as well. When turned off the switch must accept any 802.1Q frames irrespective of their VLAN ID, and untagged frames are allowed. h]h)}(hXh``port_vlan_filtering``: bridge layer function invoked when the bridge gets configured for turning on or off VLAN filtering. If nothing specific needs to be done at the hardware level, this callback does not need to be implemented. When VLAN filtering is turned on, the hardware must be programmed with rejecting 802.1Q frames which have VLAN IDs outside of the programmed allowed VLAN ID map/rules. If there is no PVID programmed into the switch port, untagged frames must be rejected as well. When turned off the switch must accept any 802.1Q frames irrespective of their VLAN ID, and untagged frames are allowed.h](j)}(h``port_vlan_filtering``h]hport_vlan_filtering}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhXQ: bridge layer function invoked when the bridge gets configured for turning on or off VLAN filtering. If nothing specific needs to be done at the hardware level, this callback does not need to be implemented. When VLAN filtering is turned on, the hardware must be programmed with rejecting 802.1Q frames which have VLAN IDs outside of the programmed allowed VLAN ID map/rules. If there is no PVID programmed into the switch port, untagged frames must be rejected as well. When turned off the switch must accept any 802.1Q frames irrespective of their VLAN ID, and untagged frames are allowed.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX+``port_vlan_add``: bridge layer function invoked when a VLAN is configured (tagged or untagged) for the given switch port. The CPU port becomes a member of a VLAN only if a foreign bridge port is also a member of it (and forwarding needs to take place in software), or the VLAN is installed to the VLAN group of the bridge device itself, for termination purposes (``bridge vlan add dev br0 vid 100 self``). VLANs on shared ports are reference counted and removed when there is no user left. Drivers do not need to manually install a VLAN on the CPU port. h]h)}(hX*``port_vlan_add``: bridge layer function invoked when a VLAN is configured (tagged or untagged) for the given switch port. The CPU port becomes a member of a VLAN only if a foreign bridge port is also a member of it (and forwarding needs to take place in software), or the VLAN is installed to the VLAN group of the bridge device itself, for termination purposes (``bridge vlan add dev br0 vid 100 self``). VLANs on shared ports are reference counted and removed when there is no user left. Drivers do not need to manually install a VLAN on the CPU port.h](j)}(h``port_vlan_add``h]h port_vlan_add}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX[: bridge layer function invoked when a VLAN is configured (tagged or untagged) for the given switch port. The CPU port becomes a member of a VLAN only if a foreign bridge port is also a member of it (and forwarding needs to take place in software), or the VLAN is installed to the VLAN group of the bridge device itself, for termination purposes (}(hjhhhNhNubj)}(h(``bridge vlan add dev br0 vid 100 self``h]h$bridge vlan add dev br0 vid 100 self}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh). VLANs on shared ports are reference counted and removed when there is no user left. Drivers do not need to manually install a VLAN on the CPU port.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hc``port_vlan_del``: bridge layer function invoked when a VLAN is removed from the given switch port h]h)}(hb``port_vlan_del``: bridge layer function invoked when a VLAN is removed from the given switch porth](j)}(h``port_vlan_del``h]h port_vlan_del}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhQ: bridge layer function invoked when a VLAN is removed from the given switch port}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX``port_fdb_add``: bridge layer function invoked when the bridge wants to install a Forwarding Database entry, the switch hardware should be programmed with the specified address in the specified VLAN Id in the forwarding database associated with this VLAN ID. h]h)}(hX``port_fdb_add``: bridge layer function invoked when the bridge wants to install a Forwarding Database entry, the switch hardware should be programmed with the specified address in the specified VLAN Id in the forwarding database associated with this VLAN ID.h](j)}(h``port_fdb_add``h]h port_fdb_add}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjCubh: bridge layer function invoked when the bridge wants to install a Forwarding Database entry, the switch hardware should be programmed with the specified address in the specified VLAN Id in the forwarding database associated with this VLAN ID.}(hjChhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj?ubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX ``port_fdb_del``: bridge layer function invoked when the bridge wants to remove a Forwarding Database entry, the switch hardware should be programmed to delete the specified MAC address from the specified VLAN ID if it was mapped into this port forwarding database h]h)}(hX``port_fdb_del``: bridge layer function invoked when the bridge wants to remove a Forwarding Database entry, the switch hardware should be programmed to delete the specified MAC address from the specified VLAN ID if it was mapped into this port forwarding databaseh](j)}(h``port_fdb_del``h]h port_fdb_del}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjiubh: bridge layer function invoked when the bridge wants to remove a Forwarding Database entry, the switch hardware should be programmed to delete the specified MAC address from the specified VLAN ID if it was mapped into this port forwarding database}(hjihhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjeubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX``port_fdb_dump``: bridge bypass function invoked by ``ndo_fdb_dump`` on the physical DSA port interfaces. Since DSA does not attempt to keep in sync its hardware FDB entries with the software bridge, this method is implemented as a means to view the entries visible on user ports in the hardware database. The entries reported by this function have the ``self`` flag in the output of the ``bridge fdb show`` command. h]h)}(hX``port_fdb_dump``: bridge bypass function invoked by ``ndo_fdb_dump`` on the physical DSA port interfaces. Since DSA does not attempt to keep in sync its hardware FDB entries with the software bridge, this method is implemented as a means to view the entries visible on user ports in the hardware database. The entries reported by this function have the ``self`` flag in the output of the ``bridge fdb show`` command.h](j)}(h``port_fdb_dump``h]h port_fdb_dump}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh$: bridge bypass function invoked by }(hjhhhNhNubj)}(h``ndo_fdb_dump``h]h ndo_fdb_dump}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX on the physical DSA port interfaces. Since DSA does not attempt to keep in sync its hardware FDB entries with the software bridge, this method is implemented as a means to view the entries visible on user ports in the hardware database. The entries reported by this function have the }(hjhhhNhNubj)}(h``self``h]hself}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh flag in the output of the }(hjhhhNhNubj)}(h``bridge fdb show``h]hbridge fdb show}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh command.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX``port_mdb_add``: bridge layer function invoked when the bridge wants to install a multicast database entry. The switch hardware should be programmed with the specified address in the specified VLAN ID in the forwarding database associated with this VLAN ID. h]h)}(hX``port_mdb_add``: bridge layer function invoked when the bridge wants to install a multicast database entry. The switch hardware should be programmed with the specified address in the specified VLAN ID in the forwarding database associated with this VLAN ID.h](j)}(h``port_mdb_add``h]h port_mdb_add}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: bridge layer function invoked when the bridge wants to install a multicast database entry. The switch hardware should be programmed with the specified address in the specified VLAN ID in the forwarding database associated with this VLAN ID.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubjF)}(hX ``port_mdb_del``: bridge layer function invoked when the bridge wants to remove a multicast database entry, the switch hardware should be programmed to delete the specified MAC address from the specified VLAN ID if it was mapped into this port forwarding database. h]h)}(hX``port_mdb_del``: bridge layer function invoked when the bridge wants to remove a multicast database entry, the switch hardware should be programmed to delete the specified MAC address from the specified VLAN ID if it was mapped into this port forwarding database.h](j)}(h``port_mdb_del``h]h port_mdb_del}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh: bridge layer function invoked when the bridge wants to remove a multicast database entry, the switch hardware should be programmed to delete the specified MAC address from the specified VLAN ID if it was mapped into this port forwarding database.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhjhhubeh}(h]bridge-vlan-filteringah ]h"]bridge vlan filteringah$]h&]uh1hhj7hhhhhMubh)}(hhh](h)}(hLink aggregationh]hLink aggregation}(hjD hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjA hhhhhMubh)}(hXLink aggregation is implemented in the Linux networking stack by the bonding and team drivers, which are modeled as virtual, stackable network interfaces. DSA is capable of offloading a link aggregation group (LAG) to hardware that supports the feature, and supports bridging between physical ports and LAGs, as well as between LAGs. A bonding/team interface which holds multiple physical ports constitutes a logical port, although DSA has no explicit concept of a logical port at the moment. Due to this, events where a LAG joins/leaves a bridge are treated as if all individual physical ports that are members of that LAG join/leave the bridge. Switchdev port attributes (VLAN filtering, STP state, etc) and objects (VLANs, MDB entries) offloaded to a LAG as bridge port are treated similarly: DSA offloads the same switchdev object / port attribute on all members of the LAG. Static bridge FDB entries on a LAG are not yet supported, since the DSA driver API does not have the concept of a logical port ID.h]hXLink aggregation is implemented in the Linux networking stack by the bonding and team drivers, which are modeled as virtual, stackable network interfaces. DSA is capable of offloading a link aggregation group (LAG) to hardware that supports the feature, and supports bridging between physical ports and LAGs, as well as between LAGs. A bonding/team interface which holds multiple physical ports constitutes a logical port, although DSA has no explicit concept of a logical port at the moment. Due to this, events where a LAG joins/leaves a bridge are treated as if all individual physical ports that are members of that LAG join/leave the bridge. Switchdev port attributes (VLAN filtering, STP state, etc) and objects (VLANs, MDB entries) offloaded to a LAG as bridge port are treated similarly: DSA offloads the same switchdev object / port attribute on all members of the LAG. Static bridge FDB entries on a LAG are not yet supported, since the DSA driver API does not have the concept of a logical port ID.}(hjR hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjA hhubjA)}(hhh](jF)}(h``port_lag_join``: function invoked when a given switch port is added to a LAG. The driver may return ``-EOPNOTSUPP``, and in this case, DSA will fall back to a software implementation where all traffic from this port is sent to the CPU.h]h)}(h``port_lag_join``: function invoked when a given switch port is added to a LAG. The driver may return ``-EOPNOTSUPP``, and in this case, DSA will fall back to a software implementation where all traffic from this port is sent to the CPU.h](j)}(h``port_lag_join``h]h port_lag_join}(hjk hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjg ubhU: function invoked when a given switch port is added to a LAG. The driver may return }(hjg hhhNhNubj)}(h``-EOPNOTSUPP``h]h -EOPNOTSUPP}(hj} hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjg ubhx, and in this case, DSA will fall back to a software implementation where all traffic from this port is sent to the CPU.}(hjg hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjc ubah}(h]h ]h"]h$]h&]uh1jEhj` hhhhhNubjF)}(hy``port_lag_leave``: function invoked when a given switch port leaves a LAG and returns to operation as a standalone port.h]h)}(hy``port_lag_leave``: function invoked when a given switch port leaves a LAG and returns to operation as a standalone port.h](j)}(h``port_lag_leave``h]hport_lag_leave}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhg: function invoked when a given switch port leaves a LAG and returns to operation as a standalone port.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhj` hhhhhNubjF)}(h``port_lag_change``: function invoked when the link state of any member of the LAG changes, and the hashing function needs rebalancing to only make use of the subset of physical LAG member ports that are up. h]h)}(h``port_lag_change``: function invoked when the link state of any member of the LAG changes, and the hashing function needs rebalancing to only make use of the subset of physical LAG member ports that are up.h](j)}(h``port_lag_change``h]hport_lag_change}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh: function invoked when the link state of any member of the LAG changes, and the hashing function needs rebalancing to only make use of the subset of physical LAG member ports that are up.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jEhj` hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhMhjA hhubh)}(hX$Drivers that benefit from having an ID associated with each offloaded LAG can optionally populate ``ds->num_lag_ids`` from the ``dsa_switch_ops::setup`` method. The LAG ID associated with a bonding/team interface can then be retrieved by a DSA switch driver using the ``dsa_lag_id`` function.h](hbDrivers that benefit from having an ID associated with each offloaded LAG can optionally populate }(hj hhhNhNubj)}(h``ds->num_lag_ids``h]hds->num_lag_ids}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh from the }(hj hhhNhNubj)}(h``dsa_switch_ops::setup``h]hdsa_switch_ops::setup}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubht method. The LAG ID associated with a bonding/team interface can then be retrieved by a DSA switch driver using the }(hj hhhNhNubj)}(h``dsa_lag_id``h]h dsa_lag_id}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh function.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hjA hhubeh}(h]link-aggregationah ]h"]link aggregationah$]h&]uh1hhj7hhhhhMubh)}(hhh](h)}(hIEC 62439-2 (MRP)9h]hIEC 62439-2 (MRP)}(hjhj!ubah}(h]h ]h"]h$]h&]uh1jEhjf!hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhM;hj9!hhubeh}(h]iec-62439-2-mrpah ]h"]iec 62439-2 (mrp)ah$]h&]uh1hhj7hhhhhM&ubh)}(hhh](h)}(hIEC 62439-3 (HSR/PRP)h]hIEC 62439-3 (HSR/PRP)}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj!hhhhhMDubh)}(hXThe Parallel Redundancy Protocol (PRP) is a network redundancy protocol which works by duplicating and sequence numbering packets through two independent L2 networks (which are unaware of the PRP tail tags carried in the packets), and eliminating the duplicates at the receiver. The High-availability Seamless Redundancy (HSR) protocol is similar in concept, except all nodes that carry the redundant traffic are aware of the fact that it is HSR-tagged (because HSR uses a header with an EtherType of 0x892f) and are physically connected in a ring topology. Both HSR and PRP use supervision frames for monitoring the health of the network and for discovery of other nodes.h]hXThe Parallel Redundancy Protocol (PRP) is a network redundancy protocol which works by duplicating and sequence numbering packets through two independent L2 networks (which are unaware of the PRP tail tags carried in the packets), and eliminating the duplicates at the receiver. The High-availability Seamless Redundancy (HSR) protocol is similar in concept, except all nodes that carry the redundant traffic are aware of the fact that it is HSR-tagged (because HSR uses a header with an EtherType of 0x892f) and are physically connected in a ring topology. Both HSR and PRP use supervision frames for monitoring the health of the network and for discovery of other nodes.}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMFhj!hhubh)}(hXIn Linux, both HSR and PRP are implemented in the hsr driver, which instantiates a virtual, stackable network interface with two member ports. The driver only implements the basic roles of DANH (Doubly Attached Node implementing HSR) and DANP (Doubly Attached Node implementing PRP); the roles of RedBox and QuadBox are not implemented (therefore, bridging a hsr network interface with a physical switch port does not produce the expected result).h]hXIn Linux, both HSR and PRP are implemented in the hsr driver, which instantiates a virtual, stackable network interface with two member ports. The driver only implements the basic roles of DANH (Doubly Attached Node implementing HSR) and DANP (Doubly Attached Node implementing PRP); the roles of RedBox and QuadBox are not implemented (therefore, bridging a hsr network interface with a physical switch port does not produce the expected result).}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMPhj!hhubh)}(hX A driver which is able of offloading certain functions of a DANP or DANH should declare the corresponding netdev features as indicated by the documentation at ``Documentation/networking/netdev-features.rst``. Additionally, the following methods must be implemented:h](hA driver which is able of offloading certain functions of a DANP or DANH should declare the corresponding netdev features as indicated by the documentation at }(hj"hhhNhNubj)}(h0``Documentation/networking/netdev-features.rst``h]h,Documentation/networking/netdev-features.rst}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"ubh:. Additionally, the following methods must be implemented:}(hj"hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMWhj!hhubjA)}(hhh](jF)}(h``port_hsr_join``: function invoked when a given switch port is added to a DANP/DANH. The driver may return ``-EOPNOTSUPP`` and in this case, DSA will fall back to a software implementation where all traffic from this port is sent to the CPU.h]h)}(h``port_hsr_join``: function invoked when a given switch port is added to a DANP/DANH. The driver may return ``-EOPNOTSUPP`` and in this case, DSA will fall back to a software implementation where all traffic from this port is sent to the CPU.h](j)}(h``port_hsr_join``h]h port_hsr_join}(hj?"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj;"ubh[: function invoked when a given switch port is added to a DANP/DANH. The driver may return }(hj;"hhhNhNubj)}(h``-EOPNOTSUPP``h]h -EOPNOTSUPP}(hjQ"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj;"ubhw and in this case, DSA will fall back to a software implementation where all traffic from this port is sent to the CPU.}(hj;"hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM\hj7"ubah}(h]h ]h"]h$]h&]uh1jEhj4"hhhhhNubjF)}(h``port_hsr_leave``: function invoked when a given switch port leaves a DANP/DANH and returns to normal operation as a standalone port. h]h)}(h``port_hsr_leave``: function invoked when a given switch port leaves a DANP/DANH and returns to normal operation as a standalone port.h](j)}(h``port_hsr_leave``h]hport_hsr_leave}(hjw"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjs"ubht: function invoked when a given switch port leaves a DANP/DANH and returns to normal operation as a standalone port.}(hjs"hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM`hjo"ubah}(h]h ]h"]h$]h&]uh1jEhj4"hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1j@hhhM\hj!hhubeh}(h]iec-62439-3-hsr-prpah ]h"]iec 62439-3 (hsr/prp)ah$]h&]uh1hhj7hhhhhMDubeh}(h]driver-developmentah ]h"]driver developmentah$]h&]uh1hhhhhhhhM ubh)}(hhh](h)}(hTODOh]hTODO}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj"hhhhhMdubh)}(hhh](h)}(h=Making SWITCHDEV and DSA converge towards an unified codebaseh]h=Making SWITCHDEV and DSA converge towards an unified codebase}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj"hhhhhMgubh)}(hXmSWITCHDEV properly takes care of abstracting the networking stack with offload capable hardware, but does not enforce a strict switch device driver model. On the other DSA enforces a fairly strict device driver model, and deals with most of the switch specific. At some point we should envision a merger between these two subsystems and get the best of both worlds.h]hXmSWITCHDEV properly takes care of abstracting the networking stack with offload capable hardware, but does not enforce a strict switch device driver model. On the other DSA enforces a fairly strict device driver model, and deals with most of the switch specific. At some point we should envision a merger between these two subsystems and get the best of both worlds.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMihj"hhubeh}(h]=making-switchdev-and-dsa-converge-towards-an-unified-codebaseah ]h"]=making switchdev and dsa converge towards an unified codebaseah$]h&]uh1hhj"hhhhhMgubeh}(h]todoah ]h"]todoah$]h&]uh1hhhhhhhhMdubeh}(h] architectureah ]h"] architectureah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj#error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j"j"j j jjj+j(jHjEjv js j j j j j j j j j j j j j4j1j j jjjjj,j)j"j"jjjOjLjSjPj=j:j-j*jjjjj> j; j6!j3!j!j!j"j"j"j"j"j"u nametypes}(j"j jj+jHjv j j j j j j j4j jjj,j"jjOjSj=j-jjj> j6!j!j"j"j"uh}(j"hj hjjj(jjEj.js jKj jy j j j j j j! j j2 j j j1j j j jj jjj)jj"j7jjhjLjjPjRj:jVj*j@jj0jjj; jj3!jA j!j9!j"j!j"j"j"j"u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.