Back to Zephyr

IEEE 802.1Qav

doc/connectivity/networking/api/8021Qav.rst

4.4.03.2 KB
Original Source

.. _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 |
	       ETHERNET_LINK_100BASE;
}

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 <zephyr/net/net_if.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/ethernet_mgmt.h>

static void qav_set_status(struct net_if *iface,
                           int queue_id, bool enable)
{
	struct ethernet_req_params params;
	int ret;

	memset(&params, 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, &params,
		       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(&params, 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, &params,
		       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, &params,
		       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