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