[SDFAB-601] Add chassis config guide

Change-Id: Ibbf6689c45efc1a128d5057c7e0993dea4a263cf
diff --git a/conf.py b/conf.py
index 55466cb..ec932a7 100644
--- a/conf.py
+++ b/conf.py
@@ -248,6 +248,10 @@
 linkcheck_timeout = 3
 linkcheck_retries = 2
 
+linkcheck_anchors_ignore = [
+    r"L\d+" # Ignore line anchors from GitHub.
+]
+
 # -- options for Intersphinx extension ---------------------------------------
 
 intersphinx_mapping = {
diff --git a/configuration/chassis.rst b/configuration/chassis.rst
index 776321f..1db3b1a 100644
--- a/configuration/chassis.rst
+++ b/configuration/chassis.rst
@@ -1,2 +1,193 @@
-Chassis Configuration
-=====================
+Stratum Chassis Configuration
+=============================
+
+.. tip::
+
+    Check out `examples <https://github.com/stratum/stratum/tree/main/stratum/hal/config>`_
+    for every platform supported by Stratum.
+
+    See the `Deployment Guide <../deployment.rst>`_ to learn about how to deploy Stratum
+    with a custom chassis config.
+
+The Stratum chassis config is the internal data structure that encapsulates the so called
+"config" pushed to the entire chassis. The term "chassis" refers to the a switching box
+with one or more switching nodes managed by a management interface.
+
+The chassis config file will be placed on the disk of the device and loaded when starting the Stratum.
+The config includes all the not-so-frequent settings that are required before the switch
+can accept flow programming requests from the controller.
+
+A valid chassis config includes a ``chassis`` and a ``node`` field, and may includes one
+or more ``singleton_port`` field. See each section below for more detail.
+
+.. note::
+
+    In Stratum the external interface for pushing config is gNMI.
+    The protobuf realization of the YANG models for the config is internally converted
+    to a chassis config before it is consumed by the internal stack components.
+
+    The `format of chassis config <https://github.com/stratum/stratum/blob/main/stratum/hal/lib/common/common.proto#L824-L833>`_
+    is based on protobuf text format, check out
+    `the protobuf language guide for more info <https://developers.google.com/protocol-buffers/docs/overview?hl=en>`_
+
+Chassis
+-------
+
+A ``chassis`` uniquely identifies a switch with a single management interface.
+Each chassis may contain one or more slots (aka linecards),
+and one or more switching nodes (aka chips) on each slot.
+
+A chassis contains the following fields:
+
+* ``platform``: The chassis platform. **Required**
+* ``name``: An arbitrary name for the chassis. **Optional**
+* ``config_params``: Parameters configured for the entire chassis when config is pushed to the the switch. **Optional**
+
+.. tip::
+
+    Check out the list of platforms `here <https://github.com/stratum/stratum/blob/main/stratum/hal/lib/common/common.proto#L33-L47>`_
+
+Node
+----
+
+A ``node`` uniquely identifies a single switching node (aka chip) on a chassis linecard
+and all its flow-related and config-related parameters.
+
+A node contains the following fields:
+
+* ``id``: The unique ID of the switch node on the chassis as used by the P4Runtime controller. **Required**
+* ``name``: An arbitrary name for the switching node. **Optional**
+* ``slot``: The 1-base index of the slot (aka linecard) which this node belongs. **Required**
+* ``index``: The optional 1-base index of the node within the chassis. **Optional**
+
+Singleton Port
+--------------
+
+A ``singleton port`` in the chassis configuration uniquely identifies a single physical port on
+a single chassis.
+
+A singleton port contains the following fields:
+
+* ``id``: The unique ID of the singleton port. **Required**
+* ``name``: An optional arbitrary name for the singleton port. **Required**
+
+    The control plan (e.g., ONOS) can use this name to query port information as a gNMI path key.
+
+* ``slot``: The 1-base index of the slot (aka linecard) of the port. **Required**
+* ``port``: The 1-base index of the singleton port on the slot. **Required**
+* ``channel``: The 1-base channel index. Absence or zero means non-channelized. **Optional**
+* ``speed_bps``: The speed of the port in bps. **Required**
+* ``node``: The id of the corresponding node that the port belongs to. **Required**
+* ``config_params``: Parameters configured for this port. **Optional**
+
+  * ``admin_state``: The initial admin state for this port, port will be disabled by default.
+
+    * Choose from ``ADMIN_STATE_DISABLED`` or ``ADMIN_STATE_ENABLED``.
+
+  * ``mtu``: The maximum transmission unit for this port.
+  * ``autoneg``: Whether auto-negotiation is enabled or not for this port.
+
+    * Choose from ``TRI_STATE_FALSE`` or ``TRI_STATE_TRUE``
+    * The initial configuration might be different if this field is empty, based on the
+      platform or the connector you are using.
+
+  * ``fec_mode``: The
+
+    * Choose from ``FEC_MODE_ON``, ``FEC_MODE_OFF``, or ``FEC_MODE_AUTO``
+
+  * ``loopback_mode``:
+
+    * Choose from ``LOOPBACK_STATE_NONE``, ``LOOPBACK_STATE_MAC``, or ``LOOPBACK_STATE_PHY``
+
+Example chassis config
+----------------------
+
+In this example, we want to set up a **Tofino-based switch** with only one node/slot.
+
+And we want to set up two ports:
+
+* Port 1: 100G port without channelization, enabled by default, and disable auto auto-negotiation.
+* Port 2: break out to four 10G ports, uses different channels for each port and enable
+  them by default with auto-negotiation.
+
+.. image:: ../images/chassis-config-example.svg
+    :width: 500px
+
+Below is an example of a chassis configuration with a list of singleton port:
+
+.. code-block::
+
+    description: "A chassis config example."
+    chassis {
+        platform: PLT_GENERIC_BAREFOOT_TOFINO
+        name: "leaf-1"
+    }
+    nodes {
+        id: 1
+        slot: 1
+        index: 1
+    }
+    singleton_ports {
+        id: 1
+        name: "1/0"
+        slot: 1
+        port: 1
+        speed_bps: 100000000000 # 100G
+        config_params {
+            admin_state: ADMIN_STATE_ENABLED
+            autoneg: TRI_STATE_FALSE
+        }
+        node: 1
+    }
+    singleton_ports {
+        id: 200
+        name: "2/0"
+        slot: 1
+        port: 2
+        channel: 1
+        speed_bps: 10000000000 # 10G
+        config_params {
+            admin_state: ADMIN_STATE_ENABLED
+            autoneg: TRI_STATE_TRUE
+        }
+        node: 1
+    }
+    singleton_ports {
+        id: 201
+        name: "2/1"
+        slot: 1
+        port: 2
+        channel: 2
+        speed_bps: 10000000000 # 10G
+        config_params {
+            admin_state: ADMIN_STATE_ENABLED
+            autoneg: TRI_STATE_TRUE
+        }
+        node: 1
+    }
+    singleton_ports {
+        id: 202
+        name: "2/2"
+        slot: 1
+        port: 2
+        channel: 3
+        speed_bps: 10000000000 # 10G
+        config_params {
+            admin_state: ADMIN_STATE_ENABLED
+            autoneg: TRI_STATE_TRUE
+        }
+        node: 1
+    }
+    singleton_ports {
+        id: 203
+        name: "2/3"
+        slot: 1
+        port: 2
+        channel: 4
+        speed_bps: 10000000000 # 10G
+        config_params {
+            admin_state: ADMIN_STATE_ENABLED
+            autoneg: TRI_STATE_TRUE
+        }
+        node: 1
+    }
diff --git a/dict.txt b/dict.txt
index c466f85..82b82df 100644
--- a/dict.txt
+++ b/dict.txt
@@ -27,3 +27,8 @@
 topologies
 uplink
 virtualenv
+gNMI
+linecard
+linecards
+config
+protobuf
diff --git a/images/chassis-config-example.svg b/images/chassis-config-example.svg
new file mode 100644
index 0000000..2461c37
--- /dev/null
+++ b/images/chassis-config-example.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than diagrams.net -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="532px" height="332px" viewBox="-0.5 -0.5 532 332" content="&lt;mxfile host=&quot;Electron&quot; modified=&quot;2021-09-30T00:45:01.011Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/15.3.7 Chrome/93.0.4577.63 Electron/14.0.1 Safari/537.36&quot; etag=&quot;xKR2AYUHPkhz5BQZKkjX&quot; version=&quot;15.3.7&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;qtn4Z6Z5bv_Oql5VsiPR&quot; name=&quot;Page-1&quot;&gt;5Vpdc9o6EP01PCZjyx+QR0xI7kObyUw606RvCpZt9coSV4gC99d3hWX8WeK0EOwpL0irlZDO2T1e24ycWbq9l3iZfBYhYSNkhduRcztCyLYtH760ZZdZbm7GmSGWNDROheGJ/k+M0TLWNQ3JquKohGCKLqvGheCcLFTFhqUUm6pbJFj1V5c4Jg3D0wKzpvUrDVWSWSeeVdj/ITRO1OHAZiTFubMxrBIcik3J5MxHzkwKobJWup0RpsHLccnm3f1i9LAxSbjqMkGlwRY9331bbl6dx6fNw2r69cuVWeUHZmtzYLNZtcsRkGLNQ6IXsUdOsEmoIk9LvNCjG+AcbIlKmRleKSn+JTPBhNzPdrLPYSTHEE4fmJ8mUpHtL89kH5CCECMiJUruwMVMQK4B10SXm/c3BVduzkhS4gnlRmziIz6sXUAIDYPiOxCdNAAkIUSU6QqpEhELjtm8sAYFxBb0Cp9PQiwNsN+JUjuTHnitRBV2sqXqWU+/9kzvxSym27fbcmeXdzgc97nceSlW0N1i2r5XzAunOrGgywUnmeWOapT249n59aGPkwoYibVckCNYmmBUWMZEHfEbtweJJAwr+qO6j5MTjhopBBpwfySNrN9JI9cPZuhsaTSpppFvNdPIRi1p5J4ri26Gl0VF4rzk6/Uji5whZJHdI8btroyjCuXWG5RHgiuzE9vvZwjYF40Bp0VJTy2knjv1/Pm5hNR13xZS9yN11LYb+PVdSO1KTl2Pe1SPuENQUtQjyjsr6XgoSto1BP5YSfdT4VR4V3JYCsrVqrTyozYU+uPV9eemdk9Y83cn3jF/aGQ7KKLxcJTfD1B38DLvob7JfPO2fWAyj3ok894gZL5HlHeU+RrlbzF+QZXvGgGXrZe94Qup3zchtRr49V1I68VTj548+IMQ0h5R3rleHkq53DUCLlQuWzX5mbxRLtfL68kHlMv+4FXe7fB4+UNVftyA9EGEBCzNW+c/e/s1D3zPcs+Fq1PD1ev62N4/2+Wz+QjvAafQmoKRERzpF44+g20Er7ICtP/fWr8I3WvV1WovVnoOwLEtBqEV6+9HEIVIyDTzuSecSLqAVgDQRfqFKrK+iIhy0aATwFbHODN6GIEY1kyY0ZhDdwHkELAHmjq6wGxqBlIahvtrQ1uQVNOzJMjIOk0sIG+i64ByOLS9DHV8dO01A8I7W0D4l724js//JueCV1e769ModMkCy24+8Jlz/MqAYWS96n2EJMJrUIWSNGSJfktX2lHvCki+4iQWisKWBX93Zue/cTS5GYnUyVJ7Hw0nSG3bbq86KjI/aZH582V18wLaldHMr5XQuusswZwTBmCGfxHbjldle9x2UW9je/x+tqFb/P8oq1eLf3E5858=&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><rect x="130" y="1" width="400" height="200" rx="30" ry="30" fill="#ffffff" stroke="#333333" stroke-width="2" pointer-events="all"/><path d="M 230 161 L 230 91 L 270 91" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><rect x="170" y="161" width="120" height="40" fill="#ffffff" stroke="#346bc2" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 181px; margin-left: 171px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">100G</div></div></div></foreignObject><text x="230" y="185" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">100G</text></switch></g><path d="M 350 161 L 350 141 L 330 141 L 330 121" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 350 201 L 350 231 L 285 231 L 285 261" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><rect x="330" y="161" width="40" height="40" fill="#ffffff" stroke="#54a56e" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 181px; margin-left: 331px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">10G</div></div></div></foreignObject><text x="350" y="185" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">10G</text></switch></g><path d="M 430 161 L 430 106 L 390 106" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 430 201 L 430 251 L 375 251 L 375 261" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><rect x="410" y="161" width="40" height="40" fill="#ffffff" stroke="#54a56e" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 181px; margin-left: 411px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">10G</div></div></div></foreignObject><text x="430" y="185" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">10G</text></switch></g><path d="M 470 161 L 470 76 L 390 76" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 470 201 L 470 296 L 420 296" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><rect x="450" y="161" width="40" height="40" fill="#ffffff" stroke="#54a56e" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 181px; margin-left: 451px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">10G</div></div></div></foreignObject><text x="470" y="185" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">10G</text></switch></g><path d="M 390 161 L 390 141 L 360 141 L 360 121" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 390 201 L 390 241 L 330 241 L 330 261" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><rect x="370" y="161" width="40" height="40" fill="#ffffff" stroke="#54a56e" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 181px; margin-left: 371px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">10G</div></div></div></foreignObject><text x="390" y="185" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">10G</text></switch></g><rect x="270" y="61" width="120" height="60" rx="9" ry="9" fill="#ffffff" stroke="#eb6504" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 91px; margin-left: 271px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Node 1</div></div></div></foreignObject><text x="330" y="95" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Node 1</text></switch></g><rect x="148.75" y="1" width="362.5" height="50" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 361px; height: 1px; padding-top: 26px; margin-left: 150px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 20px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Name: leaf-1<br style="font-size: 20px" />Platform: Generic Barefoot Tofino</div></div></div></foreignObject><text x="330" y="32" fill="#000000" font-family="Helvetica" font-size="20px" text-anchor="middle">Name: leaf-1...</text></switch></g><path d="M 135 241 L 135 221 L 230 221 L 230 201" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><rect x="0" y="241" width="180" height="50" fill="none" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 178px; height: 1px; padding-top: 266px; margin-left: 2px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Enabled by default<br />Disable auto-negotiation</div></div></div></foreignObject><text x="2" y="271" fill="#000000" font-family="Helvetica" font-size="16px">Enabled by default...</text></switch></g><rect x="240" y="261" width="180" height="70" fill="none" stroke="#000000" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 178px; height: 1px; padding-top: 296px; margin-left: 242px;"><div style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 16px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Enabled by default<br />Enable auto-negotiation<br />Channelized</div></div></div></foreignObject><text x="242" y="301" fill="#000000" font-family="Helvetica" font-size="16px">Enabled by default...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
\ No newline at end of file