diff --git a/include/net/ethernet.h b/include/net/ethernet.h index f53e3befb72..c5d799489b2 100644 --- a/include/net/ethernet.h +++ b/include/net/ethernet.h @@ -75,6 +75,9 @@ enum ethernet_hw_caps { /** IEEE 802.1AS (gPTP) clock supported */ ETHERNET_PTP = BIT(8), + + /** IEEE 802.1Qav (credit-based shaping) supported */ + ETHERNET_QAV = BIT(9), }; enum ethernet_config_type { @@ -82,6 +85,16 @@ enum ethernet_config_type { ETHERNET_CONFIG_TYPE_LINK, ETHERNET_CONFIG_TYPE_DUPLEX, ETHERNET_CONFIG_TYPE_MAC_ADDRESS, + ETHERNET_CONFIG_TYPE_QAV_DELTA_BANDWIDTH, + ETHERNET_CONFIG_TYPE_QAV_IDLE_SLOPE, +}; + +struct ethernet_qav_queue_param { + int queue_id; + union { + unsigned int delta_bandwidth; + unsigned int idle_slope; + }; }; struct ethernet_config { @@ -97,6 +110,8 @@ struct ethernet_config { } l; struct net_eth_addr mac_address; + + struct ethernet_qav_queue_param qav_queue_param; }; /* @endcond */ }; diff --git a/include/net/ethernet_mgmt.h b/include/net/ethernet_mgmt.h index dcd919b8a01..995c5092e32 100644 --- a/include/net/ethernet_mgmt.h +++ b/include/net/ethernet_mgmt.h @@ -38,6 +38,8 @@ enum net_request_ethernet_cmd { NET_REQUEST_ETHERNET_CMD_SET_LINK, NET_REQUEST_ETHERNET_CMD_SET_DUPLEX, NET_REQUEST_ETHERNET_CMD_SET_MAC_ADDRESS, + NET_REQUEST_ETHERNET_CMD_SET_QAV_DELTA_BANDWIDTH, + NET_REQUEST_ETHERNET_CMD_SET_QAV_IDLE_SLOPE, }; #define NET_REQUEST_ETHERNET_SET_AUTO_NEGOTIATION \ @@ -60,7 +62,18 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_DUPLEX); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_MAC_ADDRESS); +#define NET_REQUEST_ETHERNET_SET_QAV_DELTA_BANDWIDTH \ + (_NET_ETHERNET_BASE | NET_REQUEST_ETHERNET_CMD_SET_QAV_DELTA_BANDWIDTH) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_QAV_DELTA_BANDWIDTH); + +#define NET_REQUEST_ETHERNET_SET_QAV_IDLE_SLOPE \ + (_NET_ETHERNET_BASE | NET_REQUEST_ETHERNET_CMD_SET_QAV_IDLE_SLOPE) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_QAV_IDLE_SLOPE); + struct net_eth_addr; +struct ethernet_qav_queue_param; struct ethernet_req_params { union { @@ -74,6 +87,8 @@ struct ethernet_req_params { } l; struct net_eth_addr mac_address; + + struct ethernet_qav_queue_param qav_queue_param; }; }; diff --git a/subsys/net/l2/ethernet/ethernet_mgmt.c b/subsys/net/l2/ethernet/ethernet_mgmt.c index cccaf02c186..a9abd8672ad 100644 --- a/subsys/net/l2/ethernet/ethernet_mgmt.c +++ b/subsys/net/l2/ethernet/ethernet_mgmt.c @@ -93,6 +93,28 @@ static int ethernet_set_config(u32_t mgmt_request, memcpy(&config.mac_address, ¶ms->mac_address, sizeof(struct net_eth_addr)); type = ETHERNET_CONFIG_TYPE_MAC_ADDRESS; + } else if (mgmt_request == + NET_REQUEST_ETHERNET_SET_QAV_DELTA_BANDWIDTH) { + if (!is_hw_caps_supported(dev, ETHERNET_QAV)) { + return -ENOTSUP; + } + + if (params->qav_queue_param.delta_bandwidth < 0 + || params->qav_queue_param.delta_bandwidth > 100) { + return -EINVAL; + } + + memcpy(&config.qav_queue_param, ¶ms->qav_queue_param, + sizeof(struct ethernet_qav_queue_param)); + type = ETHERNET_CONFIG_TYPE_QAV_DELTA_BANDWIDTH; + } else if (mgmt_request == NET_REQUEST_ETHERNET_SET_QAV_IDLE_SLOPE) { + if (!is_hw_caps_supported(dev, ETHERNET_QAV)) { + return -ENOTSUP; + } + + memcpy(&config.qav_queue_param, ¶ms->qav_queue_param, + sizeof(struct ethernet_qav_queue_param)); + type = ETHERNET_CONFIG_TYPE_QAV_IDLE_SLOPE; } else { return -EINVAL; } @@ -112,6 +134,12 @@ NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_DUPLEX, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_MAC_ADDRESS, ethernet_set_config); +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_QAV_DELTA_BANDWIDTH, + ethernet_set_config); + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_QAV_IDLE_SLOPE, + ethernet_set_config); + void ethernet_mgmt_raise_carrier_on_event(struct net_if *iface) { net_mgmt_event_notify(NET_EVENT_ETHERNET_CARRIER_ON, iface);