net/enic: determine max egress packet size and max MTU
authorJohn Daley <johndale@cisco.com>
Fri, 24 Jun 2016 22:29:27 +0000 (15:29 -0700)
committerBruce Richardson <bruce.richardson@intel.com>
Wed, 29 Jun 2016 09:54:46 +0000 (11:54 +0200)
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 <johndale@cisco.com>
drivers/net/enic/base/vnic_enet.h
drivers/net/enic/enic.h
drivers/net/enic/enic_ethdev.c
drivers/net/enic/enic_res.c
drivers/net/enic/enic_res.h

index cc34998..5062247 100644 (file)
 #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 */
 
index ed5f18d..4c312c1 100644 (file)
@@ -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;
index 83048d8..6fa54b2 100644 (file)
@@ -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 |
index 42edd84..b271d34 100644 (file)
@@ -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",
index 3c8e303..303530e 100644 (file)
@@ -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