From bb34ffb848a01e2abe7300e9655ada109ffab62a Mon Sep 17 00:00:00 2001 From: John Daley Date: Fri, 24 Jun 2016 15:29:27 -0700 Subject: [PATCH] net/enic: determine max egress packet size and max MTU Pull in common VNIC code which enables querying for max egress packet size with newer firmware via a device command. If the field is non-zero, it is the max egress packet size. If it is 0, the default value (9022) can safely be assumed. The value for 1300 series VICS using firmware versions >= 3.1.2 for blade series and >= 2.0.13 for rack series servers is 9208. Tx buffers can be emitted only if they are less than the max egress packet size regardless of the MTU setting (the MTU is advisory). The max egress packet size can used to determine the upper limit of the MTU since the enic can also receive packets of size greater than max egress packet size. A max_mtu variable is added with a value of max egress packet size minus L2 header size. The default MTU is set via the CIMC/UCSM management interface and currently allows value up to 9000. If the value is changed, the host must be reboot. To avoid the reboot and allow MTU values up to the max capability of the NIC, MTU update capability will be added with a max value capped by max_mtu. Signed-off-by: John Daley --- drivers/net/enic/base/vnic_enet.h | 17 ++++++++++++++++- drivers/net/enic/enic.h | 1 + drivers/net/enic/enic_ethdev.c | 3 ++- drivers/net/enic/enic_res.c | 25 +++++++++++++++++-------- drivers/net/enic/enic_res.h | 4 +++- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/drivers/net/enic/base/vnic_enet.h b/drivers/net/enic/base/vnic_enet.h index cc34998fb9..506224792e 100644 --- a/drivers/net/enic/base/vnic_enet.h +++ b/drivers/net/enic/base/vnic_enet.h @@ -35,6 +35,10 @@ #ifndef _VNIC_ENIC_H_ #define _VNIC_ENIC_H_ +/* Hardware intr coalesce timer is in units of 1.5us */ +#define INTR_COALESCE_USEC_TO_HW(usec) ((usec) * 2 / 3) +#define INTR_COALESCE_HW_TO_USEC(usec) ((usec) * 3 / 2) + /* Device-specific region: enet configuration */ struct vnic_enet_config { u32 flags; @@ -50,6 +54,12 @@ struct vnic_enet_config { u16 vf_rq_count; u16 num_arfs; u64 mem_paddr; + u16 rdma_qp_id; + u16 rdma_qp_count; + u16 rdma_resgrp; + u32 rdma_mr_id; + u32 rdma_mr_count; + u32 max_pkt_size; }; #define VENETF_TSO 0x1 /* TSO enabled */ @@ -64,9 +74,14 @@ struct vnic_enet_config { #define VENETF_RSSHASH_IPV6_EX 0x200 /* Hash on IPv6 extended fields */ #define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */ #define VENETF_LOOP 0x800 /* Loopback enabled */ -#define VENETF_VMQ 0x4000 /* using VMQ flag for VMware NETQ */ +#define VENETF_FAILOVER 0x1000 /* Fabric failover enabled */ +#define VENETF_USPACE_NIC 0x2000 /* vHPC enabled */ +#define VENETF_VMQ 0x4000 /* VMQ enabled */ +#define VENETF_ARFS 0x8000 /* ARFS enabled */ #define VENETF_VXLAN 0x10000 /* VxLAN offload */ #define VENETF_NVGRE 0x20000 /* NVGRE offload */ +#define VENETF_GRPINTR 0x40000 /* group interrupt */ + #define VENET_INTR_TYPE_MIN 0 /* Timer specs min interrupt spacing */ #define VENET_INTR_TYPE_IDLE 1 /* Timer specs idle time before irq */ diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index ed5f18dcd6..4c312c1d9b 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -128,6 +128,7 @@ struct enic { u8 ig_vlan_strip_en; int link_status; u8 hw_ip_checksum; + u16 max_mtu; unsigned int flags; unsigned int priv_flags; diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c index 83048d8566..6fa54b21a5 100644 --- a/drivers/net/enic/enic_ethdev.c +++ b/drivers/net/enic/enic_ethdev.c @@ -439,7 +439,8 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev, device_info->max_rx_queues = enic->rq_count; device_info->max_tx_queues = enic->wq_count; device_info->min_rx_bufsize = ENIC_MIN_MTU; - device_info->max_rx_pktlen = enic->config.mtu; + device_info->max_rx_pktlen = enic->rte_dev->data->mtu + + ETHER_HDR_LEN + 4; device_info->max_mac_addrs = 1; device_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP | diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 42edd84a58..b271d340c8 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -83,6 +83,20 @@ int enic_get_vnic_config(struct enic *enic) GET_CONFIG(intr_timer_usec); GET_CONFIG(loop_tag); GET_CONFIG(num_arfs); + GET_CONFIG(max_pkt_size); + + /* max packet size is only defined in newer VIC firmware + * and will be 0 for legacy firmware and VICs + */ + if (c->max_pkt_size > ENIC_DEFAULT_MAX_PKT_SIZE) + enic->max_mtu = c->max_pkt_size - (ETHER_HDR_LEN + 4); + else + enic->max_mtu = ENIC_DEFAULT_MAX_PKT_SIZE - (ETHER_HDR_LEN + 4); + if (c->mtu == 0) + c->mtu = 1500; + + enic->rte_dev->data->mtu = min_t(u16, enic->max_mtu, + max_t(u16, ENIC_MIN_MTU, c->mtu)); c->wq_desc_count = min_t(u32, ENIC_MAX_WQ_DESCS, @@ -96,21 +110,16 @@ int enic_get_vnic_config(struct enic *enic) c->rq_desc_count)); c->rq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */ - if (c->mtu == 0) - c->mtu = 1500; - c->mtu = min_t(u16, ENIC_MAX_MTU, - max_t(u16, ENIC_MIN_MTU, - c->mtu)); - c->intr_timer_usec = min_t(u32, c->intr_timer_usec, vnic_dev_get_intr_coal_timer_max(enic->vdev)); dev_info(enic_get_dev(enic), "vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x " - "wq/rq %d/%d mtu %d\n", + "wq/rq %d/%d mtu %d, max mtu:%d\n", enic->mac_addr[0], enic->mac_addr[1], enic->mac_addr[2], enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5], - c->wq_desc_count, c->rq_desc_count, c->mtu); + c->wq_desc_count, c->rq_desc_count, + enic->rte_dev->data->mtu, enic->max_mtu); dev_info(enic_get_dev(enic), "vNIC csum tx/rx %s/%s " "rss %s intr mode %s type %s timer %d usec " "loopback tag 0x%04x\n", diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 3c8e303e5c..303530efbc 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h @@ -46,7 +46,9 @@ #define ENIC_MAX_RQ_DESCS 4096 #define ENIC_MIN_MTU 68 -#define ENIC_MAX_MTU 9000 + +/* Does not include (possible) inserted VLAN tag and FCS */ +#define ENIC_DEFAULT_MAX_PKT_SIZE 9022 #define ENIC_MULTICAST_PERFECT_FILTERS 32 #define ENIC_UNICAST_PERFECT_FILTERS 32 -- 2.20.1