0001
0002
0003
0004 #include <linux/types.h>
0005 #include <asm/byteorder.h>
0006 #include <linux/bug.h>
0007 #include <linux/errno.h>
0008 #include <linux/kernel.h>
0009 #include <linux/slab.h>
0010 #include <linux/string.h>
0011 #include <linux/vmalloc.h>
0012 #include "qed.h"
0013 #include "qed_hw.h"
0014 #include "qed_mcp.h"
0015 #include "qed_reg_addr.h"
0016
0017 #define TLV_TYPE(p) (p[0])
0018 #define TLV_LENGTH(p) (p[1])
0019 #define TLV_FLAGS(p) (p[3])
0020
0021 #define QED_TLV_DATA_MAX (14)
0022 struct qed_tlv_parsed_buf {
0023
0024 void *p_val;
0025
0026
0027 u8 data[QED_TLV_DATA_MAX];
0028 };
0029
0030 static int qed_mfw_get_tlv_group(u8 tlv_type, u8 *tlv_group)
0031 {
0032 switch (tlv_type) {
0033 case DRV_TLV_FEATURE_FLAGS:
0034 case DRV_TLV_LOCAL_ADMIN_ADDR:
0035 case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
0036 case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
0037 case DRV_TLV_OS_DRIVER_STATES:
0038 case DRV_TLV_PXE_BOOT_PROGRESS:
0039 case DRV_TLV_RX_FRAMES_RECEIVED:
0040 case DRV_TLV_RX_BYTES_RECEIVED:
0041 case DRV_TLV_TX_FRAMES_SENT:
0042 case DRV_TLV_TX_BYTES_SENT:
0043 case DRV_TLV_NPIV_ENABLED:
0044 case DRV_TLV_PCIE_BUS_RX_UTILIZATION:
0045 case DRV_TLV_PCIE_BUS_TX_UTILIZATION:
0046 case DRV_TLV_DEVICE_CPU_CORES_UTILIZATION:
0047 case DRV_TLV_LAST_VALID_DCC_TLV_RECEIVED:
0048 case DRV_TLV_NCSI_RX_BYTES_RECEIVED:
0049 case DRV_TLV_NCSI_TX_BYTES_SENT:
0050 *tlv_group |= QED_MFW_TLV_GENERIC;
0051 break;
0052 case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
0053 case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
0054 case DRV_TLV_PROMISCUOUS_MODE:
0055 case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
0056 case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
0057 case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
0058 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
0059 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
0060 case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
0061 case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
0062 case DRV_TLV_IOV_OFFLOAD:
0063 case DRV_TLV_TX_QUEUES_EMPTY:
0064 case DRV_TLV_RX_QUEUES_EMPTY:
0065 case DRV_TLV_TX_QUEUES_FULL:
0066 case DRV_TLV_RX_QUEUES_FULL:
0067 *tlv_group |= QED_MFW_TLV_ETH;
0068 break;
0069 case DRV_TLV_SCSI_TO:
0070 case DRV_TLV_R_T_TOV:
0071 case DRV_TLV_R_A_TOV:
0072 case DRV_TLV_E_D_TOV:
0073 case DRV_TLV_CR_TOV:
0074 case DRV_TLV_BOOT_TYPE:
0075 case DRV_TLV_NPIV_STATE:
0076 case DRV_TLV_NUM_OF_NPIV_IDS:
0077 case DRV_TLV_SWITCH_NAME:
0078 case DRV_TLV_SWITCH_PORT_NUM:
0079 case DRV_TLV_SWITCH_PORT_ID:
0080 case DRV_TLV_VENDOR_NAME:
0081 case DRV_TLV_SWITCH_MODEL:
0082 case DRV_TLV_SWITCH_FW_VER:
0083 case DRV_TLV_QOS_PRIORITY_PER_802_1P:
0084 case DRV_TLV_PORT_ALIAS:
0085 case DRV_TLV_PORT_STATE:
0086 case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
0087 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
0088 case DRV_TLV_LINK_FAILURE_COUNT:
0089 case DRV_TLV_FCOE_BOOT_PROGRESS:
0090 case DRV_TLV_RX_BROADCAST_PACKETS:
0091 case DRV_TLV_TX_BROADCAST_PACKETS:
0092 case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
0093 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
0094 case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
0095 case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
0096 case DRV_TLV_FCOE_TX_FRAMES_SENT:
0097 case DRV_TLV_FCOE_TX_BYTES_SENT:
0098 case DRV_TLV_CRC_ERROR_COUNT:
0099 case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
0100 case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
0101 case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
0102 case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
0103 case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
0104 case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
0105 case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
0106 case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
0107 case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
0108 case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
0109 case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
0110 case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
0111 case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
0112 case DRV_TLV_DISPARITY_ERROR_COUNT:
0113 case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
0114 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
0115 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
0116 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
0117 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
0118 case DRV_TLV_LAST_FLOGI_TIMESTAMP:
0119 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
0120 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
0121 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
0122 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
0123 case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
0124 case DRV_TLV_LAST_FLOGI_RJT:
0125 case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
0126 case DRV_TLV_FDISCS_SENT_COUNT:
0127 case DRV_TLV_FDISC_ACCS_RECEIVED:
0128 case DRV_TLV_FDISC_RJTS_RECEIVED:
0129 case DRV_TLV_PLOGI_SENT_COUNT:
0130 case DRV_TLV_PLOGI_ACCS_RECEIVED:
0131 case DRV_TLV_PLOGI_RJTS_RECEIVED:
0132 case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
0133 case DRV_TLV_PLOGI_1_TIMESTAMP:
0134 case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
0135 case DRV_TLV_PLOGI_2_TIMESTAMP:
0136 case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
0137 case DRV_TLV_PLOGI_3_TIMESTAMP:
0138 case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
0139 case DRV_TLV_PLOGI_4_TIMESTAMP:
0140 case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
0141 case DRV_TLV_PLOGI_5_TIMESTAMP:
0142 case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
0143 case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
0144 case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
0145 case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
0146 case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
0147 case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
0148 case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
0149 case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
0150 case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
0151 case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
0152 case DRV_TLV_LOGOS_ISSUED:
0153 case DRV_TLV_LOGO_ACCS_RECEIVED:
0154 case DRV_TLV_LOGO_RJTS_RECEIVED:
0155 case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
0156 case DRV_TLV_LOGO_1_TIMESTAMP:
0157 case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
0158 case DRV_TLV_LOGO_2_TIMESTAMP:
0159 case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
0160 case DRV_TLV_LOGO_3_TIMESTAMP:
0161 case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
0162 case DRV_TLV_LOGO_4_TIMESTAMP:
0163 case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
0164 case DRV_TLV_LOGO_5_TIMESTAMP:
0165 case DRV_TLV_LOGOS_RECEIVED:
0166 case DRV_TLV_ACCS_ISSUED:
0167 case DRV_TLV_PRLIS_ISSUED:
0168 case DRV_TLV_ACCS_RECEIVED:
0169 case DRV_TLV_ABTS_SENT_COUNT:
0170 case DRV_TLV_ABTS_ACCS_RECEIVED:
0171 case DRV_TLV_ABTS_RJTS_RECEIVED:
0172 case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
0173 case DRV_TLV_ABTS_1_TIMESTAMP:
0174 case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
0175 case DRV_TLV_ABTS_2_TIMESTAMP:
0176 case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
0177 case DRV_TLV_ABTS_3_TIMESTAMP:
0178 case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
0179 case DRV_TLV_ABTS_4_TIMESTAMP:
0180 case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
0181 case DRV_TLV_ABTS_5_TIMESTAMP:
0182 case DRV_TLV_RSCNS_RECEIVED:
0183 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
0184 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
0185 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
0186 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
0187 case DRV_TLV_LUN_RESETS_ISSUED:
0188 case DRV_TLV_ABORT_TASK_SETS_ISSUED:
0189 case DRV_TLV_TPRLOS_SENT:
0190 case DRV_TLV_NOS_SENT_COUNT:
0191 case DRV_TLV_NOS_RECEIVED_COUNT:
0192 case DRV_TLV_OLS_COUNT:
0193 case DRV_TLV_LR_COUNT:
0194 case DRV_TLV_LRR_COUNT:
0195 case DRV_TLV_LIP_SENT_COUNT:
0196 case DRV_TLV_LIP_RECEIVED_COUNT:
0197 case DRV_TLV_EOFA_COUNT:
0198 case DRV_TLV_EOFNI_COUNT:
0199 case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
0200 case DRV_TLV_SCSI_STATUS_CONDITION_MET_COUNT:
0201 case DRV_TLV_SCSI_STATUS_BUSY_COUNT:
0202 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_COUNT:
0203 case DRV_TLV_SCSI_STATUS_INTERMEDIATE_CONDITION_MET_COUNT:
0204 case DRV_TLV_SCSI_STATUS_RESERVATION_CONFLICT_COUNT:
0205 case DRV_TLV_SCSI_STATUS_TASK_SET_FULL_COUNT:
0206 case DRV_TLV_SCSI_STATUS_ACA_ACTIVE_COUNT:
0207 case DRV_TLV_SCSI_STATUS_TASK_ABORTED_COUNT:
0208 case DRV_TLV_SCSI_CHECK_CONDITION_1_RECEIVED_SK_ASC_ASCQ:
0209 case DRV_TLV_SCSI_CHECK_1_TIMESTAMP:
0210 case DRV_TLV_SCSI_CHECK_CONDITION_2_RECEIVED_SK_ASC_ASCQ:
0211 case DRV_TLV_SCSI_CHECK_2_TIMESTAMP:
0212 case DRV_TLV_SCSI_CHECK_CONDITION_3_RECEIVED_SK_ASC_ASCQ:
0213 case DRV_TLV_SCSI_CHECK_3_TIMESTAMP:
0214 case DRV_TLV_SCSI_CHECK_CONDITION_4_RECEIVED_SK_ASC_ASCQ:
0215 case DRV_TLV_SCSI_CHECK_4_TIMESTAMP:
0216 case DRV_TLV_SCSI_CHECK_CONDITION_5_RECEIVED_SK_ASC_ASCQ:
0217 case DRV_TLV_SCSI_CHECK_5_TIMESTAMP:
0218 *tlv_group = QED_MFW_TLV_FCOE;
0219 break;
0220 case DRV_TLV_TARGET_LLMNR_ENABLED:
0221 case DRV_TLV_HEADER_DIGEST_FLAG_ENABLED:
0222 case DRV_TLV_DATA_DIGEST_FLAG_ENABLED:
0223 case DRV_TLV_AUTHENTICATION_METHOD:
0224 case DRV_TLV_ISCSI_BOOT_TARGET_PORTAL:
0225 case DRV_TLV_MAX_FRAME_SIZE:
0226 case DRV_TLV_PDU_TX_DESCRIPTORS_QUEUE_SIZE:
0227 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_SIZE:
0228 case DRV_TLV_ISCSI_BOOT_PROGRESS:
0229 case DRV_TLV_PDU_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
0230 case DRV_TLV_PDU_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
0231 case DRV_TLV_ISCSI_PDU_RX_FRAMES_RECEIVED:
0232 case DRV_TLV_ISCSI_PDU_RX_BYTES_RECEIVED:
0233 case DRV_TLV_ISCSI_PDU_TX_FRAMES_SENT:
0234 case DRV_TLV_ISCSI_PDU_TX_BYTES_SENT:
0235 *tlv_group |= QED_MFW_TLV_ISCSI;
0236 break;
0237 default:
0238 return -EINVAL;
0239 }
0240
0241 return 0;
0242 }
0243
0244
0245 static int
0246 qed_mfw_get_gen_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
0247 struct qed_mfw_tlv_generic *p_drv_buf,
0248 struct qed_tlv_parsed_buf *p_buf)
0249 {
0250 switch (p_tlv->tlv_type) {
0251 case DRV_TLV_FEATURE_FLAGS:
0252 if (p_drv_buf->flags.b_set) {
0253 memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
0254 p_buf->data[0] = p_drv_buf->flags.ipv4_csum_offload ?
0255 1 : 0;
0256 p_buf->data[0] |= (p_drv_buf->flags.lso_supported ?
0257 1 : 0) << 1;
0258 p_buf->p_val = p_buf->data;
0259 return QED_MFW_TLV_FLAGS_SIZE;
0260 }
0261 break;
0262
0263 case DRV_TLV_LOCAL_ADMIN_ADDR:
0264 case DRV_TLV_ADDITIONAL_MAC_ADDR_1:
0265 case DRV_TLV_ADDITIONAL_MAC_ADDR_2:
0266 {
0267 int idx = p_tlv->tlv_type - DRV_TLV_LOCAL_ADMIN_ADDR;
0268
0269 if (p_drv_buf->mac_set[idx]) {
0270 p_buf->p_val = p_drv_buf->mac[idx];
0271 return ETH_ALEN;
0272 }
0273 break;
0274 }
0275
0276 case DRV_TLV_RX_FRAMES_RECEIVED:
0277 if (p_drv_buf->rx_frames_set) {
0278 p_buf->p_val = &p_drv_buf->rx_frames;
0279 return sizeof(p_drv_buf->rx_frames);
0280 }
0281 break;
0282 case DRV_TLV_RX_BYTES_RECEIVED:
0283 if (p_drv_buf->rx_bytes_set) {
0284 p_buf->p_val = &p_drv_buf->rx_bytes;
0285 return sizeof(p_drv_buf->rx_bytes);
0286 }
0287 break;
0288 case DRV_TLV_TX_FRAMES_SENT:
0289 if (p_drv_buf->tx_frames_set) {
0290 p_buf->p_val = &p_drv_buf->tx_frames;
0291 return sizeof(p_drv_buf->tx_frames);
0292 }
0293 break;
0294 case DRV_TLV_TX_BYTES_SENT:
0295 if (p_drv_buf->tx_bytes_set) {
0296 p_buf->p_val = &p_drv_buf->tx_bytes;
0297 return sizeof(p_drv_buf->tx_bytes);
0298 }
0299 break;
0300 default:
0301 break;
0302 }
0303
0304 return -1;
0305 }
0306
0307 static int
0308 qed_mfw_get_eth_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
0309 struct qed_mfw_tlv_eth *p_drv_buf,
0310 struct qed_tlv_parsed_buf *p_buf)
0311 {
0312 switch (p_tlv->tlv_type) {
0313 case DRV_TLV_LSO_MAX_OFFLOAD_SIZE:
0314 if (p_drv_buf->lso_maxoff_size_set) {
0315 p_buf->p_val = &p_drv_buf->lso_maxoff_size;
0316 return sizeof(p_drv_buf->lso_maxoff_size);
0317 }
0318 break;
0319 case DRV_TLV_LSO_MIN_SEGMENT_COUNT:
0320 if (p_drv_buf->lso_minseg_size_set) {
0321 p_buf->p_val = &p_drv_buf->lso_minseg_size;
0322 return sizeof(p_drv_buf->lso_minseg_size);
0323 }
0324 break;
0325 case DRV_TLV_PROMISCUOUS_MODE:
0326 if (p_drv_buf->prom_mode_set) {
0327 p_buf->p_val = &p_drv_buf->prom_mode;
0328 return sizeof(p_drv_buf->prom_mode);
0329 }
0330 break;
0331 case DRV_TLV_TX_DESCRIPTORS_QUEUE_SIZE:
0332 if (p_drv_buf->tx_descr_size_set) {
0333 p_buf->p_val = &p_drv_buf->tx_descr_size;
0334 return sizeof(p_drv_buf->tx_descr_size);
0335 }
0336 break;
0337 case DRV_TLV_RX_DESCRIPTORS_QUEUE_SIZE:
0338 if (p_drv_buf->rx_descr_size_set) {
0339 p_buf->p_val = &p_drv_buf->rx_descr_size;
0340 return sizeof(p_drv_buf->rx_descr_size);
0341 }
0342 break;
0343 case DRV_TLV_NUM_OF_NET_QUEUE_VMQ_CFG:
0344 if (p_drv_buf->netq_count_set) {
0345 p_buf->p_val = &p_drv_buf->netq_count;
0346 return sizeof(p_drv_buf->netq_count);
0347 }
0348 break;
0349 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV4:
0350 if (p_drv_buf->tcp4_offloads_set) {
0351 p_buf->p_val = &p_drv_buf->tcp4_offloads;
0352 return sizeof(p_drv_buf->tcp4_offloads);
0353 }
0354 break;
0355 case DRV_TLV_NUM_OFFLOADED_CONNECTIONS_TCP_IPV6:
0356 if (p_drv_buf->tcp6_offloads_set) {
0357 p_buf->p_val = &p_drv_buf->tcp6_offloads;
0358 return sizeof(p_drv_buf->tcp6_offloads);
0359 }
0360 break;
0361 case DRV_TLV_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
0362 if (p_drv_buf->tx_descr_qdepth_set) {
0363 p_buf->p_val = &p_drv_buf->tx_descr_qdepth;
0364 return sizeof(p_drv_buf->tx_descr_qdepth);
0365 }
0366 break;
0367 case DRV_TLV_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
0368 if (p_drv_buf->rx_descr_qdepth_set) {
0369 p_buf->p_val = &p_drv_buf->rx_descr_qdepth;
0370 return sizeof(p_drv_buf->rx_descr_qdepth);
0371 }
0372 break;
0373 case DRV_TLV_IOV_OFFLOAD:
0374 if (p_drv_buf->iov_offload_set) {
0375 p_buf->p_val = &p_drv_buf->iov_offload;
0376 return sizeof(p_drv_buf->iov_offload);
0377 }
0378 break;
0379 case DRV_TLV_TX_QUEUES_EMPTY:
0380 if (p_drv_buf->txqs_empty_set) {
0381 p_buf->p_val = &p_drv_buf->txqs_empty;
0382 return sizeof(p_drv_buf->txqs_empty);
0383 }
0384 break;
0385 case DRV_TLV_RX_QUEUES_EMPTY:
0386 if (p_drv_buf->rxqs_empty_set) {
0387 p_buf->p_val = &p_drv_buf->rxqs_empty;
0388 return sizeof(p_drv_buf->rxqs_empty);
0389 }
0390 break;
0391 case DRV_TLV_TX_QUEUES_FULL:
0392 if (p_drv_buf->num_txqs_full_set) {
0393 p_buf->p_val = &p_drv_buf->num_txqs_full;
0394 return sizeof(p_drv_buf->num_txqs_full);
0395 }
0396 break;
0397 case DRV_TLV_RX_QUEUES_FULL:
0398 if (p_drv_buf->num_rxqs_full_set) {
0399 p_buf->p_val = &p_drv_buf->num_rxqs_full;
0400 return sizeof(p_drv_buf->num_rxqs_full);
0401 }
0402 break;
0403 default:
0404 break;
0405 }
0406
0407 return -1;
0408 }
0409
0410 static int
0411 qed_mfw_get_tlv_time_value(struct qed_mfw_tlv_time *p_time,
0412 struct qed_tlv_parsed_buf *p_buf)
0413 {
0414 if (!p_time->b_set)
0415 return -1;
0416
0417
0418 if (p_time->month > 12)
0419 p_time->month = 0;
0420 if (p_time->day > 31)
0421 p_time->day = 0;
0422 if (p_time->hour > 23)
0423 p_time->hour = 0;
0424 if (p_time->min > 59)
0425 p_time->hour = 0;
0426 if (p_time->msec > 999)
0427 p_time->msec = 0;
0428 if (p_time->usec > 999)
0429 p_time->usec = 0;
0430
0431 memset(p_buf->data, 0, sizeof(u8) * QED_TLV_DATA_MAX);
0432 snprintf(p_buf->data, 14, "%d%d%d%d%d%d",
0433 p_time->month, p_time->day,
0434 p_time->hour, p_time->min, p_time->msec, p_time->usec);
0435
0436 p_buf->p_val = p_buf->data;
0437
0438 return QED_MFW_TLV_TIME_SIZE;
0439 }
0440
0441 static int
0442 qed_mfw_get_fcoe_tlv_value(struct qed_drv_tlv_hdr *p_tlv,
0443 struct qed_mfw_tlv_fcoe *p_drv_buf,
0444 struct qed_tlv_parsed_buf *p_buf)
0445 {
0446 struct qed_mfw_tlv_time *p_time;
0447 u8 idx;
0448
0449 switch (p_tlv->tlv_type) {
0450 case DRV_TLV_SCSI_TO:
0451 if (p_drv_buf->scsi_timeout_set) {
0452 p_buf->p_val = &p_drv_buf->scsi_timeout;
0453 return sizeof(p_drv_buf->scsi_timeout);
0454 }
0455 break;
0456 case DRV_TLV_R_T_TOV:
0457 if (p_drv_buf->rt_tov_set) {
0458 p_buf->p_val = &p_drv_buf->rt_tov;
0459 return sizeof(p_drv_buf->rt_tov);
0460 }
0461 break;
0462 case DRV_TLV_R_A_TOV:
0463 if (p_drv_buf->ra_tov_set) {
0464 p_buf->p_val = &p_drv_buf->ra_tov;
0465 return sizeof(p_drv_buf->ra_tov);
0466 }
0467 break;
0468 case DRV_TLV_E_D_TOV:
0469 if (p_drv_buf->ed_tov_set) {
0470 p_buf->p_val = &p_drv_buf->ed_tov;
0471 return sizeof(p_drv_buf->ed_tov);
0472 }
0473 break;
0474 case DRV_TLV_CR_TOV:
0475 if (p_drv_buf->cr_tov_set) {
0476 p_buf->p_val = &p_drv_buf->cr_tov;
0477 return sizeof(p_drv_buf->cr_tov);
0478 }
0479 break;
0480 case DRV_TLV_BOOT_TYPE:
0481 if (p_drv_buf->boot_type_set) {
0482 p_buf->p_val = &p_drv_buf->boot_type;
0483 return sizeof(p_drv_buf->boot_type);
0484 }
0485 break;
0486 case DRV_TLV_NPIV_STATE:
0487 if (p_drv_buf->npiv_state_set) {
0488 p_buf->p_val = &p_drv_buf->npiv_state;
0489 return sizeof(p_drv_buf->npiv_state);
0490 }
0491 break;
0492 case DRV_TLV_NUM_OF_NPIV_IDS:
0493 if (p_drv_buf->num_npiv_ids_set) {
0494 p_buf->p_val = &p_drv_buf->num_npiv_ids;
0495 return sizeof(p_drv_buf->num_npiv_ids);
0496 }
0497 break;
0498 case DRV_TLV_SWITCH_NAME:
0499 if (p_drv_buf->switch_name_set) {
0500 p_buf->p_val = &p_drv_buf->switch_name;
0501 return sizeof(p_drv_buf->switch_name);
0502 }
0503 break;
0504 case DRV_TLV_SWITCH_PORT_NUM:
0505 if (p_drv_buf->switch_portnum_set) {
0506 p_buf->p_val = &p_drv_buf->switch_portnum;
0507 return sizeof(p_drv_buf->switch_portnum);
0508 }
0509 break;
0510 case DRV_TLV_SWITCH_PORT_ID:
0511 if (p_drv_buf->switch_portid_set) {
0512 p_buf->p_val = &p_drv_buf->switch_portid;
0513 return sizeof(p_drv_buf->switch_portid);
0514 }
0515 break;
0516 case DRV_TLV_VENDOR_NAME:
0517 if (p_drv_buf->vendor_name_set) {
0518 p_buf->p_val = &p_drv_buf->vendor_name;
0519 return sizeof(p_drv_buf->vendor_name);
0520 }
0521 break;
0522 case DRV_TLV_SWITCH_MODEL:
0523 if (p_drv_buf->switch_model_set) {
0524 p_buf->p_val = &p_drv_buf->switch_model;
0525 return sizeof(p_drv_buf->switch_model);
0526 }
0527 break;
0528 case DRV_TLV_SWITCH_FW_VER:
0529 if (p_drv_buf->switch_fw_version_set) {
0530 p_buf->p_val = &p_drv_buf->switch_fw_version;
0531 return sizeof(p_drv_buf->switch_fw_version);
0532 }
0533 break;
0534 case DRV_TLV_QOS_PRIORITY_PER_802_1P:
0535 if (p_drv_buf->qos_pri_set) {
0536 p_buf->p_val = &p_drv_buf->qos_pri;
0537 return sizeof(p_drv_buf->qos_pri);
0538 }
0539 break;
0540 case DRV_TLV_PORT_ALIAS:
0541 if (p_drv_buf->port_alias_set) {
0542 p_buf->p_val = &p_drv_buf->port_alias;
0543 return sizeof(p_drv_buf->port_alias);
0544 }
0545 break;
0546 case DRV_TLV_PORT_STATE:
0547 if (p_drv_buf->port_state_set) {
0548 p_buf->p_val = &p_drv_buf->port_state;
0549 return sizeof(p_drv_buf->port_state);
0550 }
0551 break;
0552 case DRV_TLV_FIP_TX_DESCRIPTORS_QUEUE_SIZE:
0553 if (p_drv_buf->fip_tx_descr_size_set) {
0554 p_buf->p_val = &p_drv_buf->fip_tx_descr_size;
0555 return sizeof(p_drv_buf->fip_tx_descr_size);
0556 }
0557 break;
0558 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_SIZE:
0559 if (p_drv_buf->fip_rx_descr_size_set) {
0560 p_buf->p_val = &p_drv_buf->fip_rx_descr_size;
0561 return sizeof(p_drv_buf->fip_rx_descr_size);
0562 }
0563 break;
0564 case DRV_TLV_LINK_FAILURE_COUNT:
0565 if (p_drv_buf->link_failures_set) {
0566 p_buf->p_val = &p_drv_buf->link_failures;
0567 return sizeof(p_drv_buf->link_failures);
0568 }
0569 break;
0570 case DRV_TLV_FCOE_BOOT_PROGRESS:
0571 if (p_drv_buf->fcoe_boot_progress_set) {
0572 p_buf->p_val = &p_drv_buf->fcoe_boot_progress;
0573 return sizeof(p_drv_buf->fcoe_boot_progress);
0574 }
0575 break;
0576 case DRV_TLV_RX_BROADCAST_PACKETS:
0577 if (p_drv_buf->rx_bcast_set) {
0578 p_buf->p_val = &p_drv_buf->rx_bcast;
0579 return sizeof(p_drv_buf->rx_bcast);
0580 }
0581 break;
0582 case DRV_TLV_TX_BROADCAST_PACKETS:
0583 if (p_drv_buf->tx_bcast_set) {
0584 p_buf->p_val = &p_drv_buf->tx_bcast;
0585 return sizeof(p_drv_buf->tx_bcast);
0586 }
0587 break;
0588 case DRV_TLV_FCOE_TX_DESCRIPTOR_QUEUE_AVG_DEPTH:
0589 if (p_drv_buf->fcoe_txq_depth_set) {
0590 p_buf->p_val = &p_drv_buf->fcoe_txq_depth;
0591 return sizeof(p_drv_buf->fcoe_txq_depth);
0592 }
0593 break;
0594 case DRV_TLV_FCOE_RX_DESCRIPTORS_QUEUE_AVG_DEPTH:
0595 if (p_drv_buf->fcoe_rxq_depth_set) {
0596 p_buf->p_val = &p_drv_buf->fcoe_rxq_depth;
0597 return sizeof(p_drv_buf->fcoe_rxq_depth);
0598 }
0599 break;
0600 case DRV_TLV_FCOE_RX_FRAMES_RECEIVED:
0601 if (p_drv_buf->fcoe_rx_frames_set) {
0602 p_buf->p_val = &p_drv_buf->fcoe_rx_frames;
0603 return sizeof(p_drv_buf->fcoe_rx_frames);
0604 }
0605 break;
0606 case DRV_TLV_FCOE_RX_BYTES_RECEIVED:
0607 if (p_drv_buf->fcoe_rx_bytes_set) {
0608 p_buf->p_val = &p_drv_buf->fcoe_rx_bytes;
0609 return sizeof(p_drv_buf->fcoe_rx_bytes);
0610 }
0611 break;
0612 case DRV_TLV_FCOE_TX_FRAMES_SENT:
0613 if (p_drv_buf->fcoe_tx_frames_set) {
0614 p_buf->p_val = &p_drv_buf->fcoe_tx_frames;
0615 return sizeof(p_drv_buf->fcoe_tx_frames);
0616 }
0617 break;
0618 case DRV_TLV_FCOE_TX_BYTES_SENT:
0619 if (p_drv_buf->fcoe_tx_bytes_set) {
0620 p_buf->p_val = &p_drv_buf->fcoe_tx_bytes;
0621 return sizeof(p_drv_buf->fcoe_tx_bytes);
0622 }
0623 break;
0624 case DRV_TLV_CRC_ERROR_COUNT:
0625 if (p_drv_buf->crc_count_set) {
0626 p_buf->p_val = &p_drv_buf->crc_count;
0627 return sizeof(p_drv_buf->crc_count);
0628 }
0629 break;
0630 case DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID:
0631 case DRV_TLV_CRC_ERROR_2_RECEIVED_SOURCE_FC_ID:
0632 case DRV_TLV_CRC_ERROR_3_RECEIVED_SOURCE_FC_ID:
0633 case DRV_TLV_CRC_ERROR_4_RECEIVED_SOURCE_FC_ID:
0634 case DRV_TLV_CRC_ERROR_5_RECEIVED_SOURCE_FC_ID:
0635 idx = (p_tlv->tlv_type -
0636 DRV_TLV_CRC_ERROR_1_RECEIVED_SOURCE_FC_ID) / 2;
0637
0638 if (p_drv_buf->crc_err_src_fcid_set[idx]) {
0639 p_buf->p_val = &p_drv_buf->crc_err_src_fcid[idx];
0640 return sizeof(p_drv_buf->crc_err_src_fcid[idx]);
0641 }
0642 break;
0643 case DRV_TLV_CRC_ERROR_1_TIMESTAMP:
0644 case DRV_TLV_CRC_ERROR_2_TIMESTAMP:
0645 case DRV_TLV_CRC_ERROR_3_TIMESTAMP:
0646 case DRV_TLV_CRC_ERROR_4_TIMESTAMP:
0647 case DRV_TLV_CRC_ERROR_5_TIMESTAMP:
0648 idx = (p_tlv->tlv_type - DRV_TLV_CRC_ERROR_1_TIMESTAMP) / 2;
0649
0650 return qed_mfw_get_tlv_time_value(&p_drv_buf->crc_err[idx],
0651 p_buf);
0652 case DRV_TLV_LOSS_OF_SYNC_ERROR_COUNT:
0653 if (p_drv_buf->losync_err_set) {
0654 p_buf->p_val = &p_drv_buf->losync_err;
0655 return sizeof(p_drv_buf->losync_err);
0656 }
0657 break;
0658 case DRV_TLV_LOSS_OF_SIGNAL_ERRORS:
0659 if (p_drv_buf->losig_err_set) {
0660 p_buf->p_val = &p_drv_buf->losig_err;
0661 return sizeof(p_drv_buf->losig_err);
0662 }
0663 break;
0664 case DRV_TLV_PRIMITIVE_SEQUENCE_PROTOCOL_ERROR_COUNT:
0665 if (p_drv_buf->primtive_err_set) {
0666 p_buf->p_val = &p_drv_buf->primtive_err;
0667 return sizeof(p_drv_buf->primtive_err);
0668 }
0669 break;
0670 case DRV_TLV_DISPARITY_ERROR_COUNT:
0671 if (p_drv_buf->disparity_err_set) {
0672 p_buf->p_val = &p_drv_buf->disparity_err;
0673 return sizeof(p_drv_buf->disparity_err);
0674 }
0675 break;
0676 case DRV_TLV_CODE_VIOLATION_ERROR_COUNT:
0677 if (p_drv_buf->code_violation_err_set) {
0678 p_buf->p_val = &p_drv_buf->code_violation_err;
0679 return sizeof(p_drv_buf->code_violation_err);
0680 }
0681 break;
0682 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1:
0683 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_2:
0684 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_3:
0685 case DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_4:
0686 idx = p_tlv->tlv_type -
0687 DRV_TLV_LAST_FLOGI_ISSUED_COMMON_PARAMETERS_WORD_1;
0688 if (p_drv_buf->flogi_param_set[idx]) {
0689 p_buf->p_val = &p_drv_buf->flogi_param[idx];
0690 return sizeof(p_drv_buf->flogi_param[idx]);
0691 }
0692 break;
0693 case DRV_TLV_LAST_FLOGI_TIMESTAMP:
0694 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_tstamp,
0695 p_buf);
0696 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1:
0697 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_2:
0698 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_3:
0699 case DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_4:
0700 idx = p_tlv->tlv_type -
0701 DRV_TLV_LAST_FLOGI_ACC_COMMON_PARAMETERS_WORD_1;
0702
0703 if (p_drv_buf->flogi_acc_param_set[idx]) {
0704 p_buf->p_val = &p_drv_buf->flogi_acc_param[idx];
0705 return sizeof(p_drv_buf->flogi_acc_param[idx]);
0706 }
0707 break;
0708 case DRV_TLV_LAST_FLOGI_ACC_TIMESTAMP:
0709 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_acc_tstamp,
0710 p_buf);
0711 case DRV_TLV_LAST_FLOGI_RJT:
0712 if (p_drv_buf->flogi_rjt_set) {
0713 p_buf->p_val = &p_drv_buf->flogi_rjt;
0714 return sizeof(p_drv_buf->flogi_rjt);
0715 }
0716 break;
0717 case DRV_TLV_LAST_FLOGI_RJT_TIMESTAMP:
0718 return qed_mfw_get_tlv_time_value(&p_drv_buf->flogi_rjt_tstamp,
0719 p_buf);
0720 case DRV_TLV_FDISCS_SENT_COUNT:
0721 if (p_drv_buf->fdiscs_set) {
0722 p_buf->p_val = &p_drv_buf->fdiscs;
0723 return sizeof(p_drv_buf->fdiscs);
0724 }
0725 break;
0726 case DRV_TLV_FDISC_ACCS_RECEIVED:
0727 if (p_drv_buf->fdisc_acc_set) {
0728 p_buf->p_val = &p_drv_buf->fdisc_acc;
0729 return sizeof(p_drv_buf->fdisc_acc);
0730 }
0731 break;
0732 case DRV_TLV_FDISC_RJTS_RECEIVED:
0733 if (p_drv_buf->fdisc_rjt_set) {
0734 p_buf->p_val = &p_drv_buf->fdisc_rjt;
0735 return sizeof(p_drv_buf->fdisc_rjt);
0736 }
0737 break;
0738 case DRV_TLV_PLOGI_SENT_COUNT:
0739 if (p_drv_buf->plogi_set) {
0740 p_buf->p_val = &p_drv_buf->plogi;
0741 return sizeof(p_drv_buf->plogi);
0742 }
0743 break;
0744 case DRV_TLV_PLOGI_ACCS_RECEIVED:
0745 if (p_drv_buf->plogi_acc_set) {
0746 p_buf->p_val = &p_drv_buf->plogi_acc;
0747 return sizeof(p_drv_buf->plogi_acc);
0748 }
0749 break;
0750 case DRV_TLV_PLOGI_RJTS_RECEIVED:
0751 if (p_drv_buf->plogi_rjt_set) {
0752 p_buf->p_val = &p_drv_buf->plogi_rjt;
0753 return sizeof(p_drv_buf->plogi_rjt);
0754 }
0755 break;
0756 case DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID:
0757 case DRV_TLV_PLOGI_2_SENT_DESTINATION_FC_ID:
0758 case DRV_TLV_PLOGI_3_SENT_DESTINATION_FC_ID:
0759 case DRV_TLV_PLOGI_4_SENT_DESTINATION_FC_ID:
0760 case DRV_TLV_PLOGI_5_SENT_DESTINATION_FC_ID:
0761 idx = (p_tlv->tlv_type -
0762 DRV_TLV_PLOGI_1_SENT_DESTINATION_FC_ID) / 2;
0763
0764 if (p_drv_buf->plogi_dst_fcid_set[idx]) {
0765 p_buf->p_val = &p_drv_buf->plogi_dst_fcid[idx];
0766 return sizeof(p_drv_buf->plogi_dst_fcid[idx]);
0767 }
0768 break;
0769 case DRV_TLV_PLOGI_1_TIMESTAMP:
0770 case DRV_TLV_PLOGI_2_TIMESTAMP:
0771 case DRV_TLV_PLOGI_3_TIMESTAMP:
0772 case DRV_TLV_PLOGI_4_TIMESTAMP:
0773 case DRV_TLV_PLOGI_5_TIMESTAMP:
0774 idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_TIMESTAMP) / 2;
0775
0776 return qed_mfw_get_tlv_time_value(&p_drv_buf->plogi_tstamp[idx],
0777 p_buf);
0778 case DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID:
0779 case DRV_TLV_PLOGI_2_ACC_RECEIVED_SOURCE_FC_ID:
0780 case DRV_TLV_PLOGI_3_ACC_RECEIVED_SOURCE_FC_ID:
0781 case DRV_TLV_PLOGI_4_ACC_RECEIVED_SOURCE_FC_ID:
0782 case DRV_TLV_PLOGI_5_ACC_RECEIVED_SOURCE_FC_ID:
0783 idx = (p_tlv->tlv_type -
0784 DRV_TLV_PLOGI_1_ACC_RECEIVED_SOURCE_FC_ID) / 2;
0785
0786 if (p_drv_buf->plogi_acc_src_fcid_set[idx]) {
0787 p_buf->p_val = &p_drv_buf->plogi_acc_src_fcid[idx];
0788 return sizeof(p_drv_buf->plogi_acc_src_fcid[idx]);
0789 }
0790 break;
0791 case DRV_TLV_PLOGI_1_ACC_TIMESTAMP:
0792 case DRV_TLV_PLOGI_2_ACC_TIMESTAMP:
0793 case DRV_TLV_PLOGI_3_ACC_TIMESTAMP:
0794 case DRV_TLV_PLOGI_4_ACC_TIMESTAMP:
0795 case DRV_TLV_PLOGI_5_ACC_TIMESTAMP:
0796 idx = (p_tlv->tlv_type - DRV_TLV_PLOGI_1_ACC_TIMESTAMP) / 2;
0797 p_time = &p_drv_buf->plogi_acc_tstamp[idx];
0798
0799 return qed_mfw_get_tlv_time_value(p_time, p_buf);
0800 case DRV_TLV_LOGOS_ISSUED:
0801 if (p_drv_buf->tx_plogos_set) {
0802 p_buf->p_val = &p_drv_buf->tx_plogos;
0803 return sizeof(p_drv_buf->tx_plogos);
0804 }
0805 break;
0806 case DRV_TLV_LOGO_ACCS_RECEIVED:
0807 if (p_drv_buf->plogo_acc_set) {
0808 p_buf->p_val = &p_drv_buf->plogo_acc;
0809 return sizeof(p_drv_buf->plogo_acc);
0810 }
0811 break;
0812 case DRV_TLV_LOGO_RJTS_RECEIVED:
0813 if (p_drv_buf->plogo_rjt_set) {
0814 p_buf->p_val = &p_drv_buf->plogo_rjt;
0815 return sizeof(p_drv_buf->plogo_rjt);
0816 }
0817 break;
0818 case DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID:
0819 case DRV_TLV_LOGO_2_RECEIVED_SOURCE_FC_ID:
0820 case DRV_TLV_LOGO_3_RECEIVED_SOURCE_FC_ID:
0821 case DRV_TLV_LOGO_4_RECEIVED_SOURCE_FC_ID:
0822 case DRV_TLV_LOGO_5_RECEIVED_SOURCE_FC_ID:
0823 idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_RECEIVED_SOURCE_FC_ID) /
0824 2;
0825
0826 if (p_drv_buf->plogo_src_fcid_set[idx]) {
0827 p_buf->p_val = &p_drv_buf->plogo_src_fcid[idx];
0828 return sizeof(p_drv_buf->plogo_src_fcid[idx]);
0829 }
0830 break;
0831 case DRV_TLV_LOGO_1_TIMESTAMP:
0832 case DRV_TLV_LOGO_2_TIMESTAMP:
0833 case DRV_TLV_LOGO_3_TIMESTAMP:
0834 case DRV_TLV_LOGO_4_TIMESTAMP:
0835 case DRV_TLV_LOGO_5_TIMESTAMP:
0836 idx = (p_tlv->tlv_type - DRV_TLV_LOGO_1_TIMESTAMP) / 2;
0837
0838 return qed_mfw_get_tlv_time_value(&p_drv_buf->plogo_tstamp[idx],
0839 p_buf);
0840 case DRV_TLV_LOGOS_RECEIVED:
0841 if (p_drv_buf->rx_logos_set) {
0842 p_buf->p_val = &p_drv_buf->rx_logos;
0843 return sizeof(p_drv_buf->rx_logos);
0844 }
0845 break;
0846 case DRV_TLV_ACCS_ISSUED:
0847 if (p_drv_buf->tx_accs_set) {
0848 p_buf->p_val = &p_drv_buf->tx_accs;
0849 return sizeof(p_drv_buf->tx_accs);
0850 }
0851 break;
0852 case DRV_TLV_PRLIS_ISSUED:
0853 if (p_drv_buf->tx_prlis_set) {
0854 p_buf->p_val = &p_drv_buf->tx_prlis;
0855 return sizeof(p_drv_buf->tx_prlis);
0856 }
0857 break;
0858 case DRV_TLV_ACCS_RECEIVED:
0859 if (p_drv_buf->rx_accs_set) {
0860 p_buf->p_val = &p_drv_buf->rx_accs;
0861 return sizeof(p_drv_buf->rx_accs);
0862 }
0863 break;
0864 case DRV_TLV_ABTS_SENT_COUNT:
0865 if (p_drv_buf->tx_abts_set) {
0866 p_buf->p_val = &p_drv_buf->tx_abts;
0867 return sizeof(p_drv_buf->tx_abts);
0868 }
0869 break;
0870 case DRV_TLV_ABTS_ACCS_RECEIVED:
0871 if (p_drv_buf->rx_abts_acc_set) {
0872 p_buf->p_val = &p_drv_buf->rx_abts_acc;
0873 return sizeof(p_drv_buf->rx_abts_acc);
0874 }
0875 break;
0876 case DRV_TLV_ABTS_RJTS_RECEIVED:
0877 if (p_drv_buf->rx_abts_rjt_set) {
0878 p_buf->p_val = &p_drv_buf->rx_abts_rjt;
0879 return sizeof(p_drv_buf->rx_abts_rjt);
0880 }
0881 break;
0882 case DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID:
0883 case DRV_TLV_ABTS_2_SENT_DESTINATION_FC_ID:
0884 case DRV_TLV_ABTS_3_SENT_DESTINATION_FC_ID:
0885 case DRV_TLV_ABTS_4_SENT_DESTINATION_FC_ID:
0886 case DRV_TLV_ABTS_5_SENT_DESTINATION_FC_ID:
0887 idx = (p_tlv->tlv_type -
0888 DRV_TLV_ABTS_1_SENT_DESTINATION_FC_ID) / 2;
0889
0890 if (p_drv_buf->abts_dst_fcid_set[idx]) {
0891 p_buf->p_val = &p_drv_buf->abts_dst_fcid[idx];
0892 return sizeof(p_drv_buf->abts_dst_fcid[idx]);
0893 }
0894 break;
0895 case DRV_TLV_ABTS_1_TIMESTAMP:
0896 case DRV_TLV_ABTS_2_TIMESTAMP:
0897 case DRV_TLV_ABTS_3_TIMESTAMP:
0898 case DRV_TLV_ABTS_4_TIMESTAMP:
0899 case DRV_TLV_ABTS_5_TIMESTAMP:
0900 idx = (p_tlv->tlv_type - DRV_TLV_ABTS_1_TIMESTAMP) / 2;
0901
0902 return qed_mfw_get_tlv_time_value(&p_drv_buf->abts_tstamp[idx],
0903 p_buf);
0904 case DRV_TLV_RSCNS_RECEIVED:
0905 if (p_drv_buf->rx_rscn_set) {
0906 p_buf->p_val = &p_drv_buf->rx_rscn;
0907 return sizeof(p_drv_buf->rx_rscn);
0908 }
0909 break;
0910 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1:
0911 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_2:
0912 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_3:
0913 case DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_4:
0914 idx = p_tlv->tlv_type - DRV_TLV_LAST_RSCN_RECEIVED_N_PORT_1;
0915
0916 if (p_drv_buf->rx_rscn_nport_set[idx]) {
0917 p_buf->p_val = &p_drv_buf->rx_rscn_nport[idx];
0918 return sizeof(p_drv_buf->rx_rscn_nport[idx]);
0919 }
0920 break;
0921 case DRV_TLV_LUN_RESETS_ISSUED:
0922 if (p_drv_buf->tx_lun_rst_set) {
0923 p_buf->p_val = &p_drv_buf->tx_lun_rst;
0924 return sizeof(p_drv_buf->tx_lun_rst);
0925 }
0926 break;
0927 case DRV_TLV_ABORT_TASK_SETS_ISSUED:
0928 if (p_drv_buf->abort_task_sets_set) {
0929 p_buf->p_val = &p_drv_buf->abort_task_sets;
0930 return sizeof(p_drv_buf->abort_task_sets);
0931 }
0932 break;
0933 case DRV_TLV_TPRLOS_SENT:
0934 if (p_drv_buf->tx_tprlos_set) {
0935 p_buf->p_val = &p_drv_buf->tx_tprlos;
0936 return sizeof(p_drv_buf->tx_tprlos);
0937 }
0938 break;
0939 case DRV_TLV_NOS_SENT_COUNT:
0940 if (p_drv_buf->tx_nos_set) {
0941 p_buf->p_val = &p_drv_buf->tx_nos;
0942 return sizeof(p_drv_buf->tx_nos);
0943 }
0944 break;
0945 case DRV_TLV_NOS_RECEIVED_COUNT:
0946 if (p_drv_buf->rx_nos_set) {
0947 p_buf->p_val = &p_drv_buf->rx_nos;
0948 return sizeof(p_drv_buf->rx_nos);
0949 }
0950 break;
0951 case DRV_TLV_OLS_COUNT:
0952 if (p_drv_buf->ols_set) {
0953 p_buf->p_val = &p_drv_buf->ols;
0954 return sizeof(p_drv_buf->ols);
0955 }
0956 break;
0957 case DRV_TLV_LR_COUNT:
0958 if (p_drv_buf->lr_set) {
0959 p_buf->p_val = &p_drv_buf->lr;
0960 return sizeof(p_drv_buf->lr);
0961 }
0962 break;
0963 case DRV_TLV_LRR_COUNT:
0964 if (p_drv_buf->lrr_set) {
0965 p_buf->p_val = &p_drv_buf->lrr;
0966 return sizeof(p_drv_buf->lrr);
0967 }
0968 break;
0969 case DRV_TLV_LIP_SENT_COUNT:
0970 if (p_drv_buf->tx_lip_set) {
0971 p_buf->p_val = &p_drv_buf->tx_lip;
0972 return sizeof(p_drv_buf->tx_lip);
0973 }
0974 break;
0975 case DRV_TLV_LIP_RECEIVED_COUNT:
0976 if (p_drv_buf->rx_lip_set) {
0977 p_buf->p_val = &p_drv_buf->rx_lip;
0978 return sizeof(p_drv_buf->rx_lip);
0979 }
0980 break;
0981 case DRV_TLV_EOFA_COUNT:
0982 if (p_drv_buf->eofa_set) {
0983 p_buf->p_val = &p_drv_buf->eofa;
0984 return sizeof(p_drv_buf->eofa);
0985 }
0986 break;
0987 case DRV_TLV_EOFNI_COUNT:
0988 if (p_drv_buf->eofni_set) {
0989 p_buf->p_val = &p_drv_buf->eofni;
0990 return sizeof(p_drv_buf->eofni);
0991 }
0992 break;
0993 case DRV_TLV_SCSI_STATUS_CHECK_CONDITION_COUNT:
0994 if (p_drv_buf->scsi_chks_set) {
0995 p_buf->p_val = &p_drv_buf->scsi_chks;
0996 return sizeof(p_drv_buf->scsi_chks);
0997 }
0998 break;
0999 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
1076 static int
1077 qed_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
1179 static 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
1244 int 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
1272
1273
1274
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
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
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
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
1324
1325
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
1333 drv_done:
1334 rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_TLV_DONE, 0, &resp,
1335 ¶m);
1336
1337 vfree(p_mfw_buf);
1338
1339 return rc;
1340 }