cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qed_mng_tlv.c (40548B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
      2/* Copyright (c) 2019-2020 Marvell International Ltd. */
      3
      4#include <linux/types.h>
      5#include <asm/byteorder.h>
      6#include <linux/bug.h>
      7#include <linux/errno.h>
      8#include <linux/kernel.h>
      9#include <linux/slab.h>
     10#include <linux/string.h>
     11#include <linux/vmalloc.h>
     12#include "qed.h"
     13#include "qed_hw.h"
     14#include "qed_mcp.h"
     15#include "qed_reg_addr.h"
     16
     17#define TLV_TYPE(p)     (p[0])
     18#define TLV_LENGTH(p)   (p[1])
     19#define TLV_FLAGS(p)    (p[3])
     20
     21#define QED_TLV_DATA_MAX (14)
     22struct qed_tlv_parsed_buf {
     23	/* To be filled with the address to set in Value field */
     24	void *p_val;
     25
     26	/* To be used internally in case the value has to be modified */
     27	u8 data[QED_TLV_DATA_MAX];
     28};
     29
     30static int qed_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
     31{
     32	switch (tlv_type) {
     33	case DRV_TLV_FEATURE_FLAGS:
     34	case DRV_TLV_LOCAL_ADMIN_ADDR:
     35	case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
     36	case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
     37	case DRV_TLV_OS_DRIVER_STATES:
     38	case DRV_TLV_PXE_BOOT_PROGRESS:
     39	case DRV_TLV_RX_FRAMES_RECEIVED:
     40	case DRV_TLV_RX_BYTES_RECEIVED:
     41	case DRV_TLV_TX_FRAMES_SENT:
     42	case DRV_TLV_TX_BYTES_SENT:
     43	case DRV_TLV_NPIV_ENABLED:
     44	case DRV_TLV_PCIE_BUS_RX_UTILIZATION:
     45	case DRV_TLV_PCIE_BUS_TX_UTILIZATION:
     46	case DRV_TLV_DEVICE_CPU_CORES_UTILIZATION:
     47	case DRV_TLV_LAST_VALID_DCC_TLV_RECEIVED:
     48	case DRV_TLV_NCSI_RX_BYTES_RECEIVED:
     49	case DRV_TLV_NCSI_TX_BYTES_SENT:
     50		*tlv_group |= QED_MFW_TLV_GENERIC;
     51		break;
     52	case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
     53	case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
     54	case DRV_TLV_PROMISCUOUS_MODE:
     55	case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
     56	case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
     57	case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
     58	case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
     59	case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
     60	case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
     61	case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
     62	case DRV_TLV_IOV_OFFLOAD:
     63	case DRV_TLV_TX_QUEUES_EMPTY:
     64	case DRV_TLV_RX_QUEUES_EMPTY:
     65	case DRV_TLV_TX_QUEUES_FULL:
     66	case DRV_TLV_RX_QUEUES_FULL:
     67		*tlv_group |= QED_MFW_TLV_ETH;
     68		break;
     69	case DRV_TLV_SCSI_TO:
     70	case DRV_TLV_R_T_TOV:
     71	case DRV_TLV_R_A_TOV:
     72	case DRV_TLV_E_D_TOV:
     73	case DRV_TLV_CR_TOV:
     74	case DRV_TLV_BOOT_TYPE:
     75	case DRV_TLV_NPIV_STATE:
     76	case DRV_TLV_NUM_OF_NPIV_IDS:
     77	case DRV_TLV_SWITCH_NAME:
     78	case DRV_TLV_SWITCH_PORT_NUM:
     79	case DRV_TLV_SWITCH_PORT_ID:
     80	case DRV_TLV_VENDOR_NAME:
     81	case DRV_TLV_SWITCH_MODEL:
     82	case DRV_TLV_SWITCH_FW_VER:
     83	case DRV_TLV_QOS_PRIORITY_PER_802_1P:
     84	case DRV_TLV_PORT_ALIAS:
     85	case DRV_TLV_PORT_STATE:
     86	case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
     87	case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
     88	case DRV_TLV_LINK_FAILURE_COUNT:
     89	case DRV_TLV_FCOE_BOOT_PROGRESS:
     90	case DRV_TLV_RX_BROADCAST_PACKETS:
     91	case DRV_TLV_TX_BROADCAST_PACKETS:
     92	case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
     93	case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
     94	case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
     95	case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
     96	case DRV_TLV_FCOE_TX_FRAMES_SENT:
     97	case DRV_TLV_FCOE_TX_BYTES_SENT:
     98	case DRV_TLV_CRC_ERROR_COUNT:
     99	case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
    100	case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
    101	case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
    102	case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
    103	case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
    104	case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
    105	case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
    106	case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
    107	case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
    108	case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
    109	case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
    110	case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
    111	case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
    112	case DRV_TLV_DISPARITY_ERROR_COUNT:
    113	case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
    114	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
    115	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
    116	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
    117	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
    118	case DRV_TLV_LAST_FLOGI_TIMESTAMP:
    119	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
    120	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
    121	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
    122	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
    123	case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
    124	case DRV_TLV_LAST_FLOGI_RJT:
    125	case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
    126	case DRV_TLV_FDISCS_SENT_COUNT:
    127	case DRV_TLV_FDISC_ACCS_RECEIVED:
    128	case DRV_TLV_FDISC_RJTS_RECEIVED:
    129	case DRV_TLV_PLOGI_SENT_COUNT:
    130	case DRV_TLV_PLOGI_ACCS_RECEIVED:
    131	case DRV_TLV_PLOGI_RJTS_RECEIVED:
    132	case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
    133	case DRV_TLV_PLOGI_1_TIMESTAMP:
    134	case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
    135	case DRV_TLV_PLOGI_2_TIMESTAMP:
    136	case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
    137	case DRV_TLV_PLOGI_3_TIMESTAMP:
    138	case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
    139	case DRV_TLV_PLOGI_4_TIMESTAMP:
    140	case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
    141	case DRV_TLV_PLOGI_5_TIMESTAMP:
    142	case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
    143	case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
    144	case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
    145	case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
    146	case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
    147	case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
    148	case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
    149	case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
    150	case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
    151	case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
    152	case DRV_TLV_LOGOS_ISSUED:
    153	case DRV_TLV_LOGO_ACCS_RECEIVED:
    154	case DRV_TLV_LOGO_RJTS_RECEIVED:
    155	case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
    156	case DRV_TLV_LOGO_1_TIMESTAMP:
    157	case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
    158	case DRV_TLV_LOGO_2_TIMESTAMP:
    159	case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
    160	case DRV_TLV_LOGO_3_TIMESTAMP:
    161	case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
    162	case DRV_TLV_LOGO_4_TIMESTAMP:
    163	case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
    164	case DRV_TLV_LOGO_5_TIMESTAMP:
    165	case DRV_TLV_LOGOS_RECEIVED:
    166	case DRV_TLV_ACCS_ISSUED:
    167	case DRV_TLV_PRLIS_ISSUED:
    168	case DRV_TLV_ACCS_RECEIVED:
    169	case DRV_TLV_ABTS_SENT_COUNT:
    170	case DRV_TLV_ABTS_ACCS_RECEIVED:
    171	case DRV_TLV_ABTS_RJTS_RECEIVED:
    172	case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
    173	case DRV_TLV_ABTS_1_TIMESTAMP:
    174	case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
    175	case DRV_TLV_ABTS_2_TIMESTAMP:
    176	case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
    177	case DRV_TLV_ABTS_3_TIMESTAMP:
    178	case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
    179	case DRV_TLV_ABTS_4_TIMESTAMP:
    180	case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
    181	case DRV_TLV_ABTS_5_TIMESTAMP:
    182	case DRV_TLV_RSCNS_RECEIVED:
    183	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
    184	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
    185	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
    186	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
    187	case DRV_TLV_LUN_RESETS_ISSUED:
    188	case DRV_TLV_ABORT_TASK_SETS_ISSUED:
    189	case DRV_TLV_TPRLOS_SENT:
    190	case DRV_TLV_NOS_SENT_COUNT:
    191	case DRV_TLV_NOS_RECEIVED_COUNT:
    192	case DRV_TLV_OLS_COUNT:
    193	case DRV_TLV_LR_COUNT:
    194	case DRV_TLV_LRR_COUNT:
    195	case DRV_TLV_LIP_SENT_COUNT:
    196	case DRV_TLV_LIP_RECEIVED_COUNT:
    197	case DRV_TLV_EOFA_COUNT:
    198	case DRV_TLV_EOFNI_COUNT:
    199	case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
    200	case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
    201	case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
    202	case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
    203	case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
    204	case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
    205	case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
    206	case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
    207	case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
    208	case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
    209	case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
    210	case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
    211	case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
    212	case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
    213	case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
    214	case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
    215	case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
    216	case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
    217	case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
    218		*tlv_group = QED_MFW_TLV_FCOE;
    219		break;
    220	case DRV_TLV_TARGET_LLMNR_ENABLED:
    221	case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
    222	case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
    223	case DRV_TLV_AUTHENTICATION_METHOD:
    224	case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
    225	case DRV_TLV_MAX_FRAME_SIZE:
    226	case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
    227	case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
    228	case DRV_TLV_ISCSI_BOOT_PROGRESS:
    229	case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
    230	case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
    231	case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
    232	case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
    233	case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
    234	case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
    235		*tlv_group |= QED_MFW_TLV_ISCSI;
    236		break;
    237	default:
    238		return -EINVAL;
    239	}
    240
    241	return 0;
    242}
    243
    244/* Returns size of the data buffer or, -1 in case TLV data is not available. */
    245static int
    246qed_mfw_get_gen_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
    247			  struct qed_mfw_tlv_generic *p_drv_buf,
    248			  struct qed_tlv_parsed_buf *p_buf)
    249{
    250	switch (p_tlv->tlv_type) {
    251	case DRV_TLV_FEATURE_FLAGS:
    252		if (p_drv_buf->flags.b_set) {
    253			memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
    254			p_buf->data[0] = p_drv_buf->flags.ipv4_csum_offload ?
    255			    1 : 0;
    256			p_buf->data[0] |= (p_drv_buf->flags.lso_supported ?
    257					   1 : 0) << 1;
    258			p_buf->p_val = p_buf->data;
    259			return QED_MFW_TLV_FLAGS_SIZE;
    260		}
    261		break;
    262
    263	case DRV_TLV_LOCAL_ADMIN_ADDR:
    264	case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
    265	case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
    266		{
    267			int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
    268
    269			if (p_drv_buf->mac_set[idx]) {
    270				p_buf->p_val = p_drv_buf->mac[idx];
    271				return ETH_ALEN;
    272			}
    273			break;
    274		}
    275
    276	case DRV_TLV_RX_FRAMES_RECEIVED:
    277		if (p_drv_buf->rx_frames_set) {
    278			p_buf->p_val = &p_drv_buf->rx_frames;
    279			return sizeof(p_drv_buf->rx_frames);
    280		}
    281		break;
    282	case DRV_TLV_RX_BYTES_RECEIVED:
    283		if (p_drv_buf->rx_bytes_set) {
    284			p_buf->p_val = &p_drv_buf->rx_bytes;
    285			return sizeof(p_drv_buf->rx_bytes);
    286		}
    287		break;
    288	case DRV_TLV_TX_FRAMES_SENT:
    289		if (p_drv_buf->tx_frames_set) {
    290			p_buf->p_val = &p_drv_buf->tx_frames;
    291			return sizeof(p_drv_buf->tx_frames);
    292		}
    293		break;
    294	case DRV_TLV_TX_BYTES_SENT:
    295		if (p_drv_buf->tx_bytes_set) {
    296			p_buf->p_val = &p_drv_buf->tx_bytes;
    297			return sizeof(p_drv_buf->tx_bytes);
    298		}
    299		break;
    300	default:
    301		break;
    302	}
    303
    304	return -1;
    305}
    306
    307static int
    308qed_mfw_get_eth_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
    309			  struct qed_mfw_tlv_eth *p_drv_buf,
    310			  struct qed_tlv_parsed_buf *p_buf)
    311{
    312	switch (p_tlv->tlv_type) {
    313	case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
    314		if (p_drv_buf->lso_maxoff_size_set) {
    315			p_buf->p_val = &p_drv_buf->lso_maxoff_size;
    316			return sizeof(p_drv_buf->lso_maxoff_size);
    317		}
    318		break;
    319	case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
    320		if (p_drv_buf->lso_minseg_size_set) {
    321			p_buf->p_val = &p_drv_buf->lso_minseg_size;
    322			return sizeof(p_drv_buf->lso_minseg_size);
    323		}
    324		break;
    325	case DRV_TLV_PROMISCUOUS_MODE:
    326		if (p_drv_buf->prom_mode_set) {
    327			p_buf->p_val = &p_drv_buf->prom_mode;
    328			return sizeof(p_drv_buf->prom_mode);
    329		}
    330		break;
    331	case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
    332		if (p_drv_buf->tx_descr_size_set) {
    333			p_buf->p_val = &p_drv_buf->tx_descr_size;
    334			return sizeof(p_drv_buf->tx_descr_size);
    335		}
    336		break;
    337	case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
    338		if (p_drv_buf->rx_descr_size_set) {
    339			p_buf->p_val = &p_drv_buf->rx_descr_size;
    340			return sizeof(p_drv_buf->rx_descr_size);
    341		}
    342		break;
    343	case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
    344		if (p_drv_buf->netq_count_set) {
    345			p_buf->p_val = &p_drv_buf->netq_count;
    346			return sizeof(p_drv_buf->netq_count);
    347		}
    348		break;
    349	case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
    350		if (p_drv_buf->tcp4_offloads_set) {
    351			p_buf->p_val = &p_drv_buf->tcp4_offloads;
    352			return sizeof(p_drv_buf->tcp4_offloads);
    353		}
    354		break;
    355	case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
    356		if (p_drv_buf->tcp6_offloads_set) {
    357			p_buf->p_val = &p_drv_buf->tcp6_offloads;
    358			return sizeof(p_drv_buf->tcp6_offloads);
    359		}
    360		break;
    361	case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
    362		if (p_drv_buf->tx_descr_qdepth_set) {
    363			p_buf->p_val = &p_drv_buf->tx_descr_qdepth;
    364			return sizeof(p_drv_buf->tx_descr_qdepth);
    365		}
    366		break;
    367	case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
    368		if (p_drv_buf->rx_descr_qdepth_set) {
    369			p_buf->p_val = &p_drv_buf->rx_descr_qdepth;
    370			return sizeof(p_drv_buf->rx_descr_qdepth);
    371		}
    372		break;
    373	case DRV_TLV_IOV_OFFLOAD:
    374		if (p_drv_buf->iov_offload_set) {
    375			p_buf->p_val = &p_drv_buf->iov_offload;
    376			return sizeof(p_drv_buf->iov_offload);
    377		}
    378		break;
    379	case DRV_TLV_TX_QUEUES_EMPTY:
    380		if (p_drv_buf->txqs_empty_set) {
    381			p_buf->p_val = &p_drv_buf->txqs_empty;
    382			return sizeof(p_drv_buf->txqs_empty);
    383		}
    384		break;
    385	case DRV_TLV_RX_QUEUES_EMPTY:
    386		if (p_drv_buf->rxqs_empty_set) {
    387			p_buf->p_val = &p_drv_buf->rxqs_empty;
    388			return sizeof(p_drv_buf->rxqs_empty);
    389		}
    390		break;
    391	case DRV_TLV_TX_QUEUES_FULL:
    392		if (p_drv_buf->num_txqs_full_set) {
    393			p_buf->p_val = &p_drv_buf->num_txqs_full;
    394			return sizeof(p_drv_buf->num_txqs_full);
    395		}
    396		break;
    397	case DRV_TLV_RX_QUEUES_FULL:
    398		if (p_drv_buf->num_rxqs_full_set) {
    399			p_buf->p_val = &p_drv_buf->num_rxqs_full;
    400			return sizeof(p_drv_buf->num_rxqs_full);
    401		}
    402		break;
    403	default:
    404		break;
    405	}
    406
    407	return -1;
    408}
    409
    410static int
    411qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time *p_time,
    412			   struct qed_tlv_parsed_buf *p_buf)
    413{
    414	if (!p_time->b_set)
    415		return -1;
    416
    417	/* Validate numbers */
    418	if (p_time->month > 12)
    419		p_time->month = 0;
    420	if (p_time->day > 31)
    421		p_time->day = 0;
    422	if (p_time->hour > 23)
    423		p_time->hour = 0;
    424	if (p_time->min > 59)
    425		p_time->hour = 0;
    426	if (p_time->msec > 999)
    427		p_time->msec = 0;
    428	if (p_time->usec > 999)
    429		p_time->usec = 0;
    430
    431	memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
    432	snprintf(p_buf->data, 14, "%d%d%d%d%d%d",
    433		 p_time->month, p_time->day,
    434		 p_time->hour, p_time->min, p_time->msec, p_time->usec);
    435
    436	p_buf->p_val = p_buf->data;
    437
    438	return QED_MFW_TLV_TIME_SIZE;
    439}
    440
    441static int
    442qed_mfw_get_fcoe_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
    443			   struct qed_mfw_tlv_fcoe *p_drv_buf,
    444			   struct qed_tlv_parsed_buf *p_buf)
    445{
    446	struct qed_mfw_tlv_time *p_time;
    447	u8 idx;
    448
    449	switch (p_tlv->tlv_type) {
    450	case DRV_TLV_SCSI_TO:
    451		if (p_drv_buf->scsi_timeout_set) {
    452			p_buf->p_val = &p_drv_buf->scsi_timeout;
    453			return sizeof(p_drv_buf->scsi_timeout);
    454		}
    455		break;
    456	case DRV_TLV_R_T_TOV:
    457		if (p_drv_buf->rt_tov_set) {
    458			p_buf->p_val = &p_drv_buf->rt_tov;
    459			return sizeof(p_drv_buf->rt_tov);
    460		}
    461		break;
    462	case DRV_TLV_R_A_TOV:
    463		if (p_drv_buf->ra_tov_set) {
    464			p_buf->p_val = &p_drv_buf->ra_tov;
    465			return sizeof(p_drv_buf->ra_tov);
    466		}
    467		break;
    468	case DRV_TLV_E_D_TOV:
    469		if (p_drv_buf->ed_tov_set) {
    470			p_buf->p_val = &p_drv_buf->ed_tov;
    471			return sizeof(p_drv_buf->ed_tov);
    472		}
    473		break;
    474	case DRV_TLV_CR_TOV:
    475		if (p_drv_buf->cr_tov_set) {
    476			p_buf->p_val = &p_drv_buf->cr_tov;
    477			return sizeof(p_drv_buf->cr_tov);
    478		}
    479		break;
    480	case DRV_TLV_BOOT_TYPE:
    481		if (p_drv_buf->boot_type_set) {
    482			p_buf->p_val = &p_drv_buf->boot_type;
    483			return sizeof(p_drv_buf->boot_type);
    484		}
    485		break;
    486	case DRV_TLV_NPIV_STATE:
    487		if (p_drv_buf->npiv_state_set) {
    488			p_buf->p_val = &p_drv_buf->npiv_state;
    489			return sizeof(p_drv_buf->npiv_state);
    490		}
    491		break;
    492	case DRV_TLV_NUM_OF_NPIV_IDS:
    493		if (p_drv_buf->num_npiv_ids_set) {
    494			p_buf->p_val = &p_drv_buf->num_npiv_ids;
    495			return sizeof(p_drv_buf->num_npiv_ids);
    496		}
    497		break;
    498	case DRV_TLV_SWITCH_NAME:
    499		if (p_drv_buf->switch_name_set) {
    500			p_buf->p_val = &p_drv_buf->switch_name;
    501			return sizeof(p_drv_buf->switch_name);
    502		}
    503		break;
    504	case DRV_TLV_SWITCH_PORT_NUM:
    505		if (p_drv_buf->switch_portnum_set) {
    506			p_buf->p_val = &p_drv_buf->switch_portnum;
    507			return sizeof(p_drv_buf->switch_portnum);
    508		}
    509		break;
    510	case DRV_TLV_SWITCH_PORT_ID:
    511		if (p_drv_buf->switch_portid_set) {
    512			p_buf->p_val = &p_drv_buf->switch_portid;
    513			return sizeof(p_drv_buf->switch_portid);
    514		}
    515		break;
    516	case DRV_TLV_VENDOR_NAME:
    517		if (p_drv_buf->vendor_name_set) {
    518			p_buf->p_val = &p_drv_buf->vendor_name;
    519			return sizeof(p_drv_buf->vendor_name);
    520		}
    521		break;
    522	case DRV_TLV_SWITCH_MODEL:
    523		if (p_drv_buf->switch_model_set) {
    524			p_buf->p_val = &p_drv_buf->switch_model;
    525			return sizeof(p_drv_buf->switch_model);
    526		}
    527		break;
    528	case DRV_TLV_SWITCH_FW_VER:
    529		if (p_drv_buf->switch_fw_version_set) {
    530			p_buf->p_val = &p_drv_buf->switch_fw_version;
    531			return sizeof(p_drv_buf->switch_fw_version);
    532		}
    533		break;
    534	case DRV_TLV_QOS_PRIORITY_PER_802_1P:
    535		if (p_drv_buf->qos_pri_set) {
    536			p_buf->p_val = &p_drv_buf->qos_pri;
    537			return sizeof(p_drv_buf->qos_pri);
    538		}
    539		break;
    540	case DRV_TLV_PORT_ALIAS:
    541		if (p_drv_buf->port_alias_set) {
    542			p_buf->p_val = &p_drv_buf->port_alias;
    543			return sizeof(p_drv_buf->port_alias);
    544		}
    545		break;
    546	case DRV_TLV_PORT_STATE:
    547		if (p_drv_buf->port_state_set) {
    548			p_buf->p_val = &p_drv_buf->port_state;
    549			return sizeof(p_drv_buf->port_state);
    550		}
    551		break;
    552	case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
    553		if (p_drv_buf->fip_tx_descr_size_set) {
    554			p_buf->p_val = &p_drv_buf->fip_tx_descr_size;
    555			return sizeof(p_drv_buf->fip_tx_descr_size);
    556		}
    557		break;
    558	case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
    559		if (p_drv_buf->fip_rx_descr_size_set) {
    560			p_buf->p_val = &p_drv_buf->fip_rx_descr_size;
    561			return sizeof(p_drv_buf->fip_rx_descr_size);
    562		}
    563		break;
    564	case DRV_TLV_LINK_FAILURE_COUNT:
    565		if (p_drv_buf->link_failures_set) {
    566			p_buf->p_val = &p_drv_buf->link_failures;
    567			return sizeof(p_drv_buf->link_failures);
    568		}
    569		break;
    570	case DRV_TLV_FCOE_BOOT_PROGRESS:
    571		if (p_drv_buf->fcoe_boot_progress_set) {
    572			p_buf->p_val = &p_drv_buf->fcoe_boot_progress;
    573			return sizeof(p_drv_buf->fcoe_boot_progress);
    574		}
    575		break;
    576	case DRV_TLV_RX_BROADCAST_PACKETS:
    577		if (p_drv_buf->rx_bcast_set) {
    578			p_buf->p_val = &p_drv_buf->rx_bcast;
    579			return sizeof(p_drv_buf->rx_bcast);
    580		}
    581		break;
    582	case DRV_TLV_TX_BROADCAST_PACKETS:
    583		if (p_drv_buf->tx_bcast_set) {
    584			p_buf->p_val = &p_drv_buf->tx_bcast;
    585			return sizeof(p_drv_buf->tx_bcast);
    586		}
    587		break;
    588	case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
    589		if (p_drv_buf->fcoe_txq_depth_set) {
    590			p_buf->p_val = &p_drv_buf->fcoe_txq_depth;
    591			return sizeof(p_drv_buf->fcoe_txq_depth);
    592		}
    593		break;
    594	case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
    595		if (p_drv_buf->fcoe_rxq_depth_set) {
    596			p_buf->p_val = &p_drv_buf->fcoe_rxq_depth;
    597			return sizeof(p_drv_buf->fcoe_rxq_depth);
    598		}
    599		break;
    600	case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
    601		if (p_drv_buf->fcoe_rx_frames_set) {
    602			p_buf->p_val = &p_drv_buf->fcoe_rx_frames;
    603			return sizeof(p_drv_buf->fcoe_rx_frames);
    604		}
    605		break;
    606	case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
    607		if (p_drv_buf->fcoe_rx_bytes_set) {
    608			p_buf->p_val = &p_drv_buf->fcoe_rx_bytes;
    609			return sizeof(p_drv_buf->fcoe_rx_bytes);
    610		}
    611		break;
    612	case DRV_TLV_FCOE_TX_FRAMES_SENT:
    613		if (p_drv_buf->fcoe_tx_frames_set) {
    614			p_buf->p_val = &p_drv_buf->fcoe_tx_frames;
    615			return sizeof(p_drv_buf->fcoe_tx_frames);
    616		}
    617		break;
    618	case DRV_TLV_FCOE_TX_BYTES_SENT:
    619		if (p_drv_buf->fcoe_tx_bytes_set) {
    620			p_buf->p_val = &p_drv_buf->fcoe_tx_bytes;
    621			return sizeof(p_drv_buf->fcoe_tx_bytes);
    622		}
    623		break;
    624	case DRV_TLV_CRC_ERROR_COUNT:
    625		if (p_drv_buf->crc_count_set) {
    626			p_buf->p_val = &p_drv_buf->crc_count;
    627			return sizeof(p_drv_buf->crc_count);
    628		}
    629		break;
    630	case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
    631	case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
    632	case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
    633	case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
    634	case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
    635		idx = (p_tlv->tlv_type -
    636		       DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID) / 2;
    637
    638		if (p_drv_buf->crc_err_src_fcid_set[idx]) {
    639			p_buf->p_val = &p_drv_buf->crc_err_src_fcid[idx];
    640			return sizeof(p_drv_buf->crc_err_src_fcid[idx]);
    641		}
    642		break;
    643	case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
    644	case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
    645	case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
    646	case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
    647	case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
    648		idx = (p_tlv->tlv_type - DRV_TLV_CRC_ERROR_1_TIMESTAMP) / 2;
    649
    650		return qed_mfw_get_tlv_time_value(&p_drv_buf->crc_err[idx],
    651						  p_buf);
    652	case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
    653		if (p_drv_buf->losync_err_set) {
    654			p_buf->p_val = &p_drv_buf->losync_err;
    655			return sizeof(p_drv_buf->losync_err);
    656		}
    657		break;
    658	case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
    659		if (p_drv_buf->losig_err_set) {
    660			p_buf->p_val = &p_drv_buf->losig_err;
    661			return sizeof(p_drv_buf->losig_err);
    662		}
    663		break;
    664	case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
    665		if (p_drv_buf->primtive_err_set) {
    666			p_buf->p_val = &p_drv_buf->primtive_err;
    667			return sizeof(p_drv_buf->primtive_err);
    668		}
    669		break;
    670	case DRV_TLV_DISPARITY_ERROR_COUNT:
    671		if (p_drv_buf->disparity_err_set) {
    672			p_buf->p_val = &p_drv_buf->disparity_err;
    673			return sizeof(p_drv_buf->disparity_err);
    674		}
    675		break;
    676	case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
    677		if (p_drv_buf->code_violation_err_set) {
    678			p_buf->p_val = &p_drv_buf->code_violation_err;
    679			return sizeof(p_drv_buf->code_violation_err);
    680		}
    681		break;
    682	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
    683	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
    684	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
    685	case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
    686		idx = p_tlv->tlv_type -
    687			DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1;
    688		if (p_drv_buf->flogi_param_set[idx]) {
    689			p_buf->p_val = &p_drv_buf->flogi_param[idx];
    690			return sizeof(p_drv_buf->flogi_param[idx]);
    691		}
    692		break;
    693	case DRV_TLV_LAST_FLOGI_TIMESTAMP:
    694		return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_tstamp,
    695						  p_buf);
    696	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
    697	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
    698	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
    699	case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
    700		idx = p_tlv->tlv_type -
    701			DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1;
    702
    703		if (p_drv_buf->flogi_acc_param_set[idx]) {
    704			p_buf->p_val = &p_drv_buf->flogi_acc_param[idx];
    705			return sizeof(p_drv_buf->flogi_acc_param[idx]);
    706		}
    707		break;
    708	case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
    709		return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_acc_tstamp,
    710						  p_buf);
    711	case DRV_TLV_LAST_FLOGI_RJT:
    712		if (p_drv_buf->flogi_rjt_set) {
    713			p_buf->p_val = &p_drv_buf->flogi_rjt;
    714			return sizeof(p_drv_buf->flogi_rjt);
    715		}
    716		break;
    717	case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
    718		return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_rjt_tstamp,
    719						  p_buf);
    720	case DRV_TLV_FDISCS_SENT_COUNT:
    721		if (p_drv_buf->fdiscs_set) {
    722			p_buf->p_val = &p_drv_buf->fdiscs;
    723			return sizeof(p_drv_buf->fdiscs);
    724		}
    725		break;
    726	case DRV_TLV_FDISC_ACCS_RECEIVED:
    727		if (p_drv_buf->fdisc_acc_set) {
    728			p_buf->p_val = &p_drv_buf->fdisc_acc;
    729			return sizeof(p_drv_buf->fdisc_acc);
    730		}
    731		break;
    732	case DRV_TLV_FDISC_RJTS_RECEIVED:
    733		if (p_drv_buf->fdisc_rjt_set) {
    734			p_buf->p_val = &p_drv_buf->fdisc_rjt;
    735			return sizeof(p_drv_buf->fdisc_rjt);
    736		}
    737		break;
    738	case DRV_TLV_PLOGI_SENT_COUNT:
    739		if (p_drv_buf->plogi_set) {
    740			p_buf->p_val = &p_drv_buf->plogi;
    741			return sizeof(p_drv_buf->plogi);
    742		}
    743		break;
    744	case DRV_TLV_PLOGI_ACCS_RECEIVED:
    745		if (p_drv_buf->plogi_acc_set) {
    746			p_buf->p_val = &p_drv_buf->plogi_acc;
    747			return sizeof(p_drv_buf->plogi_acc);
    748		}
    749		break;
    750	case DRV_TLV_PLOGI_RJTS_RECEIVED:
    751		if (p_drv_buf->plogi_rjt_set) {
    752			p_buf->p_val = &p_drv_buf->plogi_rjt;
    753			return sizeof(p_drv_buf->plogi_rjt);
    754		}
    755		break;
    756	case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
    757	case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
    758	case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
    759	case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
    760	case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
    761		idx = (p_tlv->tlv_type -
    762		       DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID) / 2;
    763
    764		if (p_drv_buf->plogi_dst_fcid_set[idx]) {
    765			p_buf->p_val = &p_drv_buf->plogi_dst_fcid[idx];
    766			return sizeof(p_drv_buf->plogi_dst_fcid[idx]);
    767		}
    768		break;
    769	case DRV_TLV_PLOGI_1_TIMESTAMP:
    770	case DRV_TLV_PLOGI_2_TIMESTAMP:
    771	case DRV_TLV_PLOGI_3_TIMESTAMP:
    772	case DRV_TLV_PLOGI_4_TIMESTAMP:
    773	case DRV_TLV_PLOGI_5_TIMESTAMP:
    774		idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_TIMESTAMP) / 2;
    775
    776		return qed_mfw_get_tlv_time_value(&p_drv_buf->plogi_tstamp[idx],
    777						  p_buf);
    778	case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
    779	case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
    780	case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
    781	case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
    782	case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
    783		idx = (p_tlv->tlv_type -
    784		       DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID) / 2;
    785
    786		if (p_drv_buf->plogi_acc_src_fcid_set[idx]) {
    787			p_buf->p_val = &p_drv_buf->plogi_acc_src_fcid[idx];
    788			return sizeof(p_drv_buf->plogi_acc_src_fcid[idx]);
    789		}
    790		break;
    791	case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
    792	case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
    793	case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
    794	case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
    795	case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
    796		idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_ACC_TIMESTAMP) / 2;
    797		p_time = &p_drv_buf->plogi_acc_tstamp[idx];
    798
    799		return qed_mfw_get_tlv_time_value(p_time, p_buf);
    800	case DRV_TLV_LOGOS_ISSUED:
    801		if (p_drv_buf->tx_plogos_set) {
    802			p_buf->p_val = &p_drv_buf->tx_plogos;
    803			return sizeof(p_drv_buf->tx_plogos);
    804		}
    805		break;
    806	case DRV_TLV_LOGO_ACCS_RECEIVED:
    807		if (p_drv_buf->plogo_acc_set) {
    808			p_buf->p_val = &p_drv_buf->plogo_acc;
    809			return sizeof(p_drv_buf->plogo_acc);
    810		}
    811		break;
    812	case DRV_TLV_LOGO_RJTS_RECEIVED:
    813		if (p_drv_buf->plogo_rjt_set) {
    814			p_buf->p_val = &p_drv_buf->plogo_rjt;
    815			return sizeof(p_drv_buf->plogo_rjt);
    816		}
    817		break;
    818	case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
    819	case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
    820	case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
    821	case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
    822	case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
    823		idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID) /
    824			2;
    825
    826		if (p_drv_buf->plogo_src_fcid_set[idx]) {
    827			p_buf->p_val = &p_drv_buf->plogo_src_fcid[idx];
    828			return sizeof(p_drv_buf->plogo_src_fcid[idx]);
    829		}
    830		break;
    831	case DRV_TLV_LOGO_1_TIMESTAMP:
    832	case DRV_TLV_LOGO_2_TIMESTAMP:
    833	case DRV_TLV_LOGO_3_TIMESTAMP:
    834	case DRV_TLV_LOGO_4_TIMESTAMP:
    835	case DRV_TLV_LOGO_5_TIMESTAMP:
    836		idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_TIMESTAMP) / 2;
    837
    838		return qed_mfw_get_tlv_time_value(&p_drv_buf->plogo_tstamp[idx],
    839						  p_buf);
    840	case DRV_TLV_LOGOS_RECEIVED:
    841		if (p_drv_buf->rx_logos_set) {
    842			p_buf->p_val = &p_drv_buf->rx_logos;
    843			return sizeof(p_drv_buf->rx_logos);
    844		}
    845		break;
    846	case DRV_TLV_ACCS_ISSUED:
    847		if (p_drv_buf->tx_accs_set) {
    848			p_buf->p_val = &p_drv_buf->tx_accs;
    849			return sizeof(p_drv_buf->tx_accs);
    850		}
    851		break;
    852	case DRV_TLV_PRLIS_ISSUED:
    853		if (p_drv_buf->tx_prlis_set) {
    854			p_buf->p_val = &p_drv_buf->tx_prlis;
    855			return sizeof(p_drv_buf->tx_prlis);
    856		}
    857		break;
    858	case DRV_TLV_ACCS_RECEIVED:
    859		if (p_drv_buf->rx_accs_set) {
    860			p_buf->p_val = &p_drv_buf->rx_accs;
    861			return sizeof(p_drv_buf->rx_accs);
    862		}
    863		break;
    864	case DRV_TLV_ABTS_SENT_COUNT:
    865		if (p_drv_buf->tx_abts_set) {
    866			p_buf->p_val = &p_drv_buf->tx_abts;
    867			return sizeof(p_drv_buf->tx_abts);
    868		}
    869		break;
    870	case DRV_TLV_ABTS_ACCS_RECEIVED:
    871		if (p_drv_buf->rx_abts_acc_set) {
    872			p_buf->p_val = &p_drv_buf->rx_abts_acc;
    873			return sizeof(p_drv_buf->rx_abts_acc);
    874		}
    875		break;
    876	case DRV_TLV_ABTS_RJTS_RECEIVED:
    877		if (p_drv_buf->rx_abts_rjt_set) {
    878			p_buf->p_val = &p_drv_buf->rx_abts_rjt;
    879			return sizeof(p_drv_buf->rx_abts_rjt);
    880		}
    881		break;
    882	case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
    883	case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
    884	case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
    885	case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
    886	case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
    887		idx = (p_tlv->tlv_type -
    888		       DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID) / 2;
    889
    890		if (p_drv_buf->abts_dst_fcid_set[idx]) {
    891			p_buf->p_val = &p_drv_buf->abts_dst_fcid[idx];
    892			return sizeof(p_drv_buf->abts_dst_fcid[idx]);
    893		}
    894		break;
    895	case DRV_TLV_ABTS_1_TIMESTAMP:
    896	case DRV_TLV_ABTS_2_TIMESTAMP:
    897	case DRV_TLV_ABTS_3_TIMESTAMP:
    898	case DRV_TLV_ABTS_4_TIMESTAMP:
    899	case DRV_TLV_ABTS_5_TIMESTAMP:
    900		idx = (p_tlv->tlv_type - DRV_TLV_ABTS_1_TIMESTAMP) / 2;
    901
    902		return qed_mfw_get_tlv_time_value(&p_drv_buf->abts_tstamp[idx],
    903						  p_buf);
    904	case DRV_TLV_RSCNS_RECEIVED:
    905		if (p_drv_buf->rx_rscn_set) {
    906			p_buf->p_val = &p_drv_buf->rx_rscn;
    907			return sizeof(p_drv_buf->rx_rscn);
    908		}
    909		break;
    910	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
    911	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
    912	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
    913	case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
    914		idx = p_tlv->tlv_type - DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1;
    915
    916		if (p_drv_buf->rx_rscn_nport_set[idx]) {
    917			p_buf->p_val = &p_drv_buf->rx_rscn_nport[idx];
    918			return sizeof(p_drv_buf->rx_rscn_nport[idx]);
    919		}
    920		break;
    921	case DRV_TLV_LUN_RESETS_ISSUED:
    922		if (p_drv_buf->tx_lun_rst_set) {
    923			p_buf->p_val = &p_drv_buf->tx_lun_rst;
    924			return sizeof(p_drv_buf->tx_lun_rst);
    925		}
    926		break;
    927	case DRV_TLV_ABORT_TASK_SETS_ISSUED:
    928		if (p_drv_buf->abort_task_sets_set) {
    929			p_buf->p_val = &p_drv_buf->abort_task_sets;
    930			return sizeof(p_drv_buf->abort_task_sets);
    931		}
    932		break;
    933	case DRV_TLV_TPRLOS_SENT:
    934		if (p_drv_buf->tx_tprlos_set) {
    935			p_buf->p_val = &p_drv_buf->tx_tprlos;
    936			return sizeof(p_drv_buf->tx_tprlos);
    937		}
    938		break;
    939	case DRV_TLV_NOS_SENT_COUNT:
    940		if (p_drv_buf->tx_nos_set) {
    941			p_buf->p_val = &p_drv_buf->tx_nos;
    942			return sizeof(p_drv_buf->tx_nos);
    943		}
    944		break;
    945	case DRV_TLV_NOS_RECEIVED_COUNT:
    946		if (p_drv_buf->rx_nos_set) {
    947			p_buf->p_val = &p_drv_buf->rx_nos;
    948			return sizeof(p_drv_buf->rx_nos);
    949		}
    950		break;
    951	case DRV_TLV_OLS_COUNT:
    952		if (p_drv_buf->ols_set) {
    953			p_buf->p_val = &p_drv_buf->ols;
    954			return sizeof(p_drv_buf->ols);
    955		}
    956		break;
    957	case DRV_TLV_LR_COUNT:
    958		if (p_drv_buf->lr_set) {
    959			p_buf->p_val = &p_drv_buf->lr;
    960			return sizeof(p_drv_buf->lr);
    961		}
    962		break;
    963	case DRV_TLV_LRR_COUNT:
    964		if (p_drv_buf->lrr_set) {
    965			p_buf->p_val = &p_drv_buf->lrr;
    966			return sizeof(p_drv_buf->lrr);
    967		}
    968		break;
    969	case DRV_TLV_LIP_SENT_COUNT:
    970		if (p_drv_buf->tx_lip_set) {
    971			p_buf->p_val = &p_drv_buf->tx_lip;
    972			return sizeof(p_drv_buf->tx_lip);
    973		}
    974		break;
    975	case DRV_TLV_LIP_RECEIVED_COUNT:
    976		if (p_drv_buf->rx_lip_set) {
    977			p_buf->p_val = &p_drv_buf->rx_lip;
    978			return sizeof(p_drv_buf->rx_lip);
    979		}
    980		break;
    981	case DRV_TLV_EOFA_COUNT:
    982		if (p_drv_buf->eofa_set) {
    983			p_buf->p_val = &p_drv_buf->eofa;
    984			return sizeof(p_drv_buf->eofa);
    985		}
    986		break;
    987	case DRV_TLV_EOFNI_COUNT:
    988		if (p_drv_buf->eofni_set) {
    989			p_buf->p_val = &p_drv_buf->eofni;
    990			return sizeof(p_drv_buf->eofni);
    991		}
    992		break;
    993	case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
    994		if (p_drv_buf->scsi_chks_set) {
    995			p_buf->p_val = &p_drv_buf->scsi_chks;
    996			return sizeof(p_drv_buf->scsi_chks);
    997		}
    998		break;
    999	case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
   1000		if (p_drv_buf->scsi_cond_met_set) {
   1001			p_buf->p_val = &p_drv_buf->scsi_cond_met;
   1002			return sizeof(p_drv_buf->scsi_cond_met);
   1003		}
   1004		break;
   1005	case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
   1006		if (p_drv_buf->scsi_busy_set) {
   1007			p_buf->p_val = &p_drv_buf->scsi_busy;
   1008			return sizeof(p_drv_buf->scsi_busy);
   1009		}
   1010		break;
   1011	case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
   1012		if (p_drv_buf->scsi_inter_set) {
   1013			p_buf->p_val = &p_drv_buf->scsi_inter;
   1014			return sizeof(p_drv_buf->scsi_inter);
   1015		}
   1016		break;
   1017	case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
   1018		if (p_drv_buf->scsi_inter_cond_met_set) {
   1019			p_buf->p_val = &p_drv_buf->scsi_inter_cond_met;
   1020			return sizeof(p_drv_buf->scsi_inter_cond_met);
   1021		}
   1022		break;
   1023	case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
   1024		if (p_drv_buf->scsi_rsv_conflicts_set) {
   1025			p_buf->p_val = &p_drv_buf->scsi_rsv_conflicts;
   1026			return sizeof(p_drv_buf->scsi_rsv_conflicts);
   1027		}
   1028		break;
   1029	case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
   1030		if (p_drv_buf->scsi_tsk_full_set) {
   1031			p_buf->p_val = &p_drv_buf->scsi_tsk_full;
   1032			return sizeof(p_drv_buf->scsi_tsk_full);
   1033		}
   1034		break;
   1035	case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
   1036		if (p_drv_buf->scsi_aca_active_set) {
   1037			p_buf->p_val = &p_drv_buf->scsi_aca_active;
   1038			return sizeof(p_drv_buf->scsi_aca_active);
   1039		}
   1040		break;
   1041	case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
   1042		if (p_drv_buf->scsi_tsk_abort_set) {
   1043			p_buf->p_val = &p_drv_buf->scsi_tsk_abort;
   1044			return sizeof(p_drv_buf->scsi_tsk_abort);
   1045		}
   1046		break;
   1047	case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
   1048	case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
   1049	case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
   1050	case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
   1051	case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
   1052		idx = (p_tlv->tlv_type -
   1053		       DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ) / 2;
   1054
   1055		if (p_drv_buf->scsi_rx_chk_set[idx]) {
   1056			p_buf->p_val = &p_drv_buf->scsi_rx_chk[idx];
   1057			return sizeof(p_drv_buf->scsi_rx_chk[idx]);
   1058		}
   1059		break;
   1060	case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
   1061	case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
   1062	case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
   1063	case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
   1064	case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
   1065		idx = (p_tlv->tlv_type - DRV_TLV_SCSI_CHECK_1_TIMESTAMP) / 2;
   1066		p_time = &p_drv_buf->scsi_chk_tstamp[idx];
   1067
   1068		return qed_mfw_get_tlv_time_value(p_time, p_buf);
   1069	default:
   1070		break;
   1071	}
   1072
   1073	return -1;
   1074}
   1075
   1076static int
   1077qed_mfw_get_iscsi_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
   1078			    struct qed_mfw_tlv_iscsi *p_drv_buf,
   1079			    struct qed_tlv_parsed_buf *p_buf)
   1080{
   1081	switch (p_tlv->tlv_type) {
   1082	case DRV_TLV_TARGET_LLMNR_ENABLED:
   1083		if (p_drv_buf->target_llmnr_set) {
   1084			p_buf->p_val = &p_drv_buf->target_llmnr;
   1085			return sizeof(p_drv_buf->target_llmnr);
   1086		}
   1087		break;
   1088	case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
   1089		if (p_drv_buf->header_digest_set) {
   1090			p_buf->p_val = &p_drv_buf->header_digest;
   1091			return sizeof(p_drv_buf->header_digest);
   1092		}
   1093		break;
   1094	case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
   1095		if (p_drv_buf->data_digest_set) {
   1096			p_buf->p_val = &p_drv_buf->data_digest;
   1097			return sizeof(p_drv_buf->data_digest);
   1098		}
   1099		break;
   1100	case DRV_TLV_AUTHENTICATION_METHOD:
   1101		if (p_drv_buf->auth_method_set) {
   1102			p_buf->p_val = &p_drv_buf->auth_method;
   1103			return sizeof(p_drv_buf->auth_method);
   1104		}
   1105		break;
   1106	case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
   1107		if (p_drv_buf->boot_taget_portal_set) {
   1108			p_buf->p_val = &p_drv_buf->boot_taget_portal;
   1109			return sizeof(p_drv_buf->boot_taget_portal);
   1110		}
   1111		break;
   1112	case DRV_TLV_MAX_FRAME_SIZE:
   1113		if (p_drv_buf->frame_size_set) {
   1114			p_buf->p_val = &p_drv_buf->frame_size;
   1115			return sizeof(p_drv_buf->frame_size);
   1116		}
   1117		break;
   1118	case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
   1119		if (p_drv_buf->tx_desc_size_set) {
   1120			p_buf->p_val = &p_drv_buf->tx_desc_size;
   1121			return sizeof(p_drv_buf->tx_desc_size);
   1122		}
   1123		break;
   1124	case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
   1125		if (p_drv_buf->rx_desc_size_set) {
   1126			p_buf->p_val = &p_drv_buf->rx_desc_size;
   1127			return sizeof(p_drv_buf->rx_desc_size);
   1128		}
   1129		break;
   1130	case DRV_TLV_ISCSI_BOOT_PROGRESS:
   1131		if (p_drv_buf->boot_progress_set) {
   1132			p_buf->p_val = &p_drv_buf->boot_progress;
   1133			return sizeof(p_drv_buf->boot_progress);
   1134		}
   1135		break;
   1136	case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
   1137		if (p_drv_buf->tx_desc_qdepth_set) {
   1138			p_buf->p_val = &p_drv_buf->tx_desc_qdepth;
   1139			return sizeof(p_drv_buf->tx_desc_qdepth);
   1140		}
   1141		break;
   1142	case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
   1143		if (p_drv_buf->rx_desc_qdepth_set) {
   1144			p_buf->p_val = &p_drv_buf->rx_desc_qdepth;
   1145			return sizeof(p_drv_buf->rx_desc_qdepth);
   1146		}
   1147		break;
   1148	case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
   1149		if (p_drv_buf->rx_frames_set) {
   1150			p_buf->p_val = &p_drv_buf->rx_frames;
   1151			return sizeof(p_drv_buf->rx_frames);
   1152		}
   1153		break;
   1154	case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
   1155		if (p_drv_buf->rx_bytes_set) {
   1156			p_buf->p_val = &p_drv_buf->rx_bytes;
   1157			return sizeof(p_drv_buf->rx_bytes);
   1158		}
   1159		break;
   1160	case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
   1161		if (p_drv_buf->tx_frames_set) {
   1162			p_buf->p_val = &p_drv_buf->tx_frames;
   1163			return sizeof(p_drv_buf->tx_frames);
   1164		}
   1165		break;
   1166	case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
   1167		if (p_drv_buf->tx_bytes_set) {
   1168			p_buf->p_val = &p_drv_buf->tx_bytes;
   1169			return sizeof(p_drv_buf->tx_bytes);
   1170		}
   1171		break;
   1172	default:
   1173		break;
   1174	}
   1175
   1176	return -1;
   1177}
   1178
   1179static int qed_mfw_update_tlvs(struct qed_hwfn *p_hwfn,
   1180			       u8 tlv_group, u8 *p_mfw_buf, u32 size)
   1181{
   1182	union qed_mfw_tlv_data *p_tlv_data;
   1183	struct qed_tlv_parsed_buf buffer;
   1184	struct qed_drv_tlv_hdr tlv;
   1185	int len = 0;
   1186	u32 offset;
   1187	u8 *p_tlv;
   1188
   1189	p_tlv_data = vzalloc(sizeof(*p_tlv_data));
   1190	if (!p_tlv_data)
   1191		return -ENOMEM;
   1192
   1193	if (qed_mfw_fill_tlv_data(p_hwfn, tlv_group, p_tlv_data)) {
   1194		vfree(p_tlv_data);
   1195		return -EINVAL;
   1196	}
   1197
   1198	memset(&tlv, 0, sizeof(tlv));
   1199	for (offset = 0; offset < size;
   1200	     offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
   1201		p_tlv = &p_mfw_buf[offset];
   1202		tlv.tlv_type = TLV_TYPE(p_tlv);
   1203		tlv.tlv_length = TLV_LENGTH(p_tlv);
   1204		tlv.tlv_flags = TLV_FLAGS(p_tlv);
   1205
   1206		DP_VERBOSE(p_hwfn, QED_MSG_SP,
   1207			   "Type %d length = %d flags = 0x%x\n", tlv.tlv_type,
   1208			   tlv.tlv_length, tlv.tlv_flags);
   1209
   1210		if (tlv_group == QED_MFW_TLV_GENERIC)
   1211			len = qed_mfw_get_gen_tlv_value(&tlv,
   1212							&p_tlv_data->generic,
   1213							&buffer);
   1214		else if (tlv_group == QED_MFW_TLV_ETH)
   1215			len = qed_mfw_get_eth_tlv_value(&tlv,
   1216							&p_tlv_data->eth,
   1217							&buffer);
   1218		else if (tlv_group == QED_MFW_TLV_FCOE)
   1219			len = qed_mfw_get_fcoe_tlv_value(&tlv,
   1220							 &p_tlv_data->fcoe,
   1221							 &buffer);
   1222		else
   1223			len = qed_mfw_get_iscsi_tlv_value(&tlv,
   1224							  &p_tlv_data->iscsi,
   1225							  &buffer);
   1226
   1227		if (len > 0) {
   1228			WARN(len > 4 * tlv.tlv_length,
   1229			     "Incorrect MFW TLV length %d, it shouldn't be greater than %d\n",
   1230			     len, 4 * tlv.tlv_length);
   1231			len = min_t(int, len, 4 * tlv.tlv_length);
   1232			tlv.tlv_flags |= QED_DRV_TLV_FLAGS_CHANGED;
   1233			TLV_FLAGS(p_tlv) = tlv.tlv_flags;
   1234			memcpy(p_mfw_buf + offset + sizeof(tlv),
   1235			       buffer.p_val, len);
   1236		}
   1237	}
   1238
   1239	vfree(p_tlv_data);
   1240
   1241	return 0;
   1242}
   1243
   1244int qed_mfw_process_tlv_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
   1245{
   1246	u32 addr, size, offset, resp, param, val, global_offsize, global_addr;
   1247	u8 tlv_group = 0, id, *p_mfw_buf = NULL, *p_temp;
   1248	struct qed_drv_tlv_hdr tlv;
   1249	int rc;
   1250
   1251	addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base,
   1252				    PUBLIC_GLOBAL);
   1253	global_offsize = qed_rd(p_hwfn, p_ptt, addr);
   1254	global_addr = SECTION_ADDR(global_offsize, 0);
   1255	addr = global_addr + offsetof(struct public_global, data_ptr);
   1256	addr = qed_rd(p_hwfn, p_ptt, addr);
   1257	size = qed_rd(p_hwfn, p_ptt, global_addr +
   1258		      offsetof(struct public_global, data_size));
   1259
   1260	if (!size) {
   1261		DP_NOTICE(p_hwfn, "Invalid TLV req size = %d\n", size);
   1262		goto drv_done;
   1263	}
   1264
   1265	p_mfw_buf = vzalloc(size);
   1266	if (!p_mfw_buf) {
   1267		DP_NOTICE(p_hwfn, "Failed allocate memory for p_mfw_buf\n");
   1268		goto drv_done;
   1269	}
   1270
   1271	/* Read the TLV request to local buffer. MFW represents the TLV in
   1272	 * little endian format and mcp returns it bigendian format. Hence
   1273	 * driver need to convert data to little endian first and then do the
   1274	 * memcpy (casting) to preserve the MFW TLV format in the driver buffer.
   1275	 *
   1276	 */
   1277	for (offset = 0; offset < size; offset += sizeof(u32)) {
   1278		val = qed_rd(p_hwfn, p_ptt, addr + offset);
   1279		val = be32_to_cpu((__force __be32)val);
   1280		memcpy(&p_mfw_buf[offset], &val, sizeof(u32));
   1281	}
   1282
   1283	/* Parse the headers to enumerate the requested TLV groups */
   1284	for (offset = 0; offset < size;
   1285	     offset += sizeof(tlv) + sizeof(u32) * tlv.tlv_length) {
   1286		p_temp = &p_mfw_buf[offset];
   1287		tlv.tlv_type = TLV_TYPE(p_temp);
   1288		tlv.tlv_length = TLV_LENGTH(p_temp);
   1289		if (qed_mfw_get_tlv_group(tlv.tlv_type, &tlv_group))
   1290			DP_VERBOSE(p_hwfn, NETIF_MSG_DRV,
   1291				   "Un recognized TLV %d\n", tlv.tlv_type);
   1292	}
   1293
   1294	/* Sanitize the TLV groups according to personality */
   1295	if ((tlv_group & QED_MFW_TLV_ETH) && !QED_IS_L2_PERSONALITY(p_hwfn)) {
   1296		DP_VERBOSE(p_hwfn, QED_MSG_SP,
   1297			   "Skipping L2 TLVs for non-L2 function\n");
   1298		tlv_group &= ~QED_MFW_TLV_ETH;
   1299	}
   1300
   1301	if ((tlv_group & QED_MFW_TLV_FCOE) &&
   1302	    p_hwfn->hw_info.personality != QED_PCI_FCOE) {
   1303		DP_VERBOSE(p_hwfn, QED_MSG_SP,
   1304			   "Skipping FCoE TLVs for non-FCoE function\n");
   1305		tlv_group &= ~QED_MFW_TLV_FCOE;
   1306	}
   1307
   1308	if ((tlv_group & QED_MFW_TLV_ISCSI) &&
   1309	    p_hwfn->hw_info.personality != QED_PCI_ISCSI &&
   1310		p_hwfn->hw_info.personality != QED_PCI_NVMETCP) {
   1311		DP_VERBOSE(p_hwfn, QED_MSG_SP,
   1312			   "Skipping iSCSI TLVs for non-iSCSI function\n");
   1313		tlv_group &= ~QED_MFW_TLV_ISCSI;
   1314	}
   1315
   1316	/* Update the TLV values in the local buffer */
   1317	for (id = QED_MFW_TLV_GENERIC; id < QED_MFW_TLV_MAX; id <<= 1) {
   1318		if (tlv_group & id)
   1319			if (qed_mfw_update_tlvs(p_hwfn, id, p_mfw_buf, size))
   1320				goto drv_done;
   1321	}
   1322
   1323	/* Write the TLV data to shared memory. The stream of 4 bytes first need
   1324	 * to be mem-copied to u32 element to make it as LSB format. And then
   1325	 * converted to big endian as required by mcp-write.
   1326	 */
   1327	for (offset = 0; offset < size; offset += sizeof(u32)) {
   1328		memcpy(&val, &p_mfw_buf[offset], sizeof(u32));
   1329		val = (__force u32)cpu_to_be32(val);
   1330		qed_wr(p_hwfn, p_ptt, addr + offset, val);
   1331	}
   1332
   1333drv_done:
   1334	rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,
   1335			 &param);
   1336
   1337	vfree(p_mfw_buf);
   1338
   1339	return rc;
   1340}