IWL_UCODE_TLV_FW_DBG_DEST       = 38,
        IWL_UCODE_TLV_FW_DBG_CONF       = 39,
        IWL_UCODE_TLV_FW_DBG_TRIGGER    = 40,
+       IWL_UCODE_TLV_CMD_VERSIONS      = 48,
        IWL_UCODE_TLV_FW_GSCAN_CAPA     = 50,
        IWL_UCODE_TLV_FW_MEM_SEG        = 51,
        IWL_UCODE_TLV_IML               = 52,
        struct iwl_fw_dbg_conf_hcmd hcmd;
 } __packed;
 
+#define IWL_FW_CMD_VER_UNKNOWN 99
+
+/**
+ * struct iwl_fw_cmd_version - firmware command version entry
+ * @cmd: command ID
+ * @group: group ID
+ * @cmd_ver: command version
+ * @notif_ver: notification version
+ */
+struct iwl_fw_cmd_version {
+       u8 cmd;
+       u8 group;
+       u8 cmd_ver;
+       u8 notif_ver;
+} __packed;
+
 #endif  /* __iwl_fw_file_h__ */
 
  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016        Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016        Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
        u32 error_log_size;
        unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)];
        unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)];
+
+       const struct iwl_fw_cmd_version *cmd_versions;
+       u32 n_cmd_versions;
 };
 
 static inline bool
 
                kfree(drv->fw.dbg.trigger_tlv[i]);
        kfree(drv->fw.dbg.mem_tlv);
        kfree(drv->fw.iml);
+       kfree(drv->fw.ucode_capa.cmd_versions);
 
        for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
                iwl_free_fw_img(drv, drv->fw.img + i);
                        if (iwlwifi_mod_params.enable_ini)
                                iwl_fw_dbg_copy_tlv(drv->trans, tlv, false);
                        break;
+               case IWL_UCODE_TLV_CMD_VERSIONS:
+                       if (tlv_len % sizeof(struct iwl_fw_cmd_version)) {
+                               IWL_ERR(drv,
+                                       "Invalid length for command versions: %u\n",
+                                       tlv_len);
+                               tlv_len /= sizeof(struct iwl_fw_cmd_version);
+                               tlv_len *= sizeof(struct iwl_fw_cmd_version);
+                       }
+                       if (WARN_ON(capa->cmd_versions))
+                               return -EINVAL;
+                       capa->cmd_versions = kmemdup(tlv_data, tlv_len,
+                                                    GFP_KERNEL);
+                       if (!capa->cmd_versions)
+                               return -ENOMEM;
+                       capa->n_cmd_versions =
+                               tlv_len / sizeof(struct iwl_fw_cmd_version);
+                       break;
                default:
                        IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
                        break;