brintos

brintos / linux-shallow public Read only

0
0
Text · 39.6 KiB · f55eed0 Raw
1341 lines · c
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 int246qed_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 int308qed_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 int411qed_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->min = 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 int442qed_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 int1077qed_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		else1223			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 in1272	 * little endian format and mcp returns it bigendian format. Hence1273	 * driver need to convert data to little endian first and then do the1274	 * 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 need1324	 * to be mem-copied to u32 element to make it as LSB format. And then1325	 * 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}1341