This patch fixes issues related to MTU set and max_rx_pkt_len usage.
- Adjust MTU during device configuration when jumbo is enabled
- In qede_set_mtu():
Return not supported for VF as currently we do not support it.
Cache new mtu value in mtu_new for proper update.
Add check for RXQ allocation before calculating RX buffer size
if not allocated defer RX buffer size calculation till RXQ setup.
Add check for before performing device start/stop.
- Use max_rx_pkt_len appropriately
- Change QEDE_ETH_OVERHEAD macro to adjust driver specifics
Fixes:
4c4bdadfa9e7 ("net/qede: refactoring multi-queue implementation")
Fixes:
9a6d30ae6d46 ("net/qede: refactoring vport handling code")
Fixes:
1ef4c3a5c1f7 ("net/qede: prevent crash while changing MTU dynamically")
Cc: stable@dpdk.org
Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
+ /* If jumbo enabled adjust MTU */
+ if (eth_dev->data->dev_conf.rxmode.jumbo_frame)
+ eth_dev->data->mtu =
+ eth_dev->data->dev_conf.rxmode.max_rx_pkt_len -
+ ETHER_HDR_LEN - ETHER_CRC_LEN;
+
/* VF's MTU has to be set using vport-start where as
* PF's MTU can be updated via vport-update.
*/
if (IS_VF(edev)) {
/* VF's MTU has to be set using vport-start where as
* PF's MTU can be updated via vport-update.
*/
if (IS_VF(edev)) {
- if (qede_start_vport(qdev, rxmode->max_rx_pkt_len))
+ if (qede_start_vport(qdev, eth_dev->data->mtu))
- if (qede_update_mtu(eth_dev, rxmode->max_rx_pkt_len))
+ if (qede_update_mtu(eth_dev, eth_dev->data->mtu))
- qdev->mtu = rxmode->max_rx_pkt_len;
+ qdev->mtu = eth_dev->data->mtu;
qdev->new_mtu = qdev->mtu;
/* Enable VLAN offloads by default */
qdev->new_mtu = qdev->mtu;
/* Enable VLAN offloads by default */
struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
struct rte_eth_dev_info dev_info = {0};
struct qede_fastpath *fp;
struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
struct rte_eth_dev_info dev_info = {0};
struct qede_fastpath *fp;
+ uint32_t max_rx_pkt_len;
uint32_t frame_size;
uint16_t rx_buf_size;
uint16_t bufsz;
uint32_t frame_size;
uint16_t rx_buf_size;
uint16_t bufsz;
int i;
PMD_INIT_FUNC_TRACE(edev);
int i;
PMD_INIT_FUNC_TRACE(edev);
+ if (IS_VF(edev))
+ return -ENOTSUP;
qede_dev_info_get(dev, &dev_info);
qede_dev_info_get(dev, &dev_info);
- frame_size = mtu + QEDE_ETH_OVERHEAD;
+ max_rx_pkt_len = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+ frame_size = max_rx_pkt_len + QEDE_ETH_OVERHEAD;
if ((mtu < ETHER_MIN_MTU) || (frame_size > dev_info.max_rx_pktlen)) {
if ((mtu < ETHER_MIN_MTU) || (frame_size > dev_info.max_rx_pktlen)) {
- DP_ERR(edev, "MTU %u out of range\n", mtu);
+ DP_ERR(edev, "MTU %u out of range, %u is maximum allowable\n",
+ mtu, dev_info.max_rx_pktlen - ETHER_HDR_LEN -
+ ETHER_CRC_LEN - QEDE_ETH_OVERHEAD);
return -EINVAL;
}
if (!dev->data->scattered_rx &&
return -EINVAL;
}
if (!dev->data->scattered_rx &&
*/
dev->rx_pkt_burst = qede_rxtx_pkts_dummy;
dev->tx_pkt_burst = qede_rxtx_pkts_dummy;
*/
dev->rx_pkt_burst = qede_rxtx_pkts_dummy;
dev->tx_pkt_burst = qede_rxtx_pkts_dummy;
+ if (dev->data->dev_started) {
+ dev->data->dev_started = 0;
+ qede_dev_stop(dev);
+ restart = true;
+ }
/* Fix up RX buf size for all queues of the port */
for_each_rss(i) {
fp = &qdev->fp_array[i];
/* Fix up RX buf size for all queues of the port */
for_each_rss(i) {
fp = &qdev->fp_array[i];
- bufsz = (uint16_t)rte_pktmbuf_data_room_size(
- fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
- if (dev->data->scattered_rx)
- rx_buf_size = bufsz + QEDE_ETH_OVERHEAD;
- else
- rx_buf_size = mtu + QEDE_ETH_OVERHEAD;
- rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rx_buf_size);
- fp->rxq->rx_buf_size = rx_buf_size;
- DP_INFO(edev, "buf_size adjusted to %u\n", rx_buf_size);
- }
- qede_dev_start(dev);
- if (frame_size > ETHER_MAX_LEN)
+ if (fp->rxq != NULL) {
+ bufsz = (uint16_t)rte_pktmbuf_data_room_size(
+ fp->rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
+ if (dev->data->scattered_rx)
+ rx_buf_size = bufsz + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + QEDE_ETH_OVERHEAD;
+ else
+ rx_buf_size = frame_size;
+ rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rx_buf_size);
+ fp->rxq->rx_buf_size = rx_buf_size;
+ DP_INFO(edev, "buf_size adjusted to %u\n", rx_buf_size);
+ }
+ }
+ if (max_rx_pkt_len > ETHER_MAX_LEN)
dev->data->dev_conf.rxmode.jumbo_frame = 1;
else
dev->data->dev_conf.rxmode.jumbo_frame = 0;
dev->data->dev_conf.rxmode.jumbo_frame = 1;
else
dev->data->dev_conf.rxmode.jumbo_frame = 0;
+ if (!dev->data->dev_started && restart) {
+ qede_dev_start(dev);
+ dev->data->dev_started = 1;
+ }
/* update max frame size */
/* update max frame size */
- dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+ dev->data->dev_conf.rxmode.max_rx_pkt_len = max_rx_pkt_len;
/* Reassign back */
dev->rx_pkt_burst = qede_recv_pkts;
dev->tx_pkt_burst = qede_xmit_pkts;
/* Reassign back */
dev->rx_pkt_burst = qede_recv_pkts;
dev->tx_pkt_burst = qede_xmit_pkts;
rxq->port_id = dev->data->port_id;
max_rx_pkt_len = (uint16_t)rxmode->max_rx_pkt_len;
rxq->port_id = dev->data->port_id;
max_rx_pkt_len = (uint16_t)rxmode->max_rx_pkt_len;
- qdev->mtu = max_rx_pkt_len;
/* Fix up RX buffer size */
bufsz = (uint16_t)rte_pktmbuf_data_room_size(mp) - RTE_PKTMBUF_HEADROOM;
/* Fix up RX buffer size */
bufsz = (uint16_t)rte_pktmbuf_data_room_size(mp) - RTE_PKTMBUF_HEADROOM;
}
if (dev->data->scattered_rx)
}
if (dev->data->scattered_rx)
- rxq->rx_buf_size = bufsz + QEDE_ETH_OVERHEAD;
+ rxq->rx_buf_size = bufsz + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + QEDE_ETH_OVERHEAD;
- rxq->rx_buf_size = qdev->mtu + QEDE_ETH_OVERHEAD;
+ rxq->rx_buf_size = max_rx_pkt_len + QEDE_ETH_OVERHEAD;
/* Align to cache-line size if needed */
rxq->rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rxq->rx_buf_size);
/* Align to cache-line size if needed */
rxq->rx_buf_size = QEDE_CEIL_TO_CACHE_LINE_SIZE(rxq->rx_buf_size);
#define QEDE_CEIL_TO_CACHE_LINE_SIZE(n) (((n) + (QEDE_FW_RX_ALIGN_END - 1)) & \
~(QEDE_FW_RX_ALIGN_END - 1))
/* Note: QEDE_LLC_SNAP_HDR_LEN is optional */
#define QEDE_CEIL_TO_CACHE_LINE_SIZE(n) (((n) + (QEDE_FW_RX_ALIGN_END - 1)) & \
~(QEDE_FW_RX_ALIGN_END - 1))
/* Note: QEDE_LLC_SNAP_HDR_LEN is optional */
-#define QEDE_ETH_OVERHEAD ((ETHER_HDR_LEN) + ((2 * QEDE_VLAN_TAG_SIZE)) \
+#define QEDE_ETH_OVERHEAD (((2 * QEDE_VLAN_TAG_SIZE)) - (ETHER_CRC_LEN) \
+ (QEDE_LLC_SNAP_HDR_LEN))
#define QEDE_RSS_OFFLOAD_ALL (ETH_RSS_IPV4 |\
+ (QEDE_LLC_SNAP_HDR_LEN))
#define QEDE_RSS_OFFLOAD_ALL (ETH_RSS_IPV4 |\