From: John Daley Date: Fri, 24 Jun 2016 22:29:28 +0000 (-0700) Subject: net/enic: update MTU for non-scattered Rx X-Git-Tag: spdx-start~6345 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=396a6d71e556cc5311f917ea494a0eecc4e9cce3;p=dpdk.git net/enic: update MTU for non-scattered Rx Provide an update MTU callback. The function returns -ENOTSUP if Rx scatter is enabled. Updating the MTU to be greater than the value configured via the Cisco CIMC/UCSM management interface is allowed provided it is still less than the maximum egress packet size allowed by the NIC minus the size of the L2 header. Signed-off-by: John Daley --- diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst index 38c130d95b..a23eb5cca4 100644 --- a/doc/guides/nics/overview.rst +++ b/doc/guides/nics/overview.rst @@ -92,7 +92,7 @@ Most of these differences are summarized below. Queue status event Y Rx interrupt Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Queue start/stop Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y - MTU update Y Y Y Y Y Y Y Y Y Y Y Y Y + MTU update Y Y Y Y Y Y Y Y Y Y Y Y Y Y Jumbo frame Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Scattered Rx Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y LRO Y Y Y Y diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 4c312c1d9b..060fe61854 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -275,4 +275,5 @@ uint16_t enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); +int enic_set_mtu(struct enic *enic, uint16_t new_mtu); #endif /* _ENIC_H_ */ diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c index 6fa54b21a5..a7ce064fd9 100644 --- a/drivers/net/enic/enic_ethdev.c +++ b/drivers/net/enic/enic_ethdev.c @@ -528,6 +528,14 @@ static void enicpmd_remove_mac_addr(struct rte_eth_dev *eth_dev, __rte_unused ui enic_del_mac_address(enic); } +static int enicpmd_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu) +{ + struct enic *enic = pmd_priv(eth_dev); + + ENICPMD_FUNC_TRACE(); + return enic_set_mtu(enic, mtu); +} + static const struct eth_dev_ops enicpmd_eth_dev_ops = { .dev_configure = enicpmd_dev_configure, .dev_start = enicpmd_dev_start, @@ -545,7 +553,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = { .queue_stats_mapping_set = NULL, .dev_infos_get = enicpmd_dev_info_get, .dev_supported_ptypes_get = enicpmd_dev_supported_ptypes_get, - .mtu_set = NULL, + .mtu_set = enicpmd_mtu_set, .vlan_filter_set = enicpmd_vlan_filter_set, .vlan_tpid_set = NULL, .vlan_offload_set = enicpmd_vlan_offload_set, diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 15389e5c97..4797fce8b9 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1040,6 +1040,50 @@ int enic_set_vnic_res(struct enic *enic) return rc; } +/* The Cisco NIC can send and receive packets up to a max packet size + * determined by the NIC type and firmware. There is also an MTU + * configured into the NIC via the CIMC/UCSM management interface + * which can be overridden by this function (up to the max packet size). + * Depending on the network setup, doing so may cause packet drops + * and unexpected behavior. + */ +int enic_set_mtu(struct enic *enic, uint16_t new_mtu) +{ + uint16_t old_mtu; /* previous setting */ + uint16_t config_mtu; /* Value configured into NIC via CIMC/UCSM */ + struct rte_eth_dev *eth_dev = enic->rte_dev; + + old_mtu = eth_dev->data->mtu; + config_mtu = enic->config.mtu; + + /* only works with Rx scatter disabled */ + if (enic->rte_dev->data->dev_conf.rxmode.enable_scatter) + return -ENOTSUP; + + if (new_mtu > enic->max_mtu) { + dev_err(enic, + "MTU not updated: requested (%u) greater than max (%u)\n", + new_mtu, enic->max_mtu); + return -EINVAL; + } + if (new_mtu < ENIC_MIN_MTU) { + dev_info(enic, + "MTU not updated: requested (%u) less than min (%u)\n", + new_mtu, ENIC_MIN_MTU); + return -EINVAL; + } + if (new_mtu > config_mtu) + dev_warning(enic, + "MTU (%u) is greater than value configured in NIC (%u)\n", + new_mtu, config_mtu); + + /* update the mtu */ + eth_dev->data->mtu = new_mtu; + + dev_info(enic, "MTU changed from %u to %u\n", old_mtu, new_mtu); + return 0; +} + static int enic_dev_init(struct enic *enic) { int err;