The packets being received will not be dropped immediately when the WQEs are
exhausted in a Rx queue with delay drop enabled.
+ A timeout value is set in the driver to control the waiting time before
+ dropping a packet. Once the timer is expired, the delay drop will be
+ deactivated for all the Rx queues with this feature enable. To re-activeate
+ it, a rearming is needed and it is part of the kernel driver starting from
+ OFED 5.5.
+
+ To enable / disable the delay drop rearming, the private flag ``dropless_rq``
+ can be set and queried via ethtool:
+
+ - ethtool --set-priv-flags <netdev> dropless_rq on (/ off)
+ - ethtool --show-priv-flags <netdev>
+
+ The configuration flag is global per PF and can only be set on the PF, once
+ it is on, all the VFs', SFs' and representors' Rx queues will share the timer
+ and rearming.
+
- ``mprq_en`` parameter [int]
A nonzero value enables configuring Multi-Packet Rx queues. Rx queue is
memcpy(mac, request.ifr_hwaddr.sa_data, RTE_ETHER_ADDR_LEN);
return 0;
}
+
+/*
+ * Query dropless_rq private flag value provided by ETHTOOL.
+ *
+ * @param dev
+ * Pointer to Ethernet device.
+ *
+ * @return
+ * - 0 on success, flag is not set.
+ * - 1 on success, flag is set.
+ * - negative errno value otherwise and rte_errno is set.
+ */
+int mlx5_get_flag_dropless_rq(struct rte_eth_dev *dev)
+{
+ struct {
+ struct ethtool_sset_info hdr;
+ uint32_t buf[1];
+ } sset_info;
+ struct ethtool_drvinfo drvinfo;
+ struct ifreq ifr;
+ struct ethtool_gstrings *strings = NULL;
+ struct ethtool_value flags;
+ const int32_t flag_len = sizeof(flags.data) * CHAR_BIT;
+ int32_t str_sz;
+ int32_t len;
+ int32_t i;
+ int ret;
+
+ sset_info.hdr.cmd = ETHTOOL_GSSET_INFO;
+ sset_info.hdr.reserved = 0;
+ sset_info.hdr.sset_mask = 1ULL << ETH_SS_PRIV_FLAGS;
+ ifr.ifr_data = (caddr_t)&sset_info;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (!ret) {
+ const uint32_t *sset_lengths = sset_info.hdr.data;
+
+ len = sset_info.hdr.sset_mask ? sset_lengths[0] : 0;
+ } else if (ret == -EOPNOTSUPP) {
+ drvinfo.cmd = ETHTOOL_GDRVINFO;
+ ifr.ifr_data = (caddr_t)&drvinfo;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING, "port %u cannot get the driver info",
+ dev->data->port_id);
+ goto exit;
+ }
+ len = *(uint32_t *)((char *)&drvinfo +
+ offsetof(struct ethtool_drvinfo, n_priv_flags));
+ } else {
+ DRV_LOG(WARNING, "port %u cannot get the sset info",
+ dev->data->port_id);
+ goto exit;
+ }
+ if (!len) {
+ DRV_LOG(WARNING, "port %u does not have private flag",
+ dev->data->port_id);
+ rte_errno = EOPNOTSUPP;
+ ret = -rte_errno;
+ goto exit;
+ } else if (len > flag_len) {
+ DRV_LOG(WARNING, "port %u maximal private flags number is %d",
+ dev->data->port_id, flag_len);
+ len = flag_len;
+ }
+ str_sz = ETH_GSTRING_LEN * len;
+ strings = (struct ethtool_gstrings *)
+ mlx5_malloc(0, str_sz + sizeof(struct ethtool_gstrings), 0,
+ SOCKET_ID_ANY);
+ if (!strings) {
+ DRV_LOG(WARNING, "port %u unable to allocate memory for"
+ " private flags", dev->data->port_id);
+ rte_errno = ENOMEM;
+ ret = -rte_errno;
+ goto exit;
+ }
+ strings->cmd = ETHTOOL_GSTRINGS;
+ strings->string_set = ETH_SS_PRIV_FLAGS;
+ strings->len = len;
+ ifr.ifr_data = (caddr_t)strings;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING, "port %u unable to get private flags strings",
+ dev->data->port_id);
+ goto exit;
+ }
+ for (i = 0; i < len; i++) {
+ strings->data[(i + 1) * ETH_GSTRING_LEN - 1] = 0;
+ if (!strcmp((const char *)strings->data + i * ETH_GSTRING_LEN,
+ "dropless_rq"))
+ break;
+ }
+ if (i == len) {
+ DRV_LOG(WARNING, "port %u does not support dropless_rq",
+ dev->data->port_id);
+ rte_errno = EOPNOTSUPP;
+ ret = -rte_errno;
+ goto exit;
+ }
+ flags.cmd = ETHTOOL_GPFLAGS;
+ ifr.ifr_data = (caddr_t)&flags;
+ ret = mlx5_ifreq(dev, SIOCETHTOOL, &ifr);
+ if (ret) {
+ DRV_LOG(WARNING, "port %u unable to get private flags status",
+ dev->data->port_id);
+ goto exit;
+ }
+ ret = !!(flags.data & (1U << i));
+exit:
+ mlx5_free(strings);
+ return ret;
+}