}
 }
 
+/**
+ * i40e_aq_debug_dump
+ * @hw: pointer to the hardware structure
+ * @cluster_id: specific cluster to dump
+ * @table_id: table id within cluster
+ * @start_index: index of line in the block to read
+ * @buff_size: dump buffer size
+ * @buff: dump buffer
+ * @ret_buff_size: actual buffer size returned
+ * @ret_next_table: next block to read
+ * @ret_next_index: next index to read
+ *
+ * Dump internal FW/HW data for debug purposes.
+ *
+ **/
+i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
+                              u8 table_id, u32 start_index, u16 buff_size,
+                              void *buff, u16 *ret_buff_size,
+                              u8 *ret_next_table, u32 *ret_next_index,
+                              struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_debug_dump_internals *cmd =
+               (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
+       struct i40e_aqc_debug_dump_internals *resp =
+               (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
+       i40e_status status;
+
+       if (buff_size == 0 || !buff)
+               return I40E_ERR_PARAM;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_debug_dump_internals);
+       /* Indirect Command */
+       desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
+       if (buff_size > I40E_AQ_LARGE_BUF)
+               desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
+
+       cmd->cluster_id = cluster_id;
+       cmd->table_id = table_id;
+       cmd->idx = cpu_to_le32(start_index);
+
+       desc.datalen = cpu_to_le16(buff_size);
+
+       status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+       if (!status) {
+               if (ret_buff_size)
+                       *ret_buff_size = le16_to_cpu(desc.datalen);
+               if (ret_next_table)
+                       *ret_next_table = resp->table_id;
+               if (ret_next_index)
+                       *ret_next_index = le32_to_cpu(resp->idx);
+       }
+
+       return status;
+}
+
 /**
  * i40e_read_bw_from_alt_ram
  * @hw: pointer to the hardware structure
 
                                         r_cfg->app[i].selector,
                                         r_cfg->app[i].protocolid);
                        }
+               } else if (strncmp(&cmd_buf[5], "debug fwdata", 12) == 0) {
+                       int cluster_id, table_id;
+                       int index, ret;
+                       u16 buff_len = 4096;
+                       u32 next_index;
+                       u8 next_table;
+                       u8 *buff;
+                       u16 rlen;
+
+                       cnt = sscanf(&cmd_buf[18], "%i %i %i",
+                                    &cluster_id, &table_id, &index);
+                       if (cnt != 3) {
+                               dev_info(&pf->pdev->dev,
+                                        "dump debug fwdata <cluster_id> <table_id> <index>\n");
+                               goto command_write_done;
+                       }
+
+                       dev_info(&pf->pdev->dev,
+                                "AQ debug dump fwdata params %x %x %x %x\n",
+                                cluster_id, table_id, index, buff_len);
+                       buff = kzalloc(buff_len, GFP_KERNEL);
+                       if (!buff)
+                               goto command_write_done;
+
+                       ret = i40e_aq_debug_dump(&pf->hw, cluster_id, table_id,
+                                                index, buff_len, buff, &rlen,
+                                                &next_table, &next_index,
+                                                NULL);
+                       if (ret) {
+                               dev_info(&pf->pdev->dev,
+                                        "debug dump fwdata AQ Failed %d 0x%x\n",
+                                        ret, pf->hw.aq.asq_last_status);
+                               kfree(buff);
+                               buff = NULL;
+                               goto command_write_done;
+                       }
+                       dev_info(&pf->pdev->dev,
+                                "AQ debug dump fwdata rlen=0x%x next_table=0x%x next_index=0x%x\n",
+                                rlen, next_table, next_index);
+                       print_hex_dump(KERN_INFO, "AQ buffer WB: ",
+                                      DUMP_PREFIX_OFFSET, 16, 1,
+                                      buff, rlen, true);
+                       kfree(buff);
+                       buff = NULL;
                } else {
                        dev_info(&pf->pdev->dev,
                                 "dump desc tx <vsi_seid> <ring_id> [<desc_n>], dump desc rx <vsi_seid> <ring_id> [<desc_n>],\n");
                dev_info(&pf->pdev->dev, "  dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n");
                dev_info(&pf->pdev->dev, "  dump desc aq\n");
                dev_info(&pf->pdev->dev, "  dump reset stats\n");
+               dev_info(&pf->pdev->dev, "  dump debug fwdata <cluster_id> <table_id> <index>\n");
                dev_info(&pf->pdev->dev, "  msg_enable [level]\n");
                dev_info(&pf->pdev->dev, "  read <reg>\n");
                dev_info(&pf->pdev->dev, "  write <reg> <value>\n");
 
                                u16 vsi_seid, u16 queue, bool is_add,
                                struct i40e_control_filter_stats *stats,
                                struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
+                              u8 table_id, u32 start_index, u16 buff_size,
+                              void *buff, u16 *ret_buff_size,
+                              u8 *ret_next_table, u32 *ret_next_index,
+                              struct i40e_asq_cmd_details *cmd_details);
 #endif /* _I40E_PROTOTYPE_H_ */