struct rte_eth_dev *dev;
struct rte_eth_dev_info dev_info;
struct rte_eth_conf orig_conf;
+ uint16_t overhead_len;
int diag;
int ret;
+ uint16_t old_mtu;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
memcpy(&dev->data->dev_conf, dev_conf,
sizeof(dev->data->dev_conf));
+ /* Backup mtu for rollback */
+ old_mtu = dev->data->mtu;
+
ret = rte_eth_dev_info_get(port_id, &dev_info);
if (ret != 0)
goto rollback;
+ /* Get the real Ethernet overhead length */
+ if (dev_info.max_mtu != UINT16_MAX &&
+ dev_info.max_rx_pktlen > dev_info.max_mtu)
+ overhead_len = dev_info.max_rx_pktlen - dev_info.max_mtu;
+ else
+ overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
+
/* If number of queues specified by application for both Rx and Tx is
* zero, use driver preferred values. This cannot be done individually
* as it is valid for either Tx or Rx (but not both) to be zero.
ret = -EINVAL;
goto rollback;
}
+
+ /* Scale the MTU size to adapt max_rx_pkt_len */
+ dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len -
+ overhead_len;
} else {
- if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN ||
- dev_conf->rxmode.max_rx_pkt_len > RTE_ETHER_MAX_LEN)
+ uint16_t pktlen = dev_conf->rxmode.max_rx_pkt_len;
+ if (pktlen < RTE_ETHER_MIN_MTU + overhead_len ||
+ pktlen > RTE_ETHER_MTU + overhead_len)
/* Use default value */
dev->data->dev_conf.rxmode.max_rx_pkt_len =
- RTE_ETHER_MAX_LEN;
+ RTE_ETHER_MTU + overhead_len;
}
/*
eth_dev_tx_queue_config(dev, 0);
rollback:
memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf));
+ if (old_mtu != dev->data->mtu)
+ dev->data->mtu = old_mtu;
rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret);
return ret;