|  | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
|  | /**************************************************************************/ | 
|  | /*                                                                        */ | 
|  | /*  IBM System i and System p Virtual NIC Device Driver                   */ | 
|  | /*  Copyright (C) 2014 IBM Corp.                                          */ | 
|  | /*  Santiago Leon (santi_leon@yahoo.com)                                  */ | 
|  | /*  Thomas Falcon (tlfalcon@linux.vnet.ibm.com)                           */ | 
|  | /*  John Allen (jallen@linux.vnet.ibm.com)                                */ | 
|  | /*                                                                        */ | 
|  | /*                                                                        */ | 
|  | /* This module contains the implementation of a virtual ethernet device   */ | 
|  | /* for use with IBM i/pSeries LPAR Linux.  It utilizes the logical LAN    */ | 
|  | /* option of the RS/6000 Platform Architecture to interface with virtual */ | 
|  | /* ethernet NICs that are presented to the partition by the hypervisor.   */ | 
|  | /*                                                                        */ | 
|  | /**************************************************************************/ | 
|  |  | 
|  | #define IBMVNIC_NAME		"ibmvnic" | 
|  | #define IBMVNIC_DRIVER_VERSION	"1.0.1" | 
|  | #define IBMVNIC_INVALID_MAP	-1 | 
|  | #define IBMVNIC_OPEN_FAILED	3 | 
|  |  | 
|  | /* basic structures plus 100 2k buffers */ | 
|  | #define IBMVNIC_IO_ENTITLEMENT_DEFAULT	610305 | 
|  |  | 
|  | /* Initial module_parameters */ | 
|  | #define IBMVNIC_RX_WEIGHT		16 | 
|  | /* when changing this, update IBMVNIC_IO_ENTITLEMENT_DEFAULT */ | 
|  | #define IBMVNIC_BUFFS_PER_POOL	100 | 
|  | #define IBMVNIC_MAX_QUEUES	16 | 
|  | #define IBMVNIC_MAX_QUEUE_SZ   4096 | 
|  | #define IBMVNIC_MAX_IND_DESCS  16 | 
|  | #define IBMVNIC_IND_ARR_SZ	(IBMVNIC_MAX_IND_DESCS * 32) | 
|  |  | 
|  | #define IBMVNIC_TSO_BUF_SZ	65536 | 
|  | #define IBMVNIC_TSO_BUFS	64 | 
|  | #define IBMVNIC_TSO_POOL_MASK	0x80000000 | 
|  |  | 
|  | /* A VNIC adapter has set of Rx and Tx pools (aka queues). Each Rx/Tx pool | 
|  | * has a set of buffers. The size of each buffer is determined by the MTU. | 
|  | * | 
|  | * Each Rx/Tx pool is also associated with a DMA region that is shared | 
|  | * with the "hardware" (VIOS) and used to send/receive packets. The DMA | 
|  | * region is also referred to as a Long Term Buffer or LTB. | 
|  | * | 
|  | * The size of the DMA region required for an Rx/Tx pool depends on the | 
|  | * number and size (MTU) of the buffers in the pool. At the max levels | 
|  | * of 4096 jumbo frames (MTU=9000) we will need about 9K*4K = 36MB plus | 
|  | * some padding. | 
|  | * | 
|  | * But the size of a single DMA region is limited by MAX_ORDER in the | 
|  | * kernel (about 16MB currently).  To support say 4K Jumbo frames, we | 
|  | * use a set of LTBs (struct ltb_set) per pool. | 
|  | * | 
|  | * IBMVNIC_ONE_LTB_MAX  - max size of each LTB supported by kernel | 
|  | * IBMVNIC_ONE_LTB_SIZE - current max size of each LTB in an ltb_set | 
|  | * (must be <= IBMVNIC_ONE_LTB_MAX) | 
|  | * IBMVNIC_LTB_SET_SIZE - current size of all LTBs in an ltb_set | 
|  | * | 
|  | * Each VNIC can have upto 16 Rx, 16 Tx and 16 TSO pools. The TSO pools | 
|  | * are of fixed length (IBMVNIC_TSO_BUF_SZ * IBMVNIC_TSO_BUFS) of 4MB. | 
|  | * | 
|  | * The Rx and Tx pools can have upto 4096 buffers. The max size of these | 
|  | * buffers is about 9588 (for jumbo frames, including IBMVNIC_BUFFER_HLEN). | 
|  | * So, setting the IBMVNIC_LTB_SET_SIZE for a pool to 4096 * 9588 ~= 38MB. | 
|  | * | 
|  | * There is a trade-off in setting IBMVNIC_ONE_LTB_SIZE. If it is large, | 
|  | * the allocation of the LTB can fail when system is low in memory. If | 
|  | * its too small, we would need several mappings for each of the Rx/ | 
|  | * Tx/TSO pools but there is a limit of 255 mappings per vnic in the | 
|  | * VNIC protocol. | 
|  | * | 
|  | * So setting IBMVNIC_ONE_LTB_SIZE to 8MB. With IBMVNIC_LTB_SET_SIZE set | 
|  | * to 38MB, we will need 5 LTBs per Rx and Tx pool and 1 LTB per TSO | 
|  | * pool for the 4MB. Thus the 16 Rx and Tx queues require 32 * 5 = 160 | 
|  | * plus 16 for the TSO pools for a total of 176 LTB mappings per VNIC. | 
|  | */ | 
|  | #define IBMVNIC_ONE_LTB_MAX	((u32)((1 << (MAX_ORDER - 1)) * PAGE_SIZE)) | 
|  | #define IBMVNIC_ONE_LTB_SIZE	min((u32)(8 << 20), IBMVNIC_ONE_LTB_MAX) | 
|  | #define IBMVNIC_LTB_SET_SIZE	(38 << 20) | 
|  |  | 
|  | #define IBMVNIC_BUFFER_HLEN		500 | 
|  | #define IBMVNIC_RESET_DELAY 100 | 
|  |  | 
|  | struct ibmvnic_login_buffer { | 
|  | __be32 len; | 
|  | __be32 version; | 
|  | #define INITIAL_VERSION_LB 1 | 
|  | __be32 num_txcomp_subcrqs; | 
|  | __be32 off_txcomp_subcrqs; | 
|  | __be32 num_rxcomp_subcrqs; | 
|  | __be32 off_rxcomp_subcrqs; | 
|  | __be32 login_rsp_ioba; | 
|  | __be32 login_rsp_len; | 
|  | __be32 client_data_offset; | 
|  | __be32 client_data_len; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_login_rsp_buffer { | 
|  | __be32 len; | 
|  | __be32 version; | 
|  | #define INITIAL_VERSION_LRB 1 | 
|  | __be32 num_txsubm_subcrqs; | 
|  | __be32 off_txsubm_subcrqs; | 
|  | __be32 num_rxadd_subcrqs; | 
|  | __be32 off_rxadd_subcrqs; | 
|  | __be32 off_rxadd_buff_size; | 
|  | __be32 num_supp_tx_desc; | 
|  | __be32 off_supp_tx_desc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_query_ip_offload_buffer { | 
|  | __be32 len; | 
|  | __be32 version; | 
|  | #define INITIAL_VERSION_IOB 1 | 
|  | u8 ipv4_chksum; | 
|  | u8 ipv6_chksum; | 
|  | u8 tcp_ipv4_chksum; | 
|  | u8 tcp_ipv6_chksum; | 
|  | u8 udp_ipv4_chksum; | 
|  | u8 udp_ipv6_chksum; | 
|  | u8 large_tx_ipv4; | 
|  | u8 large_tx_ipv6; | 
|  | u8 large_rx_ipv4; | 
|  | u8 large_rx_ipv6; | 
|  | u8 reserved1[14]; | 
|  | __be16 max_ipv4_header_size; | 
|  | __be16 max_ipv6_header_size; | 
|  | __be16 max_tcp_header_size; | 
|  | __be16 max_udp_header_size; | 
|  | __be32 max_large_tx_size; | 
|  | __be32 max_large_rx_size; | 
|  | u8 reserved2[16]; | 
|  | u8 ipv6_extension_header; | 
|  | #define IPV6_EH_NOT_SUPPORTED	0x00 | 
|  | #define IPV6_EH_SUPPORTED_LIM	0x01 | 
|  | #define IPV6_EH_SUPPORTED	0xFF | 
|  | u8 tcp_pseudosum_req; | 
|  | #define TCP_PS_NOT_REQUIRED	0x00 | 
|  | #define TCP_PS_REQUIRED		0x01 | 
|  | u8 reserved3[30]; | 
|  | __be16 num_ipv6_ext_headers; | 
|  | __be32 off_ipv6_ext_headers; | 
|  | u8 reserved4[154]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_control_ip_offload_buffer { | 
|  | __be32 len; | 
|  | __be32 version; | 
|  | #define INITIAL_VERSION_IOB 1 | 
|  | u8 ipv4_chksum; | 
|  | u8 ipv6_chksum; | 
|  | u8 tcp_ipv4_chksum; | 
|  | u8 tcp_ipv6_chksum; | 
|  | u8 udp_ipv4_chksum; | 
|  | u8 udp_ipv6_chksum; | 
|  | u8 large_tx_ipv4; | 
|  | u8 large_tx_ipv6; | 
|  | u8 bad_packet_rx; | 
|  | u8 large_rx_ipv4; | 
|  | u8 large_rx_ipv6; | 
|  | u8 reserved4[111]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_fw_component { | 
|  | u8 name[48]; | 
|  | __be32 trace_buff_size; | 
|  | u8 correlator; | 
|  | u8 trace_level; | 
|  | u8 parent_correlator; | 
|  | u8 error_check_level; | 
|  | u8 trace_on; | 
|  | u8 reserved[7]; | 
|  | u8 description[192]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_fw_trace_entry { | 
|  | __be32 trace_id; | 
|  | u8 num_valid_data; | 
|  | u8 reserved[3]; | 
|  | __be64 pmc_registers; | 
|  | __be64 timebase; | 
|  | __be64 trace_data[5]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_statistics { | 
|  | __be32 version; | 
|  | __be32 promiscuous; | 
|  | __be64 rx_packets; | 
|  | __be64 rx_bytes; | 
|  | __be64 tx_packets; | 
|  | __be64 tx_bytes; | 
|  | __be64 ucast_tx_packets; | 
|  | __be64 ucast_rx_packets; | 
|  | __be64 mcast_tx_packets; | 
|  | __be64 mcast_rx_packets; | 
|  | __be64 bcast_tx_packets; | 
|  | __be64 bcast_rx_packets; | 
|  | __be64 align_errors; | 
|  | __be64 fcs_errors; | 
|  | __be64 single_collision_frames; | 
|  | __be64 multi_collision_frames; | 
|  | __be64 sqe_test_errors; | 
|  | __be64 deferred_tx; | 
|  | __be64 late_collisions; | 
|  | __be64 excess_collisions; | 
|  | __be64 internal_mac_tx_errors; | 
|  | __be64 carrier_sense; | 
|  | __be64 too_long_frames; | 
|  | __be64 internal_mac_rx_errors; | 
|  | u8 reserved[72]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | #define NUM_TX_STATS 3 | 
|  | struct ibmvnic_tx_queue_stats { | 
|  | u64 batched_packets; | 
|  | u64 direct_packets; | 
|  | u64 bytes; | 
|  | u64 dropped_packets; | 
|  | }; | 
|  |  | 
|  | #define NUM_RX_STATS 3 | 
|  | struct ibmvnic_rx_queue_stats { | 
|  | u64 packets; | 
|  | u64 bytes; | 
|  | u64 interrupts; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_acl_buffer { | 
|  | __be32 len; | 
|  | __be32 version; | 
|  | #define INITIAL_VERSION_IOB 1 | 
|  | u8 mac_acls_restrict; | 
|  | u8 vlan_acls_restrict; | 
|  | u8 reserved1[22]; | 
|  | __be32 num_mac_addrs; | 
|  | __be32 offset_mac_addrs; | 
|  | __be32 num_vlan_ids; | 
|  | __be32 offset_vlan_ids; | 
|  | u8 reserved2[80]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | /* descriptors have been changed, how should this be defined?  1? 4? */ | 
|  |  | 
|  | #define IBMVNIC_TX_DESC_VERSIONS 3 | 
|  |  | 
|  | /* is this still needed? */ | 
|  | struct ibmvnic_tx_comp_desc { | 
|  | u8 first; | 
|  | u8 num_comps; | 
|  | __be16 rcs[5]; | 
|  | __be32 correlators[5]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | /* some flags that included in v0 descriptor, which is gone | 
|  | * only used for IBMVNIC_TCP_CHKSUM and IBMVNIC_UDP_CHKSUM | 
|  | * and only in some offload_flags variable that doesn't seem | 
|  | * to be used anywhere, can probably be removed? | 
|  | */ | 
|  |  | 
|  | #define IBMVNIC_TCP_CHKSUM		0x20 | 
|  | #define IBMVNIC_UDP_CHKSUM		0x08 | 
|  |  | 
|  | struct ibmvnic_tx_desc { | 
|  | u8 first; | 
|  | u8 type; | 
|  |  | 
|  | #define IBMVNIC_TX_DESC 0x10 | 
|  | u8 n_crq_elem; | 
|  | u8 n_sge; | 
|  | u8 flags1; | 
|  | #define IBMVNIC_TX_COMP_NEEDED		0x80 | 
|  | #define IBMVNIC_TX_CHKSUM_OFFLOAD	0x40 | 
|  | #define IBMVNIC_TX_LSO			0x20 | 
|  | #define IBMVNIC_TX_PROT_TCP		0x10 | 
|  | #define IBMVNIC_TX_PROT_UDP		0x08 | 
|  | #define IBMVNIC_TX_PROT_IPV4		0x04 | 
|  | #define IBMVNIC_TX_PROT_IPV6		0x02 | 
|  | #define IBMVNIC_TX_VLAN_PRESENT		0x01 | 
|  | u8 flags2; | 
|  | #define IBMVNIC_TX_VLAN_INSERT		0x80 | 
|  | __be16 mss; | 
|  | u8 reserved[4]; | 
|  | __be32 correlator; | 
|  | __be16 vlan_id; | 
|  | __be16 dma_reg; | 
|  | __be32 sge_len; | 
|  | __be64 ioba; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_hdr_desc { | 
|  | u8 first; | 
|  | u8 type; | 
|  | #define IBMVNIC_HDR_DESC		0x11 | 
|  | u8 len; | 
|  | u8 l2_len; | 
|  | __be16 l3_len; | 
|  | u8 l4_len; | 
|  | u8 flag; | 
|  | u8 data[24]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_hdr_ext_desc { | 
|  | u8 first; | 
|  | u8 type; | 
|  | #define IBMVNIC_HDR_EXT_DESC		0x12 | 
|  | u8 len; | 
|  | u8 data[29]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_sge_desc { | 
|  | u8 first; | 
|  | u8 type; | 
|  | #define IBMVNIC_SGE_DESC		0x30 | 
|  | __be16 sge1_dma_reg; | 
|  | __be32 sge1_len; | 
|  | __be64 sge1_ioba; | 
|  | __be16 reserved; | 
|  | __be16 sge2_dma_reg; | 
|  | __be32 sge2_len; | 
|  | __be64 sge2_ioba; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_rx_comp_desc { | 
|  | u8 first; | 
|  | u8 flags; | 
|  | #define IBMVNIC_IP_CHKSUM_GOOD		0x80 | 
|  | #define IBMVNIC_TCP_UDP_CHKSUM_GOOD	0x40 | 
|  | #define IBMVNIC_END_FRAME			0x20 | 
|  | #define IBMVNIC_EXACT_MC			0x10 | 
|  | #define IBMVNIC_VLAN_STRIPPED			0x08 | 
|  | __be16 off_frame_data; | 
|  | __be32 len; | 
|  | __be64 correlator; | 
|  | __be16 vlan_tci; | 
|  | __be16 rc; | 
|  | u8 reserved[12]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_generic_scrq { | 
|  | u8 first; | 
|  | u8 reserved[31]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_rx_buff_add_desc { | 
|  | u8 first; | 
|  | u8 reserved[7]; | 
|  | __be64 correlator; | 
|  | __be32 ioba; | 
|  | u8 map_id; | 
|  | __be32 len:24; | 
|  | u8 reserved2[8]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_rc { | 
|  | u8 code; /* one of enum ibmvnic_rc_codes */ | 
|  | u8 detailed_data[3]; | 
|  | } __packed __aligned(4); | 
|  |  | 
|  | struct ibmvnic_generic_crq { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 params[10]; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_version_exchange { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | __be16 version; | 
|  | #define IBMVNIC_INITIAL_VERSION 1 | 
|  | u8 reserved[8]; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_capability { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | __be16 capability; /* one of ibmvnic_capabilities */ | 
|  | __be64 number; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_login { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved[6]; | 
|  | __be32 ioba; | 
|  | __be32 len; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_phys_parms { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 flags1; | 
|  | #define IBMVNIC_EXTERNAL_LOOPBACK	0x80 | 
|  | #define IBMVNIC_INTERNAL_LOOPBACK	0x40 | 
|  | #define IBMVNIC_PROMISC		0x20 | 
|  | #define IBMVNIC_PHYS_LINK_ACTIVE	0x10 | 
|  | #define IBMVNIC_AUTONEG_DUPLEX	0x08 | 
|  | #define IBMVNIC_FULL_DUPLEX	0x04 | 
|  | #define IBMVNIC_HALF_DUPLEX	0x02 | 
|  | #define IBMVNIC_CAN_CHG_PHYS_PARMS	0x01 | 
|  | u8 flags2; | 
|  | #define IBMVNIC_LOGICAL_LNK_ACTIVE 0x80 | 
|  | __be32 speed; | 
|  | #define IBMVNIC_AUTONEG		0x80000000 | 
|  | #define IBMVNIC_10MBPS		0x40000000 | 
|  | #define IBMVNIC_100MBPS		0x20000000 | 
|  | #define IBMVNIC_1GBPS		0x10000000 | 
|  | #define IBMVNIC_10GBPS		0x08000000 | 
|  | #define IBMVNIC_40GBPS		0x04000000 | 
|  | #define IBMVNIC_100GBPS		0x02000000 | 
|  | #define IBMVNIC_25GBPS		0x01000000 | 
|  | #define IBMVNIC_50GBPS		0x00800000 | 
|  | #define IBMVNIC_200GBPS		0x00400000 | 
|  | __be32 mtu; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_logical_link_state { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 link_state; | 
|  | #define IBMVNIC_LOGICAL_LNK_DN 0x00 | 
|  | #define IBMVNIC_LOGICAL_LNK_UP 0x01 | 
|  | #define IBMVNIC_LOGICAL_LNK_QUERY 0xff | 
|  | u8 reserved[9]; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_query_ip_offload { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved[2]; | 
|  | __be32 len; | 
|  | __be32 ioba; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_control_ip_offload { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved[2]; | 
|  | __be32 ioba; | 
|  | __be32 len; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_request_statistics { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 flags; | 
|  | #define IBMVNIC_PHYSICAL_PORT	0x80 | 
|  | u8 reserved1; | 
|  | __be32 ioba; | 
|  | __be32 len; | 
|  | u8 reserved[4]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_error_indication { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 flags; | 
|  | #define IBMVNIC_FATAL_ERROR	0x80 | 
|  | u8 reserved1; | 
|  | __be32 error_id; | 
|  | __be32 detail_error_sz; | 
|  | __be16 error_cause; | 
|  | u8 reserved2[2]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_link_state_indication { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved1[2]; | 
|  | u8 phys_link_state; | 
|  | u8 logical_link_state; | 
|  | u8 reserved2[10]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_change_mac_addr { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 mac_addr[6]; | 
|  | u8 reserved[4]; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_multicast_ctrl { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 mac_addr[6]; | 
|  | u8 flags; | 
|  | #define IBMVNIC_ENABLE_MC		0x80 | 
|  | #define IBMVNIC_DISABLE_MC		0x40 | 
|  | #define IBMVNIC_ENABLE_ALL		0x20 | 
|  | #define IBMVNIC_DISABLE_ALL	0x10 | 
|  | u8 reserved1; | 
|  | __be16 reserved2; /* was num_enabled_mc_addr; */ | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_get_vpd_size { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved[14]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_get_vpd_size_rsp { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved[2]; | 
|  | __be64 len; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_get_vpd { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved1[2]; | 
|  | __be32 ioba; | 
|  | __be32 len; | 
|  | u8 reserved[4]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_get_vpd_rsp { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved[10]; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_acl_change_indication { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | __be16 change_type; | 
|  | #define IBMVNIC_MAC_ACL 0 | 
|  | #define IBMVNIC_VLAN_ACL 1 | 
|  | u8 reserved[12]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_acl_query { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved1[2]; | 
|  | __be32 ioba; | 
|  | __be32 len; | 
|  | u8 reserved2[4]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_tune { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved1[2]; | 
|  | __be32 ioba; | 
|  | __be32 len; | 
|  | u8 reserved2[4]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_request_map { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved1; | 
|  | u8 map_id; | 
|  | __be32 ioba; | 
|  | __be32 len; | 
|  | u8 reserved2[4]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_request_map_rsp { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved1; | 
|  | u8 map_id; | 
|  | u8 reserved2[8]; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_request_unmap { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved1; | 
|  | u8 map_id; | 
|  | u8 reserved2[12]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_request_unmap_rsp { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved1; | 
|  | u8 map_id; | 
|  | u8 reserved2[8]; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_query_map { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved[14]; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | struct ibmvnic_query_map_rsp { | 
|  | u8 first; | 
|  | u8 cmd; | 
|  | u8 reserved; | 
|  | u8 page_size; | 
|  | __be32 tot_pages; | 
|  | __be32 free_pages; | 
|  | struct ibmvnic_rc rc; | 
|  | } __packed __aligned(8); | 
|  |  | 
|  | union ibmvnic_crq { | 
|  | struct ibmvnic_generic_crq generic; | 
|  | struct ibmvnic_version_exchange version_exchange; | 
|  | struct ibmvnic_version_exchange version_exchange_rsp; | 
|  | struct ibmvnic_capability query_capability; | 
|  | struct ibmvnic_capability query_capability_rsp; | 
|  | struct ibmvnic_capability request_capability; | 
|  | struct ibmvnic_capability request_capability_rsp; | 
|  | struct ibmvnic_login login; | 
|  | struct ibmvnic_generic_crq login_rsp; | 
|  | struct ibmvnic_phys_parms query_phys_parms; | 
|  | struct ibmvnic_phys_parms query_phys_parms_rsp; | 
|  | struct ibmvnic_phys_parms query_phys_capabilities; | 
|  | struct ibmvnic_phys_parms query_phys_capabilities_rsp; | 
|  | struct ibmvnic_phys_parms set_phys_parms; | 
|  | struct ibmvnic_phys_parms set_phys_parms_rsp; | 
|  | struct ibmvnic_logical_link_state logical_link_state; | 
|  | struct ibmvnic_logical_link_state logical_link_state_rsp; | 
|  | struct ibmvnic_query_ip_offload query_ip_offload; | 
|  | struct ibmvnic_query_ip_offload query_ip_offload_rsp; | 
|  | struct ibmvnic_control_ip_offload control_ip_offload; | 
|  | struct ibmvnic_control_ip_offload control_ip_offload_rsp; | 
|  | struct ibmvnic_request_statistics request_statistics; | 
|  | struct ibmvnic_generic_crq request_statistics_rsp; | 
|  | struct ibmvnic_error_indication error_indication; | 
|  | struct ibmvnic_link_state_indication link_state_indication; | 
|  | struct ibmvnic_change_mac_addr change_mac_addr; | 
|  | struct ibmvnic_change_mac_addr change_mac_addr_rsp; | 
|  | struct ibmvnic_multicast_ctrl multicast_ctrl; | 
|  | struct ibmvnic_multicast_ctrl multicast_ctrl_rsp; | 
|  | struct ibmvnic_get_vpd_size get_vpd_size; | 
|  | struct ibmvnic_get_vpd_size_rsp get_vpd_size_rsp; | 
|  | struct ibmvnic_get_vpd get_vpd; | 
|  | struct ibmvnic_get_vpd_rsp get_vpd_rsp; | 
|  | struct ibmvnic_acl_change_indication acl_change_indication; | 
|  | struct ibmvnic_acl_query acl_query; | 
|  | struct ibmvnic_generic_crq acl_query_rsp; | 
|  | struct ibmvnic_tune tune; | 
|  | struct ibmvnic_generic_crq tune_rsp; | 
|  | struct ibmvnic_request_map request_map; | 
|  | struct ibmvnic_request_map_rsp request_map_rsp; | 
|  | struct ibmvnic_request_unmap request_unmap; | 
|  | struct ibmvnic_request_unmap_rsp request_unmap_rsp; | 
|  | struct ibmvnic_query_map query_map; | 
|  | struct ibmvnic_query_map_rsp query_map_rsp; | 
|  | }; | 
|  |  | 
|  | enum ibmvnic_rc_codes { | 
|  | SUCCESS = 0, | 
|  | PARTIALSUCCESS = 1, | 
|  | PERMISSION = 2, | 
|  | NOMEMORY = 3, | 
|  | PARAMETER = 4, | 
|  | UNKNOWNCOMMAND = 5, | 
|  | ABORTED = 6, | 
|  | INVALIDSTATE = 7, | 
|  | INVALIDIOBA = 8, | 
|  | INVALIDLENGTH = 9, | 
|  | UNSUPPORTEDOPTION = 10, | 
|  | }; | 
|  |  | 
|  | enum ibmvnic_capabilities { | 
|  | MIN_TX_QUEUES = 1, | 
|  | MIN_RX_QUEUES = 2, | 
|  | MIN_RX_ADD_QUEUES = 3, | 
|  | MAX_TX_QUEUES = 4, | 
|  | MAX_RX_QUEUES = 5, | 
|  | MAX_RX_ADD_QUEUES = 6, | 
|  | REQ_TX_QUEUES = 7, | 
|  | REQ_RX_QUEUES = 8, | 
|  | REQ_RX_ADD_QUEUES = 9, | 
|  | MIN_TX_ENTRIES_PER_SUBCRQ = 10, | 
|  | MIN_RX_ADD_ENTRIES_PER_SUBCRQ = 11, | 
|  | MAX_TX_ENTRIES_PER_SUBCRQ = 12, | 
|  | MAX_RX_ADD_ENTRIES_PER_SUBCRQ = 13, | 
|  | REQ_TX_ENTRIES_PER_SUBCRQ = 14, | 
|  | REQ_RX_ADD_ENTRIES_PER_SUBCRQ = 15, | 
|  | TCP_IP_OFFLOAD = 16, | 
|  | PROMISC_REQUESTED = 17, | 
|  | PROMISC_SUPPORTED = 18, | 
|  | MIN_MTU = 19, | 
|  | MAX_MTU = 20, | 
|  | REQ_MTU = 21, | 
|  | MAX_MULTICAST_FILTERS = 22, | 
|  | VLAN_HEADER_INSERTION = 23, | 
|  | RX_VLAN_HEADER_INSERTION = 24, | 
|  | MAX_TX_SG_ENTRIES = 25, | 
|  | RX_SG_SUPPORTED = 26, | 
|  | RX_SG_REQUESTED = 27, | 
|  | OPT_TX_COMP_SUB_QUEUES = 28, | 
|  | OPT_RX_COMP_QUEUES = 29, | 
|  | OPT_RX_BUFADD_Q_PER_RX_COMP_Q = 30, | 
|  | OPT_TX_ENTRIES_PER_SUBCRQ = 31, | 
|  | OPT_RXBA_ENTRIES_PER_SUBCRQ = 32, | 
|  | TX_RX_DESC_REQ = 33, | 
|  | }; | 
|  |  | 
|  | enum ibmvnic_error_cause { | 
|  | ADAPTER_PROBLEM = 0, | 
|  | BUS_PROBLEM = 1, | 
|  | FW_PROBLEM = 2, | 
|  | DD_PROBLEM = 3, | 
|  | EEH_RECOVERY = 4, | 
|  | FW_UPDATED = 5, | 
|  | LOW_MEMORY = 6, | 
|  | }; | 
|  |  | 
|  | enum ibmvnic_commands { | 
|  | VERSION_EXCHANGE = 0x01, | 
|  | VERSION_EXCHANGE_RSP = 0x81, | 
|  | QUERY_CAPABILITY = 0x02, | 
|  | QUERY_CAPABILITY_RSP = 0x82, | 
|  | REQUEST_CAPABILITY = 0x03, | 
|  | REQUEST_CAPABILITY_RSP = 0x83, | 
|  | LOGIN = 0x04, | 
|  | LOGIN_RSP = 0x84, | 
|  | QUERY_PHYS_PARMS = 0x05, | 
|  | QUERY_PHYS_PARMS_RSP = 0x85, | 
|  | QUERY_PHYS_CAPABILITIES = 0x06, | 
|  | QUERY_PHYS_CAPABILITIES_RSP = 0x86, | 
|  | SET_PHYS_PARMS = 0x07, | 
|  | SET_PHYS_PARMS_RSP = 0x87, | 
|  | ERROR_INDICATION = 0x08, | 
|  | LOGICAL_LINK_STATE = 0x0C, | 
|  | LOGICAL_LINK_STATE_RSP = 0x8C, | 
|  | REQUEST_STATISTICS = 0x0D, | 
|  | REQUEST_STATISTICS_RSP = 0x8D, | 
|  | COLLECT_FW_TRACE = 0x11, | 
|  | COLLECT_FW_TRACE_RSP = 0x91, | 
|  | LINK_STATE_INDICATION = 0x12, | 
|  | CHANGE_MAC_ADDR = 0x13, | 
|  | CHANGE_MAC_ADDR_RSP = 0x93, | 
|  | MULTICAST_CTRL = 0x14, | 
|  | MULTICAST_CTRL_RSP = 0x94, | 
|  | GET_VPD_SIZE = 0x15, | 
|  | GET_VPD_SIZE_RSP = 0x95, | 
|  | GET_VPD = 0x16, | 
|  | GET_VPD_RSP = 0x96, | 
|  | TUNE = 0x17, | 
|  | TUNE_RSP = 0x97, | 
|  | QUERY_IP_OFFLOAD = 0x18, | 
|  | QUERY_IP_OFFLOAD_RSP = 0x98, | 
|  | CONTROL_IP_OFFLOAD = 0x19, | 
|  | CONTROL_IP_OFFLOAD_RSP = 0x99, | 
|  | ACL_CHANGE_INDICATION = 0x1A, | 
|  | ACL_QUERY = 0x1B, | 
|  | ACL_QUERY_RSP = 0x9B, | 
|  | QUERY_MAP = 0x1D, | 
|  | QUERY_MAP_RSP = 0x9D, | 
|  | REQUEST_MAP = 0x1E, | 
|  | REQUEST_MAP_RSP = 0x9E, | 
|  | REQUEST_UNMAP = 0x1F, | 
|  | REQUEST_UNMAP_RSP = 0x9F, | 
|  | VLAN_CTRL = 0x20, | 
|  | VLAN_CTRL_RSP = 0xA0, | 
|  | }; | 
|  |  | 
|  | enum ibmvnic_crq_type { | 
|  | IBMVNIC_CRQ_CMD			= 0x80, | 
|  | IBMVNIC_CRQ_CMD_RSP		= 0x80, | 
|  | IBMVNIC_CRQ_INIT_CMD		= 0xC0, | 
|  | IBMVNIC_CRQ_INIT_RSP		= 0xC0, | 
|  | IBMVNIC_CRQ_XPORT_EVENT		= 0xFF, | 
|  | }; | 
|  |  | 
|  | enum ibmvfc_crq_format { | 
|  | IBMVNIC_CRQ_INIT                 = 0x01, | 
|  | IBMVNIC_CRQ_INIT_COMPLETE        = 0x02, | 
|  | IBMVNIC_PARTITION_MIGRATED       = 0x06, | 
|  | IBMVNIC_DEVICE_FAILOVER          = 0x08, | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_crq_queue { | 
|  | union ibmvnic_crq *msgs; | 
|  | int size, cur; | 
|  | dma_addr_t msg_token; | 
|  | /* Used for serialization of msgs, cur */ | 
|  | spinlock_t lock; | 
|  | bool active; | 
|  | char name[32]; | 
|  | }; | 
|  |  | 
|  | union sub_crq { | 
|  | struct ibmvnic_generic_scrq generic; | 
|  | struct ibmvnic_tx_comp_desc tx_comp; | 
|  | struct ibmvnic_tx_desc v1; | 
|  | struct ibmvnic_hdr_desc hdr; | 
|  | struct ibmvnic_hdr_ext_desc hdr_ext; | 
|  | struct ibmvnic_sge_desc sge; | 
|  | struct ibmvnic_rx_comp_desc rx_comp; | 
|  | struct ibmvnic_rx_buff_add_desc rx_add; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_ind_xmit_queue { | 
|  | union sub_crq *indir_arr; | 
|  | dma_addr_t indir_dma; | 
|  | int index; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_sub_crq_queue { | 
|  | union sub_crq *msgs; | 
|  | int size, cur; | 
|  | dma_addr_t msg_token; | 
|  | unsigned long crq_num; | 
|  | unsigned long hw_irq; | 
|  | unsigned int irq; | 
|  | unsigned int pool_index; | 
|  | int scrq_num; | 
|  | /* Used for serialization of msgs, cur */ | 
|  | spinlock_t lock; | 
|  | struct sk_buff *rx_skb_top; | 
|  | struct ibmvnic_adapter *adapter; | 
|  | struct ibmvnic_ind_xmit_queue ind_buf; | 
|  | atomic_t used; | 
|  | char name[32]; | 
|  | u64 handle; | 
|  | } ____cacheline_aligned; | 
|  |  | 
|  | struct ibmvnic_long_term_buff { | 
|  | unsigned char *buff; | 
|  | dma_addr_t addr; | 
|  | u64 size; | 
|  | u8 map_id; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_ltb_set { | 
|  | int num_ltbs; | 
|  | struct ibmvnic_long_term_buff *ltbs; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_tx_buff { | 
|  | struct sk_buff *skb; | 
|  | int index; | 
|  | int pool_index; | 
|  | int num_entries; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_tx_pool { | 
|  | struct ibmvnic_tx_buff *tx_buff; | 
|  | int *free_map; | 
|  | int consumer_index; | 
|  | int producer_index; | 
|  | struct ibmvnic_ltb_set ltb_set; | 
|  | int num_buffers; | 
|  | int buf_size; | 
|  | } ____cacheline_aligned; | 
|  |  | 
|  | struct ibmvnic_rx_buff { | 
|  | struct sk_buff *skb; | 
|  | dma_addr_t dma; | 
|  | unsigned char *data; | 
|  | int size; | 
|  | int pool_index; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_rx_pool { | 
|  | struct ibmvnic_rx_buff *rx_buff; | 
|  | int size;			/* # of buffers in the pool */ | 
|  | int index; | 
|  | int buff_size; | 
|  | atomic_t available; | 
|  | int *free_map; | 
|  | int next_free; | 
|  | int next_alloc; | 
|  | int active; | 
|  | struct ibmvnic_ltb_set ltb_set; | 
|  | } ____cacheline_aligned; | 
|  |  | 
|  | struct ibmvnic_vpd { | 
|  | unsigned char *buff; | 
|  | dma_addr_t dma_addr; | 
|  | u64 len; | 
|  | }; | 
|  |  | 
|  | enum vnic_state {VNIC_PROBING = 1, | 
|  | VNIC_PROBED, | 
|  | VNIC_OPENING, | 
|  | VNIC_OPEN, | 
|  | VNIC_CLOSING, | 
|  | VNIC_CLOSED, | 
|  | VNIC_REMOVING, | 
|  | VNIC_REMOVED, | 
|  | VNIC_DOWN}; | 
|  |  | 
|  | enum ibmvnic_reset_reason {VNIC_RESET_FAILOVER = 1, | 
|  | VNIC_RESET_MOBILITY, | 
|  | VNIC_RESET_FATAL, | 
|  | VNIC_RESET_NON_FATAL, | 
|  | VNIC_RESET_TIMEOUT, | 
|  | VNIC_RESET_CHANGE_PARAM, | 
|  | VNIC_RESET_PASSIVE_INIT}; | 
|  |  | 
|  | struct ibmvnic_rwi { | 
|  | enum ibmvnic_reset_reason reset_reason; | 
|  | struct list_head list; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_tunables { | 
|  | u64 rx_queues; | 
|  | u64 tx_queues; | 
|  | u64 rx_entries; | 
|  | u64 tx_entries; | 
|  | u64 mtu; | 
|  | }; | 
|  |  | 
|  | struct ibmvnic_adapter { | 
|  | struct vio_dev *vdev; | 
|  | struct net_device *netdev; | 
|  | struct ibmvnic_crq_queue crq; | 
|  | u8 mac_addr[ETH_ALEN]; | 
|  | struct ibmvnic_query_ip_offload_buffer ip_offload_buf; | 
|  | dma_addr_t ip_offload_tok; | 
|  | struct ibmvnic_control_ip_offload_buffer ip_offload_ctrl; | 
|  | dma_addr_t ip_offload_ctrl_tok; | 
|  | u32 msg_enable; | 
|  |  | 
|  | /* Vital Product Data (VPD) */ | 
|  | struct ibmvnic_vpd *vpd; | 
|  | char fw_version[32]; | 
|  |  | 
|  | /* Statistics */ | 
|  | struct ibmvnic_statistics stats; | 
|  | dma_addr_t stats_token; | 
|  | struct completion stats_done; | 
|  | int replenish_no_mem; | 
|  | int replenish_add_buff_success; | 
|  | int replenish_add_buff_failure; | 
|  | int replenish_task_cycles; | 
|  | int tx_send_failed; | 
|  | int tx_map_failed; | 
|  |  | 
|  | struct ibmvnic_tx_queue_stats *tx_stats_buffers; | 
|  | struct ibmvnic_rx_queue_stats *rx_stats_buffers; | 
|  |  | 
|  | int phys_link_state; | 
|  | int logical_link_state; | 
|  |  | 
|  | u32 speed; | 
|  | u8 duplex; | 
|  |  | 
|  | /* login data */ | 
|  | struct ibmvnic_login_buffer *login_buf; | 
|  | dma_addr_t login_buf_token; | 
|  | int login_buf_sz; | 
|  |  | 
|  | struct ibmvnic_login_rsp_buffer *login_rsp_buf; | 
|  | dma_addr_t login_rsp_buf_token; | 
|  | int login_rsp_buf_sz; | 
|  |  | 
|  | atomic_t running_cap_crqs; | 
|  |  | 
|  | struct ibmvnic_sub_crq_queue **tx_scrq ____cacheline_aligned; | 
|  | struct ibmvnic_sub_crq_queue **rx_scrq ____cacheline_aligned; | 
|  |  | 
|  | /* rx structs */ | 
|  | struct napi_struct *napi; | 
|  | struct ibmvnic_rx_pool *rx_pool; | 
|  | u64 promisc; | 
|  |  | 
|  | struct ibmvnic_tx_pool *tx_pool; | 
|  | struct ibmvnic_tx_pool *tso_pool; | 
|  | struct completion probe_done; | 
|  | struct completion init_done; | 
|  | int init_done_rc; | 
|  |  | 
|  | struct completion fw_done; | 
|  | /* Used for serialization of device commands */ | 
|  | struct mutex fw_lock; | 
|  | int fw_done_rc; | 
|  |  | 
|  | struct completion reset_done; | 
|  | int reset_done_rc; | 
|  | bool wait_for_reset; | 
|  |  | 
|  | /* partner capabilities */ | 
|  | u64 min_tx_queues; | 
|  | u64 min_rx_queues; | 
|  | u64 min_rx_add_queues; | 
|  | u64 max_tx_queues; | 
|  | u64 max_rx_queues; | 
|  | u64 max_rx_add_queues; | 
|  | u64 req_tx_queues; | 
|  | u64 req_rx_queues; | 
|  | u64 req_rx_add_queues; | 
|  | u64 min_tx_entries_per_subcrq; | 
|  | u64 min_rx_add_entries_per_subcrq; | 
|  | u64 max_tx_entries_per_subcrq; | 
|  | u64 max_rx_add_entries_per_subcrq; | 
|  | u64 req_tx_entries_per_subcrq; | 
|  | u64 req_rx_add_entries_per_subcrq; | 
|  | u64 tcp_ip_offload; | 
|  | u64 promisc_requested; | 
|  | u64 promisc_supported; | 
|  | u64 min_mtu; | 
|  | u64 max_mtu; | 
|  | u64 req_mtu; | 
|  | u64 prev_mtu; | 
|  | u64 max_multicast_filters; | 
|  | u64 vlan_header_insertion; | 
|  | u64 rx_vlan_header_insertion; | 
|  | u64 max_tx_sg_entries; | 
|  | u64 rx_sg_supported; | 
|  | u64 rx_sg_requested; | 
|  | u64 opt_tx_comp_sub_queues; | 
|  | u64 opt_rx_comp_queues; | 
|  | u64 opt_rx_bufadd_q_per_rx_comp_q; | 
|  | u64 opt_tx_entries_per_subcrq; | 
|  | u64 opt_rxba_entries_per_subcrq; | 
|  | __be64 tx_rx_desc_req; | 
|  | #define MAX_MAP_ID	255 | 
|  | DECLARE_BITMAP(map_ids, MAX_MAP_ID); | 
|  | u32 num_active_rx_scrqs; | 
|  | u32 num_active_rx_pools; | 
|  | u32 num_active_rx_napi; | 
|  | u32 num_active_tx_scrqs; | 
|  | u32 num_active_tx_pools; | 
|  |  | 
|  | u32 prev_rx_pool_size; | 
|  | u32 prev_tx_pool_size; | 
|  | u32 cur_rx_buf_sz; | 
|  | u32 prev_rx_buf_sz; | 
|  |  | 
|  | struct tasklet_struct tasklet; | 
|  | enum vnic_state state; | 
|  | /* Used for serialization of state field. When taking both state | 
|  | * and rwi locks, take state lock first. | 
|  | */ | 
|  | spinlock_t state_lock; | 
|  | enum ibmvnic_reset_reason reset_reason; | 
|  | struct list_head rwi_list; | 
|  | /* Used for serialization of rwi_list. When taking both state | 
|  | * and rwi locks, take state lock first | 
|  | */ | 
|  | spinlock_t rwi_lock; | 
|  | struct work_struct ibmvnic_reset; | 
|  | struct delayed_work ibmvnic_delayed_reset; | 
|  | unsigned long resetting; | 
|  | /* last device reset time */ | 
|  | unsigned long last_reset_time; | 
|  |  | 
|  | bool napi_enabled; | 
|  | bool from_passive_init; | 
|  | bool login_pending; | 
|  | /* protected by rcu */ | 
|  | bool tx_queues_active; | 
|  | bool failover_pending; | 
|  | bool force_reset_recovery; | 
|  |  | 
|  | struct ibmvnic_tunables desired; | 
|  | struct ibmvnic_tunables fallback; | 
|  | }; |