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