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 <johndale@cisco.com>
This commit is contained in:
John Daley 2016-06-24 15:29:27 -07:00 committed by Bruce Richardson
parent 9c9def9bfa
commit bb34ffb848
5 changed files with 39 additions and 11 deletions

View File

@ -35,6 +35,10 @@
#ifndef _VNIC_ENIC_H_ #ifndef _VNIC_ENIC_H_
#define _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 */ /* Device-specific region: enet configuration */
struct vnic_enet_config { struct vnic_enet_config {
u32 flags; u32 flags;
@ -50,6 +54,12 @@ struct vnic_enet_config {
u16 vf_rq_count; u16 vf_rq_count;
u16 num_arfs; u16 num_arfs;
u64 mem_paddr; 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 */ #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_IPV6_EX 0x200 /* Hash on IPv6 extended fields */
#define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */ #define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */
#define VENETF_LOOP 0x800 /* Loopback enabled */ #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_VXLAN 0x10000 /* VxLAN offload */
#define VENETF_NVGRE 0x20000 /* NVGRE 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_MIN 0 /* Timer specs min interrupt spacing */
#define VENET_INTR_TYPE_IDLE 1 /* Timer specs idle time before irq */ #define VENET_INTR_TYPE_IDLE 1 /* Timer specs idle time before irq */

View File

@ -128,6 +128,7 @@ struct enic {
u8 ig_vlan_strip_en; u8 ig_vlan_strip_en;
int link_status; int link_status;
u8 hw_ip_checksum; u8 hw_ip_checksum;
u16 max_mtu;
unsigned int flags; unsigned int flags;
unsigned int priv_flags; unsigned int priv_flags;

View 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_rx_queues = enic->rq_count;
device_info->max_tx_queues = enic->wq_count; device_info->max_tx_queues = enic->wq_count;
device_info->min_rx_bufsize = ENIC_MIN_MTU; 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->max_mac_addrs = 1;
device_info->rx_offload_capa = device_info->rx_offload_capa =
DEV_RX_OFFLOAD_VLAN_STRIP | DEV_RX_OFFLOAD_VLAN_STRIP |

View File

@ -83,6 +83,20 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(intr_timer_usec); GET_CONFIG(intr_timer_usec);
GET_CONFIG(loop_tag); GET_CONFIG(loop_tag);
GET_CONFIG(num_arfs); 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 = c->wq_desc_count =
min_t(u32, ENIC_MAX_WQ_DESCS, 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));
c->rq_desc_count &= 0xffffffe0; /* must be aligned to groups of 32 */ 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, c->intr_timer_usec = min_t(u32, c->intr_timer_usec,
vnic_dev_get_intr_coal_timer_max(enic->vdev)); vnic_dev_get_intr_coal_timer_max(enic->vdev));
dev_info(enic_get_dev(enic), dev_info(enic_get_dev(enic),
"vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x " "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[0], enic->mac_addr[1], enic->mac_addr[2],
enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5], 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 " dev_info(enic_get_dev(enic), "vNIC csum tx/rx %s/%s "
"rss %s intr mode %s type %s timer %d usec " "rss %s intr mode %s type %s timer %d usec "
"loopback tag 0x%04x\n", "loopback tag 0x%04x\n",

View File

@ -46,7 +46,9 @@
#define ENIC_MAX_RQ_DESCS 4096 #define ENIC_MAX_RQ_DESCS 4096
#define ENIC_MIN_MTU 68 #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_MULTICAST_PERFECT_FILTERS 32
#define ENIC_UNICAST_PERFECT_FILTERS 32 #define ENIC_UNICAST_PERFECT_FILTERS 32