diff --git a/doc/reference/networking/8021Qav.rst b/doc/reference/networking/8021Qav.rst index 217abb2bc6a..c943b6cda26 100644 --- a/doc/reference/networking/8021Qav.rst +++ b/doc/reference/networking/8021Qav.rst @@ -13,5 +13,97 @@ described in the `IEEE 802.1Qav-2009 standard`_. Zephyr does not implement the actual shaper; it only provides a way to configure the shaper implemented by the Ethernet device driver. +Enabling 802.1Qav +***************** + +To enable 802.1Qav shaper, the Ethernet device driver must declare +that it supports credit-based shaping. The Ethernet driver's capability +function must return ``ETHERNET_QAV`` value for this purpose. Typically +also priority queues ``ETHERNET_PRIORITY_QUEUES`` need to be supported. + +.. code-block:: none + + static enum ethernet_hw_caps eth_get_capabilities(struct device *dev) + { + ARG_UNUSED(dev); + + return ETHERNET_QAV | ETHERNET_PRIORITY_QUEUES | + ETHERNET_HW_VLAN | ETHERNET_LINK_10BASE_T | + ETHERNET_LINK_100BASE_T; + } + +See ``sam-e70-xplained`` board Ethernet driver +:zephyr_file:`drivers/ethernet/eth_sam_gmac.c` for an example. + +Configuring 802.1Qav +******************** + +The application can configure the credit-based shaper like this: + +.. code-block:: c + + #include + #include + #include + + static void qav_set_status(struct net_if *iface, + int queue_id, bool enable) + { + struct ethernet_req_params params; + int ret; + + memset(¶ms, 0, sizeof(params)); + + params.qav_param.queue_id = queue_id; + params.qav_param.enabled = enable; + params.qav_param.type = ETHERNET_QAV_PARAM_TYPE_STATUS; + + /* Disable or enable Qav for a queue */ + ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QAV_PARAM, + iface, ¶ms, + sizeof(struct ethernet_req_params)); + if (ret) { + LOG_ERR("Cannot %s Qav for queue %d for interface %p", + enable ? "enable" : "disable", + queue_id, iface); + } + } + + static void qav_set_bandwidth_and_slope(struct net_if *iface, + int queue_id, + unsigned int bandwidth, + unsigned int idle_slope) + { + struct ethernet_req_params params; + int ret; + + memset(¶ms, 0, sizeof(params)); + + params.qav_param.queue_id = queue_id; + params.qav_param.delta_bandwidth = bandwidth; + params.qav_param.type = ETHERNET_QAV_PARAM_TYPE_DELTA_BANDWIDTH; + + ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QAV_PARAM, + iface, ¶ms, + sizeof(struct ethernet_req_params)); + if (ret) { + LOG_ERR("Cannot set Qav delta bandwidth %u for " + "queue %d for interface %p", + bandwidth, queue_id, iface); + } + + params.qav_param.idle_slope = idle_slope; + params.qav_param.type = ETHERNET_QAV_PARAM_TYPE_IDLE_SLOPE; + + ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QAV_PARAM, + iface, ¶ms, + sizeof(struct ethernet_req_params)); + if (ret) { + LOG_ERR("Cannot set Qav idle slope %u for " + "queue %d for interface %p", + idle_slope, queue_id, iface); + } + } + .. _IEEE 802.1Qav-2009 standard: https://standards.ieee.org/standard/802_1Qav-2009.html