Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/887918/?format=api
{ "id": 887918, "url": "http://patchwork.ozlabs.org/api/patches/887918/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180319215644.31978-2-jeffrey.t.kirsher@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20180319215644.31978-2-jeffrey.t.kirsher@intel.com>", "list_archive_url": null, "date": "2018-03-19T21:56:31", "name": "[v3,02/15] ice: Add support for control queues", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "f7b653eab5e88274a29a9c28a9599eff49bf69f3", "submitter": { "id": 473, "url": "http://patchwork.ozlabs.org/api/people/473/?format=api", "name": "Kirsher, Jeffrey T", "email": "jeffrey.t.kirsher@intel.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180319215644.31978-2-jeffrey.t.kirsher@intel.com/mbox/", "series": [ { "id": 34702, "url": "http://patchwork.ozlabs.org/api/series/34702/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=34702", "date": "2018-03-19T21:56:30", "name": "[v3,01/15] ice: Add basic driver framework for Intel(R) E800 Series", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/34702/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/887918/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/887918/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.136; helo=silver.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=none (p=none dis=none) header.from=intel.com" ], "Received": [ "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 404qf31kNvz9s3M\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 20 Mar 2018 08:56:43 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id C9C3F26129;\n\tMon, 19 Mar 2018 21:56:41 +0000 (UTC)", "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id XvpKx1tK7s18; Mon, 19 Mar 2018 21:56:23 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id DCF7526423;\n\tMon, 19 Mar 2018 21:56:18 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id 37D2F1C2272\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Mar 2018 21:56:15 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 2958888E95\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Mar 2018 21:56:15 +0000 (UTC)", "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id 3rVfLExlmOd5 for <intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Mar 2018 21:56:08 +0000 (UTC)", "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id A1CB988ED6\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Mar 2018 21:56:08 +0000 (UTC)", "from orsmga008.jf.intel.com ([10.7.209.65])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Mar 2018 14:56:07 -0700", "from jtkirshe-nuc.jf.intel.com ([134.134.177.59])\n\tby orsmga008.jf.intel.com with ESMTP; 19 Mar 2018 14:56:07 -0700" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6", "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.48,332,1517904000\"; d=\"scan'208\";a=\"26667079\"", "From": "Jeff Kirsher <jeffrey.t.kirsher@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Mon, 19 Mar 2018 14:56:31 -0700", "Message-Id": "<20180319215644.31978-2-jeffrey.t.kirsher@intel.com>", "X-Mailer": "git-send-email 2.14.3", "In-Reply-To": "<20180319215644.31978-1-jeffrey.t.kirsher@intel.com>", "References": "<20180319215644.31978-1-jeffrey.t.kirsher@intel.com>", "Subject": "[Intel-wired-lan] [PATCH v3 02/15] ice: Add support for control\n\tqueues", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.24", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>\n\nA control queue is a hardware interface which is used by the driver\nto interact with other subsystems (like firmware, PHY, etc.). It is\nimplemented as a producer-consumer ring. More specifically, an\n\"admin queue\" is a type of control queue used to interact with the\nfirmware.\n\nThis patch introduces data structures and functions to initialize\nand teardown control/admin queues. Once the admin queue is initialized,\nthe driver uses it to get the firmware version.\n\nSigned-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>\n---\n drivers/net/ethernet/intel/ice/Makefile | 4 +-\n drivers/net/ethernet/intel/ice/ice.h | 1 +\n drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | 108 +++\n drivers/net/ethernet/intel/ice/ice_common.c | 144 ++++\n drivers/net/ethernet/intel/ice/ice_common.h | 39 +\n drivers/net/ethernet/intel/ice/ice_controlq.c | 979 ++++++++++++++++++++++++\n drivers/net/ethernet/intel/ice/ice_controlq.h | 97 +++\n drivers/net/ethernet/intel/ice/ice_hw_autogen.h | 46 ++\n drivers/net/ethernet/intel/ice/ice_main.c | 11 +-\n drivers/net/ethernet/intel/ice/ice_osdep.h | 86 +++\n drivers/net/ethernet/intel/ice/ice_status.h | 35 +\n drivers/net/ethernet/intel/ice/ice_type.h | 22 +\n 12 files changed, 1570 insertions(+), 2 deletions(-)\n create mode 100644 drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\n create mode 100644 drivers/net/ethernet/intel/ice/ice_common.c\n create mode 100644 drivers/net/ethernet/intel/ice/ice_common.h\n create mode 100644 drivers/net/ethernet/intel/ice/ice_controlq.c\n create mode 100644 drivers/net/ethernet/intel/ice/ice_controlq.h\n create mode 100644 drivers/net/ethernet/intel/ice/ice_hw_autogen.h\n create mode 100644 drivers/net/ethernet/intel/ice/ice_osdep.h\n create mode 100644 drivers/net/ethernet/intel/ice/ice_status.h", "diff": "diff --git a/drivers/net/ethernet/intel/ice/Makefile b/drivers/net/ethernet/intel/ice/Makefile\nindex 2a177ea21b74..eebf619e84a8 100644\n--- a/drivers/net/ethernet/intel/ice/Makefile\n+++ b/drivers/net/ethernet/intel/ice/Makefile\n@@ -24,4 +24,6 @@\n \n obj-$(CONFIG_ICE) += ice.o\n \n-ice-y := ice_main.o\n+ice-y := ice_main.o\t\\\n+\t ice_controlq.o\t\\\n+\t ice_common.o\ndiff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h\nindex d781027330cc..ea2fb63bb095 100644\n--- a/drivers/net/ethernet/intel/ice/ice.h\n+++ b/drivers/net/ethernet/intel/ice/ice.h\n@@ -26,6 +26,7 @@\n #include <linux/compiler.h>\n #include <linux/pci.h>\n #include <linux/aer.h>\n+#include <linux/delay.h>\n #include <linux/bitmap.h>\n #include \"ice_devids.h\"\n #include \"ice_type.h\"\ndiff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\nnew file mode 100644\nindex 000000000000..885fa3c6fec4\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\n@@ -0,0 +1,108 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/* Intel(R) Ethernet Connection E800 Series Linux Driver\n+ * Copyright (c) 2018, Intel Corporation.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * The full GNU General Public License is included in this distribution in\n+ * the file called \"COPYING\".\n+ */\n+\n+#ifndef _ICE_ADMINQ_CMD_H_\n+#define _ICE_ADMINQ_CMD_H_\n+\n+/* This header file defines the Admin Queue commands, error codes and\n+ * descriptor format. It is shared between Firmware and Software.\n+ */\n+\n+struct ice_aqc_generic {\n+\t__le32 param0;\n+\t__le32 param1;\n+\t__le32 addr_high;\n+\t__le32 addr_low;\n+};\n+\n+/* Get version (direct 0x0001) */\n+struct ice_aqc_get_ver {\n+\t__le32 rom_ver;\n+\t__le32 fw_build;\n+\tu8 fw_branch;\n+\tu8 fw_major;\n+\tu8 fw_minor;\n+\tu8 fw_patch;\n+\tu8 api_branch;\n+\tu8 api_major;\n+\tu8 api_minor;\n+\tu8 api_patch;\n+};\n+\n+/* Queue Shutdown (direct 0x0003) */\n+struct ice_aqc_q_shutdown {\n+#define ICE_AQC_DRIVER_UNLOADING\tBIT(0)\n+\t__le32 driver_unloading;\n+\tu8 reserved[12];\n+};\n+\n+/**\n+ * struct ice_aq_desc - Admin Queue (AQ) descriptor\n+ * @flags: ICE_AQ_FLAG_* flags\n+ * @opcode: AQ command opcode\n+ * @datalen: length in bytes of indirect/external data buffer\n+ * @retval: return value from firmware\n+ * @cookie_h: opaque data high-half\n+ * @cookie_l: opaque data low-half\n+ * @params: command-specific parameters\n+ *\n+ * Descriptor format for commands the driver posts on the Admin Transmit Queue\n+ * (ATQ). The firmware writes back onto the command descriptor and returns\n+ * the result of the command. Asynchronous events that are not an immediate\n+ * result of the command are written to the Admin Receive Queue (ARQ) using\n+ * the same descriptor format. Descriptors are in little-endian notation with\n+ * 32-bit words.\n+ */\n+struct ice_aq_desc {\n+\t__le16 flags;\n+\t__le16 opcode;\n+\t__le16 datalen;\n+\t__le16 retval;\n+\t__le32 cookie_high;\n+\t__le32 cookie_low;\n+\tunion {\n+\t\tu8 raw[16];\n+\t\tstruct ice_aqc_generic generic;\n+\t\tstruct ice_aqc_get_ver get_ver;\n+\t\tstruct ice_aqc_q_shutdown q_shutdown;\n+\t} params;\n+};\n+\n+/* FW defined boundary for a large buffer, 4k >= Large buffer > 512 bytes */\n+#define ICE_AQ_LG_BUF\t512\n+\n+#define ICE_AQ_FLAG_LB_S\t9\n+#define ICE_AQ_FLAG_BUF_S\t12\n+#define ICE_AQ_FLAG_SI_S\t13\n+\n+#define ICE_AQ_FLAG_LB\t\tBIT(ICE_AQ_FLAG_LB_S) /* 0x200 */\n+#define ICE_AQ_FLAG_BUF\t\tBIT(ICE_AQ_FLAG_BUF_S) /* 0x1000 */\n+#define ICE_AQ_FLAG_SI\t\tBIT(ICE_AQ_FLAG_SI_S) /* 0x2000 */\n+\n+/* error codes */\n+enum ice_aq_err {\n+\tICE_AQ_RC_OK\t\t= 0, /* success */\n+};\n+\n+/* Admin Queue command opcodes */\n+enum ice_adminq_opc {\n+\t/* AQ commands */\n+\tice_aqc_opc_get_ver\t\t\t\t= 0x0001,\n+\tice_aqc_opc_q_shutdown\t\t\t\t= 0x0003,\n+};\n+\n+#endif /* _ICE_ADMINQ_CMD_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c\nnew file mode 100644\nindex 000000000000..d980f0518744\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_common.c\n@@ -0,0 +1,144 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/* Intel(R) Ethernet Connection E800 Series Linux Driver\n+ * Copyright (c) 2018, Intel Corporation.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * The full GNU General Public License is included in this distribution in\n+ * the file called \"COPYING\".\n+ */\n+\n+#include \"ice_common.h\"\n+#include \"ice_adminq_cmd.h\"\n+\n+/**\n+ * ice_debug_cq\n+ * @hw: pointer to the hardware structure\n+ * @mask: debug mask\n+ * @desc: pointer to control queue descriptor\n+ * @buf: pointer to command buffer\n+ * @buf_len: max length of buf\n+ *\n+ * Dumps debug log about control command with descriptor contents.\n+ */\n+void ice_debug_cq(struct ice_hw *hw, u32 __maybe_unused mask, void *desc,\n+\t\t void *buf, u16 buf_len)\n+{\n+\tstruct ice_aq_desc *cq_desc = (struct ice_aq_desc *)desc;\n+\tu16 len;\n+\n+#ifndef CONFIG_DYNAMIC_DEBUG\n+\tif (!(mask & hw->debug_mask))\n+\t\treturn;\n+#endif\n+\n+\tif (!desc)\n+\t\treturn;\n+\n+\tlen = le16_to_cpu(cq_desc->datalen);\n+\n+\tice_debug(hw, mask,\n+\t\t \"CQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\\n\",\n+\t\t le16_to_cpu(cq_desc->opcode),\n+\t\t le16_to_cpu(cq_desc->flags),\n+\t\t le16_to_cpu(cq_desc->datalen), le16_to_cpu(cq_desc->retval));\n+\tice_debug(hw, mask, \"\\tcookie (h,l) 0x%08X 0x%08X\\n\",\n+\t\t le32_to_cpu(cq_desc->cookie_high),\n+\t\t le32_to_cpu(cq_desc->cookie_low));\n+\tice_debug(hw, mask, \"\\tparam (0,1) 0x%08X 0x%08X\\n\",\n+\t\t le32_to_cpu(cq_desc->params.generic.param0),\n+\t\t le32_to_cpu(cq_desc->params.generic.param1));\n+\tice_debug(hw, mask, \"\\taddr (h,l) 0x%08X 0x%08X\\n\",\n+\t\t le32_to_cpu(cq_desc->params.generic.addr_high),\n+\t\t le32_to_cpu(cq_desc->params.generic.addr_low));\n+\tif (buf && cq_desc->datalen != 0) {\n+\t\tice_debug(hw, mask, \"Buffer:\\n\");\n+\t\tif (buf_len < len)\n+\t\t\tlen = buf_len;\n+\n+\t\tice_debug_array(hw, mask, 16, 1, (u8 *)buf, len);\n+\t}\n+}\n+\n+/* FW Admin Queue command wrappers */\n+\n+/**\n+ * ice_aq_send_cmd - send FW Admin Queue command to FW Admin Queue\n+ * @hw: pointer to the hw struct\n+ * @desc: descriptor describing the command\n+ * @buf: buffer to use for indirect commands (NULL for direct commands)\n+ * @buf_size: size of buffer for indirect commands (0 for direct commands)\n+ * @cd: pointer to command details structure\n+ *\n+ * Helper function to send FW Admin Queue commands to the FW Admin Queue.\n+ */\n+enum ice_status\n+ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf,\n+\t\tu16 buf_size, struct ice_sq_cd *cd)\n+{\n+\treturn ice_sq_send_cmd(hw, &hw->adminq, desc, buf, buf_size, cd);\n+}\n+\n+/**\n+ * ice_aq_get_fw_ver\n+ * @hw: pointer to the hw struct\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Get the firmware version (0x0001) from the admin queue commands\n+ */\n+enum ice_status ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_get_ver *resp;\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\n+\tresp = &desc.params.get_ver;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_ver);\n+\n+\tstatus = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);\n+\n+\tif (!status) {\n+\t\thw->fw_branch = resp->fw_branch;\n+\t\thw->fw_maj_ver = resp->fw_major;\n+\t\thw->fw_min_ver = resp->fw_minor;\n+\t\thw->fw_patch = resp->fw_patch;\n+\t\thw->fw_build = le32_to_cpu(resp->fw_build);\n+\t\thw->api_branch = resp->api_branch;\n+\t\thw->api_maj_ver = resp->api_major;\n+\t\thw->api_min_ver = resp->api_minor;\n+\t\thw->api_patch = resp->api_patch;\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ice_aq_q_shutdown\n+ * @hw: pointer to the hw struct\n+ * @unloading: is the driver unloading itself\n+ *\n+ * Tell the Firmware that we're shutting down the AdminQ and whether\n+ * or not the driver is unloading as well (0x0003).\n+ */\n+enum ice_status ice_aq_q_shutdown(struct ice_hw *hw, bool unloading)\n+{\n+\tstruct ice_aqc_q_shutdown *cmd;\n+\tstruct ice_aq_desc desc;\n+\n+\tcmd = &desc.params.q_shutdown;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_q_shutdown);\n+\n+\tif (unloading)\n+\t\tcmd->driver_unloading = cpu_to_le32(ICE_AQC_DRIVER_UNLOADING);\n+\n+\treturn ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);\n+}\ndiff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h\nnew file mode 100644\nindex 000000000000..1e3caecc38c6\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_common.h\n@@ -0,0 +1,39 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/* Intel(R) Ethernet Connection E800 Series Linux Driver\n+ * Copyright (c) 2018, Intel Corporation.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * The full GNU General Public License is included in this distribution in\n+ * the file called \"COPYING\".\n+ */\n+\n+#ifndef _ICE_COMMON_H_\n+#define _ICE_COMMON_H_\n+\n+#include \"ice.h\"\n+#include \"ice_type.h\"\n+\n+void ice_debug_cq(struct ice_hw *hw, u32 mask, void *desc, void *buf,\n+\t\t u16 buf_len);\n+enum ice_status ice_init_all_ctrlq(struct ice_hw *hw);\n+void ice_shutdown_all_ctrlq(struct ice_hw *hw);\n+enum ice_status\n+ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,\n+\t\tstruct ice_aq_desc *desc, void *buf, u16 buf_size,\n+\t\tstruct ice_sq_cd *cd);\n+bool ice_check_sq_alive(struct ice_hw *hw, struct ice_ctl_q_info *cq);\n+enum ice_status ice_aq_q_shutdown(struct ice_hw *hw, bool unloading);\n+void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode);\n+enum ice_status\n+ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc,\n+\t\tvoid *buf, u16 buf_size, struct ice_sq_cd *cd);\n+enum ice_status ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd);\n+#endif /* _ICE_COMMON_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c\nnew file mode 100644\nindex 000000000000..b1143d66d4bd\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_controlq.c\n@@ -0,0 +1,979 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/* Intel(R) Ethernet Connection E800 Series Linux Driver\n+ * Copyright (c) 2018, Intel Corporation.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * The full GNU General Public License is included in this distribution in\n+ * the file called \"COPYING\".\n+ */\n+\n+#include \"ice_common.h\"\n+\n+/**\n+ * ice_adminq_init_regs - Initialize AdminQ registers\n+ * @hw: pointer to the hardware structure\n+ *\n+ * This assumes the alloc_sq and alloc_rq functions have already been called\n+ */\n+static void ice_adminq_init_regs(struct ice_hw *hw)\n+{\n+\tstruct ice_ctl_q_info *cq = &hw->adminq;\n+\n+\tcq->sq.head = PF_FW_ATQH;\n+\tcq->sq.tail = PF_FW_ATQT;\n+\tcq->sq.len = PF_FW_ATQLEN;\n+\tcq->sq.bah = PF_FW_ATQBAH;\n+\tcq->sq.bal = PF_FW_ATQBAL;\n+\tcq->sq.len_mask = PF_FW_ATQLEN_ATQLEN_M;\n+\tcq->sq.len_ena_mask = PF_FW_ATQLEN_ATQENABLE_M;\n+\tcq->sq.head_mask = PF_FW_ATQH_ATQH_M;\n+\n+\tcq->rq.head = PF_FW_ARQH;\n+\tcq->rq.tail = PF_FW_ARQT;\n+\tcq->rq.len = PF_FW_ARQLEN;\n+\tcq->rq.bah = PF_FW_ARQBAH;\n+\tcq->rq.bal = PF_FW_ARQBAL;\n+\tcq->rq.len_mask = PF_FW_ARQLEN_ARQLEN_M;\n+\tcq->rq.len_ena_mask = PF_FW_ARQLEN_ARQENABLE_M;\n+\tcq->rq.head_mask = PF_FW_ARQH_ARQH_M;\n+}\n+\n+/**\n+ * ice_check_sq_alive\n+ * @hw: pointer to the hw struct\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * Returns true if Queue is enabled else false.\n+ */\n+bool ice_check_sq_alive(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\t/* check both queue-length and queue-enable fields */\n+\tif (cq->sq.len && cq->sq.len_mask && cq->sq.len_ena_mask)\n+\t\treturn (rd32(hw, cq->sq.len) & (cq->sq.len_mask |\n+\t\t\t\t\t\tcq->sq.len_ena_mask)) ==\n+\t\t\t(cq->num_sq_entries | cq->sq.len_ena_mask);\n+\n+\treturn false;\n+}\n+\n+/**\n+ * ice_alloc_ctrlq_sq_ring - Allocate Control Transmit Queue (ATQ) rings\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ */\n+static enum ice_status\n+ice_alloc_ctrlq_sq_ring(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tsize_t size = cq->num_sq_entries * sizeof(struct ice_aq_desc);\n+\n+\tcq->sq.desc_buf.va = dmam_alloc_coherent(ice_hw_to_dev(hw), size,\n+\t\t\t\t\t\t &cq->sq.desc_buf.pa,\n+\t\t\t\t\t\t GFP_KERNEL | __GFP_ZERO);\n+\tif (!cq->sq.desc_buf.va)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\tcq->sq.desc_buf.size = size;\n+\n+\tcq->sq.cmd_buf = devm_kcalloc(ice_hw_to_dev(hw), cq->num_sq_entries,\n+\t\t\t\t sizeof(struct ice_sq_cd), GFP_KERNEL);\n+\tif (!cq->sq.cmd_buf) {\n+\t\tdmam_free_coherent(ice_hw_to_dev(hw), cq->sq.desc_buf.size,\n+\t\t\t\t cq->sq.desc_buf.va, cq->sq.desc_buf.pa);\n+\t\tcq->sq.desc_buf.va = NULL;\n+\t\tcq->sq.desc_buf.pa = 0;\n+\t\tcq->sq.desc_buf.size = 0;\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_alloc_ctrlq_rq_ring - Allocate Control Receive Queue (ARQ) rings\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ */\n+static enum ice_status\n+ice_alloc_ctrlq_rq_ring(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tsize_t size = cq->num_rq_entries * sizeof(struct ice_aq_desc);\n+\n+\tcq->rq.desc_buf.va = dmam_alloc_coherent(ice_hw_to_dev(hw), size,\n+\t\t\t\t\t\t &cq->rq.desc_buf.pa,\n+\t\t\t\t\t\t GFP_KERNEL | __GFP_ZERO);\n+\tif (!cq->rq.desc_buf.va)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\tcq->rq.desc_buf.size = size;\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_free_ctrlq_sq_ring - Free Control Transmit Queue (ATQ) rings\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * This assumes the posted send buffers have already been cleaned\n+ * and de-allocated\n+ */\n+static void ice_free_ctrlq_sq_ring(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tdmam_free_coherent(ice_hw_to_dev(hw), cq->sq.desc_buf.size,\n+\t\t\t cq->sq.desc_buf.va, cq->sq.desc_buf.pa);\n+\tcq->sq.desc_buf.va = NULL;\n+\tcq->sq.desc_buf.pa = 0;\n+\tcq->sq.desc_buf.size = 0;\n+}\n+\n+/**\n+ * ice_free_ctrlq_rq_ring - Free Control Receive Queue (ARQ) rings\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * This assumes the posted receive buffers have already been cleaned\n+ * and de-allocated\n+ */\n+static void ice_free_ctrlq_rq_ring(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tdmam_free_coherent(ice_hw_to_dev(hw), cq->rq.desc_buf.size,\n+\t\t\t cq->rq.desc_buf.va, cq->rq.desc_buf.pa);\n+\tcq->rq.desc_buf.va = NULL;\n+\tcq->rq.desc_buf.pa = 0;\n+\tcq->rq.desc_buf.size = 0;\n+}\n+\n+/**\n+ * ice_alloc_rq_bufs - Allocate pre-posted buffers for the ARQ\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ */\n+static enum ice_status\n+ice_alloc_rq_bufs(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tint i;\n+\n+\t/* We'll be allocating the buffer info memory first, then we can\n+\t * allocate the mapped buffers for the event processing\n+\t */\n+\tcq->rq.dma_head = devm_kcalloc(ice_hw_to_dev(hw), cq->num_rq_entries,\n+\t\t\t\t sizeof(cq->rq.desc_buf), GFP_KERNEL);\n+\tif (!cq->rq.dma_head)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\tcq->rq.r.rq_bi = (struct ice_dma_mem *)cq->rq.dma_head;\n+\n+\t/* allocate the mapped buffers */\n+\tfor (i = 0; i < cq->num_rq_entries; i++) {\n+\t\tstruct ice_aq_desc *desc;\n+\t\tstruct ice_dma_mem *bi;\n+\n+\t\tbi = &cq->rq.r.rq_bi[i];\n+\t\tbi->va = dmam_alloc_coherent(ice_hw_to_dev(hw),\n+\t\t\t\t\t cq->rq_buf_size, &bi->pa,\n+\t\t\t\t\t GFP_KERNEL | __GFP_ZERO);\n+\t\tif (!bi->va)\n+\t\t\tgoto unwind_alloc_rq_bufs;\n+\t\tbi->size = cq->rq_buf_size;\n+\n+\t\t/* now configure the descriptors for use */\n+\t\tdesc = ICE_CTL_Q_DESC(cq->rq, i);\n+\n+\t\tdesc->flags = cpu_to_le16(ICE_AQ_FLAG_BUF);\n+\t\tif (cq->rq_buf_size > ICE_AQ_LG_BUF)\n+\t\t\tdesc->flags |= cpu_to_le16(ICE_AQ_FLAG_LB);\n+\t\tdesc->opcode = 0;\n+\t\t/* This is in accordance with Admin queue design, there is no\n+\t\t * register for buffer size configuration\n+\t\t */\n+\t\tdesc->datalen = cpu_to_le16(bi->size);\n+\t\tdesc->retval = 0;\n+\t\tdesc->cookie_high = 0;\n+\t\tdesc->cookie_low = 0;\n+\t\tdesc->params.generic.addr_high =\n+\t\t\tcpu_to_le32(upper_32_bits(bi->pa));\n+\t\tdesc->params.generic.addr_low =\n+\t\t\tcpu_to_le32(lower_32_bits(bi->pa));\n+\t\tdesc->params.generic.param0 = 0;\n+\t\tdesc->params.generic.param1 = 0;\n+\t}\n+\treturn 0;\n+\n+unwind_alloc_rq_bufs:\n+\t/* don't try to free the one that failed... */\n+\ti--;\n+\tfor (; i >= 0; i--) {\n+\t\tdmam_free_coherent(ice_hw_to_dev(hw), cq->rq.r.rq_bi[i].size,\n+\t\t\t\t cq->rq.r.rq_bi[i].va, cq->rq.r.rq_bi[i].pa);\n+\t\tcq->rq.r.rq_bi[i].va = NULL;\n+\t\tcq->rq.r.rq_bi[i].pa = 0;\n+\t\tcq->rq.r.rq_bi[i].size = 0;\n+\t}\n+\tdevm_kfree(ice_hw_to_dev(hw), cq->rq.dma_head);\n+\n+\treturn ICE_ERR_NO_MEMORY;\n+}\n+\n+/**\n+ * ice_alloc_sq_bufs - Allocate empty buffer structs for the ATQ\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ */\n+static enum ice_status\n+ice_alloc_sq_bufs(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tint i;\n+\n+\t/* No mapped memory needed yet, just the buffer info structures */\n+\tcq->sq.dma_head = devm_kcalloc(ice_hw_to_dev(hw), cq->num_sq_entries,\n+\t\t\t\t sizeof(cq->sq.desc_buf), GFP_KERNEL);\n+\tif (!cq->sq.dma_head)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\tcq->sq.r.sq_bi = (struct ice_dma_mem *)cq->sq.dma_head;\n+\n+\t/* allocate the mapped buffers */\n+\tfor (i = 0; i < cq->num_sq_entries; i++) {\n+\t\tstruct ice_dma_mem *bi;\n+\n+\t\tbi = &cq->sq.r.sq_bi[i];\n+\t\tbi->va = dmam_alloc_coherent(ice_hw_to_dev(hw),\n+\t\t\t\t\t cq->sq_buf_size, &bi->pa,\n+\t\t\t\t\t GFP_KERNEL | __GFP_ZERO);\n+\t\tif (!bi->va)\n+\t\t\tgoto unwind_alloc_sq_bufs;\n+\t\tbi->size = cq->sq_buf_size;\n+\t}\n+\treturn 0;\n+\n+unwind_alloc_sq_bufs:\n+\t/* don't try to free the one that failed... */\n+\ti--;\n+\tfor (; i >= 0; i--) {\n+\t\tdmam_free_coherent(ice_hw_to_dev(hw), cq->sq.r.sq_bi[i].size,\n+\t\t\t\t cq->sq.r.sq_bi[i].va, cq->sq.r.sq_bi[i].pa);\n+\t\tcq->sq.r.sq_bi[i].va = NULL;\n+\t\tcq->sq.r.sq_bi[i].pa = 0;\n+\t\tcq->sq.r.sq_bi[i].size = 0;\n+\t}\n+\tdevm_kfree(ice_hw_to_dev(hw), cq->sq.dma_head);\n+\n+\treturn ICE_ERR_NO_MEMORY;\n+}\n+\n+/**\n+ * ice_free_rq_bufs - Free ARQ buffer info elements\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ */\n+static void ice_free_rq_bufs(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tint i;\n+\n+\t/* free descriptors */\n+\tfor (i = 0; i < cq->num_rq_entries; i++) {\n+\t\tdmam_free_coherent(ice_hw_to_dev(hw), cq->rq.r.rq_bi[i].size,\n+\t\t\t\t cq->rq.r.rq_bi[i].va, cq->rq.r.rq_bi[i].pa);\n+\t\tcq->rq.r.rq_bi[i].va = NULL;\n+\t\tcq->rq.r.rq_bi[i].pa = 0;\n+\t\tcq->rq.r.rq_bi[i].size = 0;\n+\t}\n+\n+\t/* free the dma header */\n+\tdevm_kfree(ice_hw_to_dev(hw), cq->rq.dma_head);\n+}\n+\n+/**\n+ * ice_free_sq_bufs - Free ATQ buffer info elements\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ */\n+static void ice_free_sq_bufs(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tint i;\n+\n+\t/* only unmap if the address is non-NULL */\n+\tfor (i = 0; i < cq->num_sq_entries; i++)\n+\t\tif (cq->sq.r.sq_bi[i].pa) {\n+\t\t\tdmam_free_coherent(ice_hw_to_dev(hw),\n+\t\t\t\t\t cq->sq.r.sq_bi[i].size,\n+\t\t\t\t\t cq->sq.r.sq_bi[i].va,\n+\t\t\t\t\t cq->sq.r.sq_bi[i].pa);\n+\t\t\tcq->sq.r.sq_bi[i].va = NULL;\n+\t\t\tcq->sq.r.sq_bi[i].pa = 0;\n+\t\t\tcq->sq.r.sq_bi[i].size = 0;\n+\t\t}\n+\n+\t/* free the buffer info list */\n+\tdevm_kfree(ice_hw_to_dev(hw), cq->sq.cmd_buf);\n+\n+\t/* free the dma header */\n+\tdevm_kfree(ice_hw_to_dev(hw), cq->sq.dma_head);\n+}\n+\n+/**\n+ * ice_cfg_sq_regs - configure Control ATQ registers\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * Configure base address and length registers for the transmit queue\n+ */\n+static enum ice_status\n+ice_cfg_sq_regs(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tu32 reg = 0;\n+\n+\t/* Clear Head and Tail */\n+\twr32(hw, cq->sq.head, 0);\n+\twr32(hw, cq->sq.tail, 0);\n+\n+\t/* set starting point */\n+\twr32(hw, cq->sq.len, (cq->num_sq_entries | cq->sq.len_ena_mask));\n+\twr32(hw, cq->sq.bal, lower_32_bits(cq->sq.desc_buf.pa));\n+\twr32(hw, cq->sq.bah, upper_32_bits(cq->sq.desc_buf.pa));\n+\n+\t/* Check one register to verify that config was applied */\n+\treg = rd32(hw, cq->sq.bal);\n+\tif (reg != lower_32_bits(cq->sq.desc_buf.pa))\n+\t\treturn ICE_ERR_AQ_ERROR;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_cfg_rq_regs - configure Control ARQ register\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * Configure base address and length registers for the receive (event q)\n+ */\n+static enum ice_status\n+ice_cfg_rq_regs(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tu32 reg = 0;\n+\n+\t/* Clear Head and Tail */\n+\twr32(hw, cq->rq.head, 0);\n+\twr32(hw, cq->rq.tail, 0);\n+\n+\t/* set starting point */\n+\twr32(hw, cq->rq.len, (cq->num_rq_entries | cq->rq.len_ena_mask));\n+\twr32(hw, cq->rq.bal, lower_32_bits(cq->rq.desc_buf.pa));\n+\twr32(hw, cq->rq.bah, upper_32_bits(cq->rq.desc_buf.pa));\n+\n+\t/* Update tail in the HW to post pre-allocated buffers */\n+\twr32(hw, cq->rq.tail, (u32)(cq->num_rq_entries - 1));\n+\n+\t/* Check one register to verify that config was applied */\n+\treg = rd32(hw, cq->rq.bal);\n+\tif (reg != lower_32_bits(cq->rq.desc_buf.pa))\n+\t\treturn ICE_ERR_AQ_ERROR;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_init_sq - main initialization routine for Control ATQ\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * This is the main initialization routine for the Control Send Queue\n+ * Prior to calling this function, drivers *MUST* set the following fields\n+ * in the cq->structure:\n+ * - cq->num_sq_entries\n+ * - cq->sq_buf_size\n+ *\n+ * Do *NOT* hold the lock when calling this as the memory allocation routines\n+ * called are not going to be atomic context safe\n+ */\n+static enum ice_status ice_init_sq(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tenum ice_status ret_code;\n+\n+\tif (cq->sq.count > 0) {\n+\t\t/* queue already initialized */\n+\t\tret_code = ICE_ERR_NOT_READY;\n+\t\tgoto init_ctrlq_exit;\n+\t}\n+\n+\t/* verify input for valid configuration */\n+\tif (!cq->num_sq_entries || !cq->sq_buf_size) {\n+\t\tret_code = ICE_ERR_CFG;\n+\t\tgoto init_ctrlq_exit;\n+\t}\n+\n+\tcq->sq.next_to_use = 0;\n+\tcq->sq.next_to_clean = 0;\n+\n+\t/* allocate the ring memory */\n+\tret_code = ice_alloc_ctrlq_sq_ring(hw, cq);\n+\tif (ret_code)\n+\t\tgoto init_ctrlq_exit;\n+\n+\t/* allocate buffers in the rings */\n+\tret_code = ice_alloc_sq_bufs(hw, cq);\n+\tif (ret_code)\n+\t\tgoto init_ctrlq_free_rings;\n+\n+\t/* initialize base registers */\n+\tret_code = ice_cfg_sq_regs(hw, cq);\n+\tif (ret_code)\n+\t\tgoto init_ctrlq_free_rings;\n+\n+\t/* success! */\n+\tcq->sq.count = cq->num_sq_entries;\n+\tgoto init_ctrlq_exit;\n+\n+init_ctrlq_free_rings:\n+\tice_free_ctrlq_sq_ring(hw, cq);\n+\n+init_ctrlq_exit:\n+\treturn ret_code;\n+}\n+\n+/**\n+ * ice_init_rq - initialize ARQ\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * The main initialization routine for the Admin Receive (Event) Queue.\n+ * Prior to calling this function, drivers *MUST* set the following fields\n+ * in the cq->structure:\n+ * - cq->num_rq_entries\n+ * - cq->rq_buf_size\n+ *\n+ * Do *NOT* hold the lock when calling this as the memory allocation routines\n+ * called are not going to be atomic context safe\n+ */\n+static enum ice_status ice_init_rq(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tenum ice_status ret_code;\n+\n+\tif (cq->rq.count > 0) {\n+\t\t/* queue already initialized */\n+\t\tret_code = ICE_ERR_NOT_READY;\n+\t\tgoto init_ctrlq_exit;\n+\t}\n+\n+\t/* verify input for valid configuration */\n+\tif (!cq->num_rq_entries || !cq->rq_buf_size) {\n+\t\tret_code = ICE_ERR_CFG;\n+\t\tgoto init_ctrlq_exit;\n+\t}\n+\n+\tcq->rq.next_to_use = 0;\n+\tcq->rq.next_to_clean = 0;\n+\n+\t/* allocate the ring memory */\n+\tret_code = ice_alloc_ctrlq_rq_ring(hw, cq);\n+\tif (ret_code)\n+\t\tgoto init_ctrlq_exit;\n+\n+\t/* allocate buffers in the rings */\n+\tret_code = ice_alloc_rq_bufs(hw, cq);\n+\tif (ret_code)\n+\t\tgoto init_ctrlq_free_rings;\n+\n+\t/* initialize base registers */\n+\tret_code = ice_cfg_rq_regs(hw, cq);\n+\tif (ret_code)\n+\t\tgoto init_ctrlq_free_rings;\n+\n+\t/* success! */\n+\tcq->rq.count = cq->num_rq_entries;\n+\tgoto init_ctrlq_exit;\n+\n+init_ctrlq_free_rings:\n+\tice_free_ctrlq_rq_ring(hw, cq);\n+\n+init_ctrlq_exit:\n+\treturn ret_code;\n+}\n+\n+/**\n+ * ice_shutdown_sq - shutdown the Control ATQ\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * The main shutdown routine for the Control Transmit Queue\n+ */\n+static enum ice_status\n+ice_shutdown_sq(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tenum ice_status ret_code = 0;\n+\n+\tmutex_lock(&cq->sq_lock);\n+\n+\tif (!cq->sq.count) {\n+\t\tret_code = ICE_ERR_NOT_READY;\n+\t\tgoto shutdown_sq_out;\n+\t}\n+\n+\t/* Stop firmware AdminQ processing */\n+\twr32(hw, cq->sq.head, 0);\n+\twr32(hw, cq->sq.tail, 0);\n+\twr32(hw, cq->sq.len, 0);\n+\twr32(hw, cq->sq.bal, 0);\n+\twr32(hw, cq->sq.bah, 0);\n+\n+\tcq->sq.count = 0;\t/* to indicate uninitialized queue */\n+\n+\t/* free ring buffers and the ring itself */\n+\tice_free_sq_bufs(hw, cq);\n+\tice_free_ctrlq_sq_ring(hw, cq);\n+\n+shutdown_sq_out:\n+\tmutex_unlock(&cq->sq_lock);\n+\treturn ret_code;\n+}\n+\n+/**\n+ * ice_aq_ver_check - Check the reported AQ API version.\n+ * @fw_branch: The \"branch\" of FW, typically describes the device type\n+ * @fw_major: The major version of the FW API\n+ * @fw_minor: The minor version increment of the FW API\n+ *\n+ * Checks if the driver should load on a given AQ API version.\n+ *\n+ * Return: 'true' iff the driver should attempt to load. 'false' otherwise.\n+ */\n+static bool ice_aq_ver_check(u8 fw_branch, u8 fw_major, u8 fw_minor)\n+{\n+\tif (fw_branch != EXP_FW_API_VER_BRANCH)\n+\t\treturn false;\n+\tif (fw_major != EXP_FW_API_VER_MAJOR)\n+\t\treturn false;\n+\tif (fw_minor != EXP_FW_API_VER_MINOR)\n+\t\treturn false;\n+\treturn true;\n+}\n+\n+/**\n+ * ice_shutdown_rq - shutdown Control ARQ\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * The main shutdown routine for the Control Receive Queue\n+ */\n+static enum ice_status\n+ice_shutdown_rq(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tenum ice_status ret_code = 0;\n+\n+\tmutex_lock(&cq->rq_lock);\n+\n+\tif (!cq->rq.count) {\n+\t\tret_code = ICE_ERR_NOT_READY;\n+\t\tgoto shutdown_rq_out;\n+\t}\n+\n+\t/* Stop Control Queue processing */\n+\twr32(hw, cq->rq.head, 0);\n+\twr32(hw, cq->rq.tail, 0);\n+\twr32(hw, cq->rq.len, 0);\n+\twr32(hw, cq->rq.bal, 0);\n+\twr32(hw, cq->rq.bah, 0);\n+\n+\t/* set rq.count to 0 to indicate uninitialized queue */\n+\tcq->rq.count = 0;\n+\n+\t/* free ring buffers and the ring itself */\n+\tice_free_rq_bufs(hw, cq);\n+\tice_free_ctrlq_rq_ring(hw, cq);\n+\n+shutdown_rq_out:\n+\tmutex_unlock(&cq->rq_lock);\n+\treturn ret_code;\n+}\n+\n+/**\n+ * ice_init_check_adminq - Check version for Admin Queue to know if its alive\n+ * @hw: pointer to the hardware structure\n+ */\n+static enum ice_status ice_init_check_adminq(struct ice_hw *hw)\n+{\n+\tstruct ice_ctl_q_info *cq = &hw->adminq;\n+\tenum ice_status status;\n+\n+\tstatus = ice_aq_get_fw_ver(hw, NULL);\n+\tif (status)\n+\t\tgoto init_ctrlq_free_rq;\n+\n+\tif (!ice_aq_ver_check(hw->api_branch, hw->api_maj_ver,\n+\t\t\t hw->api_min_ver)) {\n+\t\tstatus = ICE_ERR_FW_API_VER;\n+\t\tgoto init_ctrlq_free_rq;\n+\t}\n+\n+\treturn 0;\n+\n+init_ctrlq_free_rq:\n+\tice_shutdown_rq(hw, cq);\n+\tice_shutdown_sq(hw, cq);\n+\tmutex_destroy(&cq->sq_lock);\n+\tmutex_destroy(&cq->rq_lock);\n+\treturn status;\n+}\n+\n+/**\n+ * ice_init_ctrlq - main initialization routine for any control Queue\n+ * @hw: pointer to the hardware structure\n+ * @q_type: specific Control queue type\n+ *\n+ * Prior to calling this function, drivers *MUST* set the following fields\n+ * in the cq->structure:\n+ * - cq->num_sq_entries\n+ * - cq->num_rq_entries\n+ * - cq->rq_buf_size\n+ * - cq->sq_buf_size\n+ *\n+ */\n+static enum ice_status ice_init_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)\n+{\n+\tstruct ice_ctl_q_info *cq;\n+\tenum ice_status ret_code;\n+\n+\tswitch (q_type) {\n+\tcase ICE_CTL_Q_ADMIN:\n+\t\tice_adminq_init_regs(hw);\n+\t\tcq = &hw->adminq;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn ICE_ERR_PARAM;\n+\t}\n+\tcq->qtype = q_type;\n+\n+\t/* verify input for valid configuration */\n+\tif (!cq->num_rq_entries || !cq->num_sq_entries ||\n+\t !cq->rq_buf_size || !cq->sq_buf_size) {\n+\t\treturn ICE_ERR_CFG;\n+\t}\n+\tmutex_init(&cq->sq_lock);\n+\tmutex_init(&cq->rq_lock);\n+\n+\t/* setup SQ command write back timeout */\n+\tcq->sq_cmd_timeout = ICE_CTL_Q_SQ_CMD_TIMEOUT;\n+\n+\t/* allocate the ATQ */\n+\tret_code = ice_init_sq(hw, cq);\n+\tif (ret_code)\n+\t\tgoto init_ctrlq_destroy_locks;\n+\n+\t/* allocate the ARQ */\n+\tret_code = ice_init_rq(hw, cq);\n+\tif (ret_code)\n+\t\tgoto init_ctrlq_free_sq;\n+\n+\t/* success! */\n+\treturn 0;\n+\n+init_ctrlq_free_sq:\n+\tice_shutdown_sq(hw, cq);\n+init_ctrlq_destroy_locks:\n+\tmutex_destroy(&cq->sq_lock);\n+\tmutex_destroy(&cq->rq_lock);\n+\treturn ret_code;\n+}\n+\n+/**\n+ * ice_init_all_ctrlq - main initialization routine for all control queues\n+ * @hw: pointer to the hardware structure\n+ *\n+ * Prior to calling this function, drivers *MUST* set the following fields\n+ * in the cq->structure for all control queues:\n+ * - cq->num_sq_entries\n+ * - cq->num_rq_entries\n+ * - cq->rq_buf_size\n+ * - cq->sq_buf_size\n+ */\n+enum ice_status ice_init_all_ctrlq(struct ice_hw *hw)\n+{\n+\tenum ice_status ret_code;\n+\n+\t/* Init FW admin queue */\n+\tret_code = ice_init_ctrlq(hw, ICE_CTL_Q_ADMIN);\n+\tif (ret_code)\n+\t\treturn ret_code;\n+\n+\treturn ice_init_check_adminq(hw);\n+}\n+\n+/**\n+ * ice_shutdown_ctrlq - shutdown routine for any control queue\n+ * @hw: pointer to the hardware structure\n+ * @q_type: specific Control queue type\n+ */\n+static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)\n+{\n+\tstruct ice_ctl_q_info *cq;\n+\n+\tswitch (q_type) {\n+\tcase ICE_CTL_Q_ADMIN:\n+\t\tcq = &hw->adminq;\n+\t\tif (ice_check_sq_alive(hw, cq))\n+\t\t\tice_aq_q_shutdown(hw, true);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn;\n+\t}\n+\n+\tice_shutdown_sq(hw, cq);\n+\tice_shutdown_rq(hw, cq);\n+\tmutex_destroy(&cq->sq_lock);\n+\tmutex_destroy(&cq->rq_lock);\n+}\n+\n+/**\n+ * ice_shutdown_all_ctrlq - shutdown routine for all control queues\n+ * @hw: pointer to the hardware structure\n+ */\n+void ice_shutdown_all_ctrlq(struct ice_hw *hw)\n+{\n+\t/* Shutdown FW admin queue */\n+\tice_shutdown_ctrlq(hw, ICE_CTL_Q_ADMIN);\n+}\n+\n+/**\n+ * ice_clean_sq - cleans Admin send queue (ATQ)\n+ * @hw: pointer to the hardware structure\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * returns the number of free desc\n+ */\n+static u16 ice_clean_sq(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\tstruct ice_ctl_q_ring *sq = &cq->sq;\n+\tu16 ntc = sq->next_to_clean;\n+\tstruct ice_sq_cd *details;\n+\tstruct ice_aq_desc *desc;\n+\n+\tdesc = ICE_CTL_Q_DESC(*sq, ntc);\n+\tdetails = ICE_CTL_Q_DETAILS(*sq, ntc);\n+\n+\twhile (rd32(hw, cq->sq.head) != ntc) {\n+\t\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t\t \"ntc %d head %d.\\n\", ntc, rd32(hw, cq->sq.head));\n+\t\tmemset(desc, 0, sizeof(*desc));\n+\t\tmemset(details, 0, sizeof(*details));\n+\t\tntc++;\n+\t\tif (ntc == sq->count)\n+\t\t\tntc = 0;\n+\t\tdesc = ICE_CTL_Q_DESC(*sq, ntc);\n+\t\tdetails = ICE_CTL_Q_DETAILS(*sq, ntc);\n+\t}\n+\n+\tsq->next_to_clean = ntc;\n+\n+\treturn ICE_CTL_Q_DESC_UNUSED(sq);\n+}\n+\n+/**\n+ * ice_sq_done - check if FW has processed the Admin Send Queue (ATQ)\n+ * @hw: pointer to the hw struct\n+ * @cq: pointer to the specific Control queue\n+ *\n+ * Returns true if the firmware has processed all descriptors on the\n+ * admin send queue. Returns false if there are still requests pending.\n+ */\n+static bool ice_sq_done(struct ice_hw *hw, struct ice_ctl_q_info *cq)\n+{\n+\t/* AQ designers suggest use of head for better\n+\t * timing reliability than DD bit\n+\t */\n+\treturn rd32(hw, cq->sq.head) == cq->sq.next_to_use;\n+}\n+\n+/**\n+ * ice_sq_send_cmd - send command to Control Queue (ATQ)\n+ * @hw: pointer to the hw struct\n+ * @cq: pointer to the specific Control queue\n+ * @desc: prefilled descriptor describing the command (non DMA mem)\n+ * @buf: buffer to use for indirect commands (or NULL for direct commands)\n+ * @buf_size: size of buffer for indirect commands (or 0 for direct commands)\n+ * @cd: pointer to command details structure\n+ *\n+ * This is the main send command routine for the ATQ. It runs the q,\n+ * cleans the queue, etc.\n+ */\n+enum ice_status\n+ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,\n+\t\tstruct ice_aq_desc *desc, void *buf, u16 buf_size,\n+\t\tstruct ice_sq_cd *cd)\n+{\n+\tstruct ice_dma_mem *dma_buf = NULL;\n+\tstruct ice_aq_desc *desc_on_ring;\n+\tbool cmd_completed = false;\n+\tenum ice_status status = 0;\n+\tstruct ice_sq_cd *details;\n+\tu32 total_delay = 0;\n+\tu16 retval = 0;\n+\tu32 val = 0;\n+\n+\tmutex_lock(&cq->sq_lock);\n+\n+\tcq->sq_last_status = ICE_AQ_RC_OK;\n+\n+\tif (!cq->sq.count) {\n+\t\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t\t \"Control Send queue not initialized.\\n\");\n+\t\tstatus = ICE_ERR_AQ_EMPTY;\n+\t\tgoto sq_send_command_error;\n+\t}\n+\n+\tif ((buf && !buf_size) || (!buf && buf_size)) {\n+\t\tstatus = ICE_ERR_PARAM;\n+\t\tgoto sq_send_command_error;\n+\t}\n+\n+\tif (buf) {\n+\t\tif (buf_size > cq->sq_buf_size) {\n+\t\t\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t\t\t \"Invalid buffer size for Control Send queue: %d.\\n\",\n+\t\t\t\t buf_size);\n+\t\t\tstatus = ICE_ERR_INVAL_SIZE;\n+\t\t\tgoto sq_send_command_error;\n+\t\t}\n+\n+\t\tdesc->flags |= cpu_to_le16(ICE_AQ_FLAG_BUF);\n+\t\tif (buf_size > ICE_AQ_LG_BUF)\n+\t\t\tdesc->flags |= cpu_to_le16(ICE_AQ_FLAG_LB);\n+\t}\n+\n+\tval = rd32(hw, cq->sq.head);\n+\tif (val >= cq->num_sq_entries) {\n+\t\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t\t \"head overrun at %d in the Control Send Queue ring\\n\",\n+\t\t\t val);\n+\t\tstatus = ICE_ERR_AQ_EMPTY;\n+\t\tgoto sq_send_command_error;\n+\t}\n+\n+\tdetails = ICE_CTL_Q_DETAILS(cq->sq, cq->sq.next_to_use);\n+\tif (cd)\n+\t\tmemcpy(details, cd, sizeof(*details));\n+\telse\n+\t\tmemset(details, 0, sizeof(*details));\n+\n+\t/* Call clean and check queue available function to reclaim the\n+\t * descriptors that were processed by FW/MBX; the function returns the\n+\t * number of desc available. The clean function called here could be\n+\t * called in a separate thread in case of asynchronous completions.\n+\t */\n+\tif (ice_clean_sq(hw, cq) == 0) {\n+\t\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t\t \"Error: Control Send Queue is full.\\n\");\n+\t\tstatus = ICE_ERR_AQ_FULL;\n+\t\tgoto sq_send_command_error;\n+\t}\n+\n+\t/* initialize the temp desc pointer with the right desc */\n+\tdesc_on_ring = ICE_CTL_Q_DESC(cq->sq, cq->sq.next_to_use);\n+\n+\t/* if the desc is available copy the temp desc to the right place */\n+\tmemcpy(desc_on_ring, desc, sizeof(*desc_on_ring));\n+\n+\t/* if buf is not NULL assume indirect command */\n+\tif (buf) {\n+\t\tdma_buf = &cq->sq.r.sq_bi[cq->sq.next_to_use];\n+\t\t/* copy the user buf into the respective DMA buf */\n+\t\tmemcpy(dma_buf->va, buf, buf_size);\n+\t\tdesc_on_ring->datalen = cpu_to_le16(buf_size);\n+\n+\t\t/* Update the address values in the desc with the pa value\n+\t\t * for respective buffer\n+\t\t */\n+\t\tdesc_on_ring->params.generic.addr_high =\n+\t\t\tcpu_to_le32(upper_32_bits(dma_buf->pa));\n+\t\tdesc_on_ring->params.generic.addr_low =\n+\t\t\tcpu_to_le32(lower_32_bits(dma_buf->pa));\n+\t}\n+\n+\t/* Debug desc and buffer */\n+\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t \"ATQ: Control Send queue desc and buffer:\\n\");\n+\n+\tice_debug_cq(hw, ICE_DBG_AQ_CMD, (void *)desc_on_ring, buf, buf_size);\n+\n+\t(cq->sq.next_to_use)++;\n+\tif (cq->sq.next_to_use == cq->sq.count)\n+\t\tcq->sq.next_to_use = 0;\n+\twr32(hw, cq->sq.tail, cq->sq.next_to_use);\n+\n+\tdo {\n+\t\tif (ice_sq_done(hw, cq))\n+\t\t\tbreak;\n+\n+\t\tmdelay(1);\n+\t\ttotal_delay++;\n+\t} while (total_delay < cq->sq_cmd_timeout);\n+\n+\t/* if ready, copy the desc back to temp */\n+\tif (ice_sq_done(hw, cq)) {\n+\t\tmemcpy(desc, desc_on_ring, sizeof(*desc));\n+\t\tif (buf) {\n+\t\t\t/* get returned length to copy */\n+\t\t\tu16 copy_size = le16_to_cpu(desc->datalen);\n+\n+\t\t\tif (copy_size > buf_size) {\n+\t\t\t\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t\t\t\t \"Return len %d > than buf len %d\\n\",\n+\t\t\t\t\t copy_size, buf_size);\n+\t\t\t\tstatus = ICE_ERR_AQ_ERROR;\n+\t\t\t} else {\n+\t\t\t\tmemcpy(buf, dma_buf->va, copy_size);\n+\t\t\t}\n+\t\t}\n+\t\tretval = le16_to_cpu(desc->retval);\n+\t\tif (retval) {\n+\t\t\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t\t\t \"Control Send Queue command completed with error 0x%x\\n\",\n+\t\t\t\t retval);\n+\n+\t\t\t/* strip off FW internal code */\n+\t\t\tretval &= 0xff;\n+\t\t}\n+\t\tcmd_completed = true;\n+\t\tif (!status && retval != ICE_AQ_RC_OK)\n+\t\t\tstatus = ICE_ERR_AQ_ERROR;\n+\t\tcq->sq_last_status = (enum ice_aq_err)retval;\n+\t}\n+\n+\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t \"ATQ: desc and buffer writeback:\\n\");\n+\n+\tice_debug_cq(hw, ICE_DBG_AQ_CMD, (void *)desc, buf, buf_size);\n+\n+\t/* save writeback AQ if requested */\n+\tif (details->wb_desc)\n+\t\tmemcpy(details->wb_desc, desc_on_ring,\n+\t\t sizeof(*details->wb_desc));\n+\n+\t/* update the error if time out occurred */\n+\tif (!cmd_completed) {\n+\t\tice_debug(hw, ICE_DBG_AQ_MSG,\n+\t\t\t \"Control Send Queue Writeback timeout.\\n\");\n+\t\tstatus = ICE_ERR_AQ_TIMEOUT;\n+\t}\n+\n+sq_send_command_error:\n+\tmutex_unlock(&cq->sq_lock);\n+\treturn status;\n+}\n+\n+/**\n+ * ice_fill_dflt_direct_cmd_desc - AQ descriptor helper function\n+ * @desc: pointer to the temp descriptor (non DMA mem)\n+ * @opcode: the opcode can be used to decide which flags to turn off or on\n+ *\n+ * Fill the desc with default values\n+ */\n+void ice_fill_dflt_direct_cmd_desc(struct ice_aq_desc *desc, u16 opcode)\n+{\n+\t/* zero out the desc */\n+\tmemset(desc, 0, sizeof(*desc));\n+\tdesc->opcode = cpu_to_le16(opcode);\n+\tdesc->flags = cpu_to_le16(ICE_AQ_FLAG_SI);\n+}\ndiff --git a/drivers/net/ethernet/intel/ice/ice_controlq.h b/drivers/net/ethernet/intel/ice/ice_controlq.h\nnew file mode 100644\nindex 000000000000..143578d02aec\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_controlq.h\n@@ -0,0 +1,97 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/* Intel(R) Ethernet Connection E800 Series Linux Driver\n+ * Copyright (c) 2018, Intel Corporation.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * The full GNU General Public License is included in this distribution in\n+ * the file called \"COPYING\".\n+ */\n+\n+#ifndef _ICE_CONTROLQ_H_\n+#define _ICE_CONTROLQ_H_\n+\n+#include \"ice_adminq_cmd.h\"\n+\n+#define ICE_CTL_Q_DESC(R, i) \\\n+\t(&(((struct ice_aq_desc *)((R).desc_buf.va))[i]))\n+\n+#define ICE_CTL_Q_DESC_UNUSED(R) \\\n+\t(u16)((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \\\n+\t (R)->next_to_clean - (R)->next_to_use - 1)\n+\n+/* Defines that help manage the driver vs FW API checks.\n+ * Take a look at ice_aq_ver_check in ice_controlq.c for actual usage.\n+ *\n+ */\n+#define EXP_FW_API_VER_BRANCH\t\t0x00\n+#define EXP_FW_API_VER_MAJOR\t\t0x00\n+#define EXP_FW_API_VER_MINOR\t\t0x01\n+\n+/* Different control queue types: These are mainly for SW consumption. */\n+enum ice_ctl_q {\n+\tICE_CTL_Q_UNKNOWN = 0,\n+\tICE_CTL_Q_ADMIN,\n+};\n+\n+/* Control Queue default settings */\n+#define ICE_CTL_Q_SQ_CMD_TIMEOUT\t250 /* msecs */\n+\n+struct ice_ctl_q_ring {\n+\tvoid *dma_head;\t\t\t/* Virtual address to dma head */\n+\tstruct ice_dma_mem desc_buf;\t/* descriptor ring memory */\n+\tvoid *cmd_buf;\t\t\t/* command buffer memory */\n+\n+\tunion {\n+\t\tstruct ice_dma_mem *sq_bi;\n+\t\tstruct ice_dma_mem *rq_bi;\n+\t} r;\n+\n+\tu16 count;\t\t/* Number of descriptors */\n+\n+\t/* used for interrupt processing */\n+\tu16 next_to_use;\n+\tu16 next_to_clean;\n+\n+\t/* used for queue tracking */\n+\tu32 head;\n+\tu32 tail;\n+\tu32 len;\n+\tu32 bah;\n+\tu32 bal;\n+\tu32 len_mask;\n+\tu32 len_ena_mask;\n+\tu32 head_mask;\n+};\n+\n+/* sq transaction details */\n+struct ice_sq_cd {\n+\tstruct ice_aq_desc *wb_desc;\n+};\n+\n+#define ICE_CTL_Q_DETAILS(R, i) (&(((struct ice_sq_cd *)((R).cmd_buf))[i]))\n+\n+/* Control Queue information */\n+struct ice_ctl_q_info {\n+\tenum ice_ctl_q qtype;\n+\tstruct ice_ctl_q_ring rq;\t/* receive queue */\n+\tstruct ice_ctl_q_ring sq;\t/* send queue */\n+\tu32 sq_cmd_timeout;\t\t/* send queue cmd write back timeout */\n+\tu16 num_rq_entries;\t\t/* receive queue depth */\n+\tu16 num_sq_entries;\t\t/* send queue depth */\n+\tu16 rq_buf_size;\t\t/* receive queue buffer size */\n+\tu16 sq_buf_size;\t\t/* send queue buffer size */\n+\tstruct mutex sq_lock;\t\t/* Send queue lock */\n+\tstruct mutex rq_lock;\t\t/* Receive queue lock */\n+\tenum ice_aq_err sq_last_status;\t/* last status on send queue */\n+\tenum ice_aq_err rq_last_status;\t/* last status on receive queue */\n+};\n+\n+#endif /* _ICE_CONTROLQ_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h\nnew file mode 100644\nindex 000000000000..3d6bb273e4c8\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h\n@@ -0,0 +1,46 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/* Intel(R) Ethernet Connection E800 Series Linux Driver\n+ * Copyright (c) 2018, Intel Corporation.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * The full GNU General Public License is included in this distribution in\n+ * the file called \"COPYING\".\n+ */\n+\n+/* Machine-generated file */\n+\n+#ifndef _ICE_HW_AUTOGEN_H_\n+#define _ICE_HW_AUTOGEN_H_\n+\n+#define PF_FW_ARQBAH\t\t\t0x00080180\n+#define PF_FW_ARQBAL\t\t\t0x00080080\n+#define PF_FW_ARQH\t\t\t0x00080380\n+#define PF_FW_ARQH_ARQH_S\t\t0\n+#define PF_FW_ARQH_ARQH_M\t\tICE_M(0x3FF, PF_FW_ARQH_ARQH_S)\n+#define PF_FW_ARQLEN\t\t\t0x00080280\n+#define PF_FW_ARQLEN_ARQLEN_S\t\t0\n+#define PF_FW_ARQLEN_ARQLEN_M\t\tICE_M(0x3FF, PF_FW_ARQLEN_ARQLEN_S)\n+#define PF_FW_ARQLEN_ARQENABLE_S\t31\n+#define PF_FW_ARQLEN_ARQENABLE_M\tBIT(PF_FW_ARQLEN_ARQENABLE_S)\n+#define PF_FW_ARQT\t\t\t0x00080480\n+#define PF_FW_ATQBAH\t\t\t0x00080100\n+#define PF_FW_ATQBAL\t\t\t0x00080000\n+#define PF_FW_ATQH\t\t\t0x00080300\n+#define PF_FW_ATQH_ATQH_S\t\t0\n+#define PF_FW_ATQH_ATQH_M\t\tICE_M(0x3FF, PF_FW_ATQH_ATQH_S)\n+#define PF_FW_ATQLEN\t\t\t0x00080200\n+#define PF_FW_ATQLEN_ATQLEN_S\t\t0\n+#define PF_FW_ATQLEN_ATQLEN_M\t\tICE_M(0x3FF, PF_FW_ATQLEN_ATQLEN_S)\n+#define PF_FW_ATQLEN_ATQENABLE_S\t31\n+#define PF_FW_ATQLEN_ATQENABLE_M\tBIT(PF_FW_ATQLEN_ATQENABLE_S)\n+#define PF_FW_ATQT\t\t\t0x00080400\n+\n+#endif /* _ICE_HW_AUTOGEN_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c\nindex 0631812aef2b..408ae90d6562 100644\n--- a/drivers/net/ethernet/intel/ice/ice_main.c\n+++ b/drivers/net/ethernet/intel/ice/ice_main.c\n@@ -34,7 +34,11 @@ MODULE_VERSION(DRV_VERSION);\n \n static int debug = -1;\n module_param(debug, int, 0644);\n-MODULE_PARM_DESC(debug, \"netif message level (0=none,...,0x7FFF=all)\");\n+#ifndef CONFIG_DYNAMIC_DEBUG\n+MODULE_PARM_DESC(debug, \"netif level (0=none,...,16=all), hw debug_mask (0x8XXXXXXX)\");\n+#else\n+MODULE_PARM_DESC(debug, \"netif level (0=none,...,16=all)\");\n+#endif /* !CONFIG_DYNAMIC_DEBUG */\n \n /**\n * ice_probe - Device initialization routine\n@@ -93,6 +97,11 @@ static int ice_probe(struct pci_dev *pdev,\n \thw->bus.func = PCI_FUNC(pdev->devfn);\n \tpf->msg_enable = netif_msg_init(debug, ICE_DFLT_NETIF_M);\n \n+#ifndef CONFIG_DYNAMIC_DEBUG\n+\tif (debug < -1)\n+\t\thw->debug_mask = debug;\n+#endif\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/net/ethernet/intel/ice/ice_osdep.h b/drivers/net/ethernet/intel/ice/ice_osdep.h\nnew file mode 100644\nindex 000000000000..fc6576a3a9d1\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_osdep.h\n@@ -0,0 +1,86 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/* Intel(R) Ethernet Connection E800 Series Linux Driver\n+ * Copyright (c) 2018, Intel Corporation.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * The full GNU General Public License is included in this distribution in\n+ * the file called \"COPYING\".\n+ */\n+\n+#ifndef _ICE_OSDEP_H_\n+#define _ICE_OSDEP_H_\n+\n+#include <linux/types.h>\n+#include <linux/io.h>\n+#ifndef CONFIG_64BIT\n+#include <linux/io-64-nonatomic-lo-hi.h>\n+#endif\n+\n+#define wr32(a, reg, value)\twritel((value), ((a)->hw_addr + (reg)))\n+#define rd32(a, reg)\t\treadl((a)->hw_addr + (reg))\n+#define wr64(a, reg, value)\twriteq((value), ((a)->hw_addr + (reg)))\n+#define rd64(a, reg)\t\treadq((a)->hw_addr + (reg))\n+\n+#define ICE_M(m, s)\t\t((m) << (s))\n+\n+struct ice_dma_mem {\n+\tvoid *va;\n+\tdma_addr_t pa;\n+\tsize_t size;\n+};\n+\n+#define ice_hw_to_dev(ptr)\t\\\n+\t(&(container_of((ptr), struct ice_pf, hw))->pdev->dev)\n+\n+#ifdef CONFIG_DYNAMIC_DEBUG\n+#define ice_debug(hw, type, fmt, args...) \\\n+\tdev_dbg(ice_hw_to_dev(hw), fmt, ##args)\n+\n+#define ice_debug_array(hw, type, rowsize, groupsize, buf, len) \\\n+\tprint_hex_dump_debug(KBUILD_MODNAME \" \",\t\t\\\n+\t\t\t DUMP_PREFIX_OFFSET, rowsize,\t\\\n+\t\t\t groupsize, buf, len, false)\n+#else\n+#define ice_debug(hw, type, fmt, args...)\t\t\t\\\n+do {\t\t\t\t\t\t\t\t\\\n+\tif ((type) & (hw)->debug_mask)\t\t\t\t\\\n+\t\tdev_info(ice_hw_to_dev(hw), fmt, ##args);\t\\\n+} while (0)\n+\n+#ifdef DEBUG\n+#define ice_debug_array(hw, type, rowsize, groupsize, buf, len) \\\n+do {\t\t\t\t\t\t\t\t\\\n+\tif ((type) & (hw)->debug_mask)\t\t\t\t\\\n+\t\tprint_hex_dump_debug(KBUILD_MODNAME,\t\t\\\n+\t\t\t\t DUMP_PREFIX_OFFSET,\t\\\n+\t\t\t\t rowsize, groupsize, buf,\t\\\n+\t\t\t\t len, false);\t\t\\\n+} while (0)\n+#else\n+#define ice_debug_array(hw, type, rowsize, groupsize, buf, len) \\\n+do {\t\t\t\t\t\t\t\t\\\n+\tstruct ice_hw *hw_l = hw;\t\t\t\t\\\n+\tif ((type) & (hw_l)->debug_mask) {\t\t\t\\\n+\t\tu16 len_l = len;\t\t\t\t\\\n+\t\tu8 *buf_l = buf;\t\t\t\t\\\n+\t\tint i;\t\t\t\t\t\t\\\n+\t\tfor (i = 0; i < (len_l - 16); i += 16)\t\t\\\n+\t\t\tice_debug(hw_l, type, \"0x%04X %16ph\\n\",\\\n+\t\t\t\t i, ((buf_l) + i));\t\t\\\n+\t\tif (i < len_l)\t\t\t\t\t\\\n+\t\t\tice_debug(hw_l, type, \"0x%04X %*ph\\n\", \\\n+\t\t\t\t i, ((len_l) - i), ((buf_l) + i));\\\n+\t}\t\t\t\t\t\t\t\\\n+} while (0)\n+#endif /* DEBUG */\n+#endif /* CONFIG_DYNAMIC_DEBUG */\n+\n+#endif /* _ICE_OSDEP_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_status.h b/drivers/net/ethernet/intel/ice/ice_status.h\nnew file mode 100644\nindex 000000000000..940d6f57adcf\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_status.h\n@@ -0,0 +1,35 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/* Intel(R) Ethernet Connection E800 Series Linux Driver\n+ * Copyright (c) 2018, Intel Corporation.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * The full GNU General Public License is included in this distribution in\n+ * the file called \"COPYING\".\n+ */\n+\n+#ifndef _ICE_STATUS_H_\n+#define _ICE_STATUS_H_\n+\n+/* Error Codes */\n+enum ice_status {\n+\tICE_ERR_PARAM\t\t\t\t= -1,\n+\tICE_ERR_NOT_READY\t\t\t= -3,\n+\tICE_ERR_INVAL_SIZE\t\t\t= -6,\n+\tICE_ERR_FW_API_VER\t\t\t= -10,\n+\tICE_ERR_NO_MEMORY\t\t\t= -11,\n+\tICE_ERR_CFG\t\t\t\t= -12,\n+\tICE_ERR_AQ_ERROR\t\t\t= -100,\n+\tICE_ERR_AQ_TIMEOUT\t\t\t= -101,\n+\tICE_ERR_AQ_FULL\t\t\t\t= -102,\n+\tICE_ERR_AQ_EMPTY\t\t\t= -104,\n+};\n+\n+#endif /* _ICE_STATUS_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h\nindex ad01e5f73d2c..cfa98e55a33a 100644\n--- a/drivers/net/ethernet/intel/ice/ice_type.h\n+++ b/drivers/net/ethernet/intel/ice/ice_type.h\n@@ -18,6 +18,15 @@\n #ifndef _ICE_TYPE_H_\n #define _ICE_TYPE_H_\n \n+#include \"ice_status.h\"\n+#include \"ice_hw_autogen.h\"\n+#include \"ice_osdep.h\"\n+#include \"ice_controlq.h\"\n+\n+/* debug masks - set these bits in hw->debug_mask to control output */\n+#define ICE_DBG_AQ_MSG\t\tBIT_ULL(24)\n+#define ICE_DBG_AQ_CMD\t\tBIT_ULL(27)\n+\n /* Bus parameters */\n struct ice_bus_info {\n \tu16 device;\n@@ -28,6 +37,7 @@ struct ice_bus_info {\n struct ice_hw {\n \tu8 __iomem *hw_addr;\n \tvoid *back;\n+\tu64 debug_mask;\t\t/* bitmap for debug mask */\n \n \t/* pci info */\n \tu16 device_id;\n@@ -37,6 +47,18 @@ struct ice_hw {\n \tu8 revision_id;\n \n \tstruct ice_bus_info bus;\n+\t/* Control Queue info */\n+\tstruct ice_ctl_q_info adminq;\n+\n+\tu8 api_branch;\t\t/* API branch version */\n+\tu8 api_maj_ver;\t\t/* API major version */\n+\tu8 api_min_ver;\t\t/* API minor version */\n+\tu8 api_patch;\t\t/* API patch version */\n+\tu8 fw_branch;\t\t/* firmware branch version */\n+\tu8 fw_maj_ver;\t\t/* firmware major version */\n+\tu8 fw_min_ver;\t\t/* firmware minor version */\n+\tu8 fw_patch;\t\t/* firmware patch version */\n+\tu32 fw_build;\t\t/* firmware build number */\n };\n \n #endif /* _ICE_TYPE_H_ */\n", "prefixes": [ "v3", "02/15" ] }