1.. _8021Qav:
2
3IEEE 802.1Qav
4#############
5
6Overview
7********
8
9Credit-based shaping is an alternative scheduling algorithm used in
10network schedulers to achieve fairness when sharing a limited network
11resource.  Zephyr has support for configuring a credit-based shaper
12described in the `IEEE 802.1Qav-2009 standard`_. Zephyr does not
13implement the actual shaper; it only provides a way to configure the
14shaper implemented by the Ethernet device driver.
15
16Enabling 802.1Qav
17*****************
18
19To enable 802.1Qav shaper, the Ethernet device driver must declare
20that it supports credit-based shaping. The Ethernet driver's capability
21function must return ``ETHERNET_QAV`` value for this purpose. Typically
22also priority queues ``ETHERNET_PRIORITY_QUEUES`` need to be supported.
23
24.. code-block:: none
25
26	static enum ethernet_hw_caps eth_get_capabilities(const struct device *dev)
27	{
28		ARG_UNUSED(dev);
29
30		return ETHERNET_QAV | ETHERNET_PRIORITY_QUEUES |
31		       ETHERNET_HW_VLAN | ETHERNET_LINK_10BASE_T |
32		       ETHERNET_LINK_100BASE_T;
33	}
34
35See ``sam-e70-xplained`` board Ethernet driver
36:zephyr_file:`drivers/ethernet/eth_sam_gmac.c` for an example.
37
38Configuring 802.1Qav
39********************
40
41The application can configure the credit-based shaper like this:
42
43.. code-block:: c
44
45	#include <zephyr/net/net_if.h>
46	#include <zephyr/net/ethernet.h>
47	#include <zephyr/net/ethernet_mgmt.h>
48
49	static void qav_set_status(struct net_if *iface,
50	                           int queue_id, bool enable)
51	{
52		struct ethernet_req_params params;
53		int ret;
54
55		memset(&params, 0, sizeof(params));
56
57		params.qav_param.queue_id = queue_id;
58		params.qav_param.enabled = enable;
59		params.qav_param.type = ETHERNET_QAV_PARAM_TYPE_STATUS;
60
61		/* Disable or enable Qav for a queue */
62		ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QAV_PARAM,
63			       iface, &params,
64			       sizeof(struct ethernet_req_params));
65		if (ret) {
66			LOG_ERR("Cannot %s Qav for queue %d for interface %p",
67			        enable ? "enable" : "disable",
68			        queue_id, iface);
69		}
70	}
71
72	static void qav_set_bandwidth_and_slope(struct net_if *iface,
73	                                        int queue_id,
74	                                        unsigned int bandwidth,
75	                                        unsigned int idle_slope)
76	{
77		struct ethernet_req_params params;
78		int ret;
79
80		memset(&params, 0, sizeof(params));
81
82		params.qav_param.queue_id = queue_id;
83		params.qav_param.delta_bandwidth = bandwidth;
84		params.qav_param.type = ETHERNET_QAV_PARAM_TYPE_DELTA_BANDWIDTH;
85
86		ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QAV_PARAM,
87			       iface, &params,
88			       sizeof(struct ethernet_req_params));
89		if (ret) {
90			LOG_ERR("Cannot set Qav delta bandwidth %u for "
91			        "queue %d for interface %p",
92			        bandwidth, queue_id, iface);
93		}
94
95		params.qav_param.idle_slope = idle_slope;
96		params.qav_param.type = ETHERNET_QAV_PARAM_TYPE_IDLE_SLOPE;
97
98		ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QAV_PARAM,
99			       iface, &params,
100			       sizeof(struct ethernet_req_params));
101		if (ret) {
102			LOG_ERR("Cannot set Qav idle slope %u for "
103			        "queue %d for interface %p",
104			        idle_slope, queue_id, iface);
105		}
106	}
107
108.. _IEEE 802.1Qav-2009 standard:
109   https://standards.ieee.org/standard/802_1Qav-2009.html
110