.. _8021Qav: IEEE 802.1Qav ############# Overview ******** Credit-based shaping is an alternative scheduling algorithm used in network schedulers to achieve fairness when sharing a limited network resource. Zephyr has support for configuring a credit-based shaper 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(const 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