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) 22 struct 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 30 static 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. */ 245 static int 246 qed_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 307 static int 308 qed_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 410 static int 411 qed_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 441 static int 442 qed_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 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 /* 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 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 } 1341