get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/886540/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 886540,
    "url": "http://patchwork.ozlabs.org/api/patches/886540/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20180315234802.31336-6-anirudh.venkataramanan@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": "<20180315234802.31336-6-anirudh.venkataramanan@intel.com>",
    "list_archive_url": null,
    "date": "2018-03-15T23:47:52",
    "name": "[v2,05/15] ice: Get MAC/PHY/link info and scheduler topology",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "4f2a27392f9d4c48fdfdf591ff6a8cc67e66fdea",
    "submitter": {
        "id": 73601,
        "url": "http://patchwork.ozlabs.org/api/people/73601/?format=api",
        "name": "Anirudh Venkataramanan",
        "email": "anirudh.venkataramanan@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/20180315234802.31336-6-anirudh.venkataramanan@intel.com/mbox/",
    "series": [
        {
            "id": 34096,
            "url": "http://patchwork.ozlabs.org/api/series/34096/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=34096",
            "date": "2018-03-15T23:47:47",
            "name": "Add ice driver",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/34096/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/886540/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/886540/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.133; helo=hemlock.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 hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\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 402QK63bYXz9s1c\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 16 Mar 2018 10:48:42 +1100 (AEDT)",
            "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id EB0B78A26E;\n\tThu, 15 Mar 2018 23:48:40 +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 Nne8QvG0mkIq; Thu, 15 Mar 2018 23:48:30 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 233908A2B8;\n\tThu, 15 Mar 2018 23:48:14 +0000 (UTC)",
            "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\tby ash.osuosl.org (Postfix) with ESMTP id E288E1C0359\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 15 Mar 2018 23:48:11 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id DF4A622118\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 15 Mar 2018 23:48:11 +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 5gBFvePmhSF7 for <intel-wired-lan@lists.osuosl.org>;\n\tThu, 15 Mar 2018 23:48:04 +0000 (UTC)",
            "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n\tby silver.osuosl.org (Postfix) with ESMTPS id 786EA2267D\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 15 Mar 2018 23:48:04 +0000 (UTC)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n\tby fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t15 Mar 2018 16:48:03 -0700",
            "from shasta.jf.intel.com ([10.166.241.32])\n\tby fmsmga004.fm.intel.com with ESMTP; 15 Mar 2018 16:48:03 -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,313,1517904000\"; d=\"scan'208\";a=\"37836785\"",
        "From": "Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>",
        "To": "intel-wired-lan@lists.osuosl.org",
        "Date": "Thu, 15 Mar 2018 16:47:52 -0700",
        "Message-Id": "<20180315234802.31336-6-anirudh.venkataramanan@intel.com>",
        "X-Mailer": "git-send-email 2.14.3",
        "In-Reply-To": "<20180315234802.31336-1-anirudh.venkataramanan@intel.com>",
        "References": "<20180315234802.31336-1-anirudh.venkataramanan@intel.com>",
        "Subject": "[Intel-wired-lan] [PATCH v2 05/15] ice: Get MAC/PHY/link info and\n\tscheduler topology",
        "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>",
        "Cc": "netdev@vger.kernel.org",
        "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": "This patch adds code to continue the initialization flow as follows:\n\n1) Get PHY/link information and store it\n2) Get default scheduler tree topology and store it\n3) Get the MAC address associated with the port and store it\n\nSigned-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>\n---\n drivers/net/ethernet/intel/ice/ice.h            |   1 +\n drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | 261 +++++++++++++++++++\n drivers/net/ethernet/intel/ice/ice_common.c     | 264 +++++++++++++++++++\n drivers/net/ethernet/intel/ice/ice_common.h     |   3 +\n drivers/net/ethernet/intel/ice/ice_sched.c      | 328 ++++++++++++++++++++++++\n drivers/net/ethernet/intel/ice/ice_sched.h      |   6 +\n drivers/net/ethernet/intel/ice/ice_status.h     |   1 +\n drivers/net/ethernet/intel/ice/ice_type.h       |  65 +++++\n 8 files changed, 929 insertions(+)",
    "diff": "diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h\nindex f6e3339591bb..9681e971bcab 100644\n--- a/drivers/net/ethernet/intel/ice/ice.h\n+++ b/drivers/net/ethernet/intel/ice/ice.h\n@@ -24,6 +24,7 @@\n #include <linux/module.h>\n #include <linux/netdevice.h>\n #include <linux/compiler.h>\n+#include <linux/etherdevice.h>\n #include <linux/pci.h>\n #include <linux/aer.h>\n #include <linux/delay.h>\ndiff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\nindex 66a3f41df673..13e3b7f3e24d 100644\n--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\n+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\n@@ -118,6 +118,35 @@ struct ice_aqc_list_caps_elem {\n \t__le64 rsvd2;\n };\n \n+/* Manage MAC address, read command - indirect (0x0107)\n+ * This struct is also used for the response\n+ */\n+struct ice_aqc_manage_mac_read {\n+\t__le16 flags; /* Zeroed by device driver */\n+#define ICE_AQC_MAN_MAC_LAN_ADDR_VALID\t\tBIT(4)\n+#define ICE_AQC_MAN_MAC_SAN_ADDR_VALID\t\tBIT(5)\n+#define ICE_AQC_MAN_MAC_PORT_ADDR_VALID\t\tBIT(6)\n+#define ICE_AQC_MAN_MAC_WOL_ADDR_VALID\t\tBIT(7)\n+#define ICE_AQC_MAN_MAC_READ_S\t\t\t4\n+#define ICE_AQC_MAN_MAC_READ_M\t\t\t(0xF << ICE_AQC_MAN_MAC_READ_S)\n+\tu8 lport_num;\n+\tu8 lport_num_valid;\n+#define ICE_AQC_MAN_MAC_PORT_NUM_IS_VALID\tBIT(0)\n+\tu8 num_addr; /* Used in response */\n+\tu8 reserved[3];\n+\t__le32 addr_high;\n+\t__le32 addr_low;\n+};\n+\n+/* Response buffer format for manage MAC read command */\n+struct ice_aqc_manage_mac_read_resp {\n+\tu8 lport_num;\n+\tu8 addr_type;\n+#define ICE_AQC_MAN_MAC_ADDR_TYPE_LAN\t\t0\n+#define ICE_AQC_MAN_MAC_ADDR_TYPE_WOL\t\t1\n+\tu8 mac_addr[ETH_ALEN];\n+};\n+\n /* Clear PXE Command and response (direct 0x0110) */\n struct ice_aqc_clear_pxe {\n \tu8 rx_cnt;\n@@ -175,6 +204,16 @@ struct ice_aqc_get_sw_cfg_resp {\n \tstruct ice_aqc_get_sw_cfg_resp_elem elements[1];\n };\n \n+/* Get Default Topology (indirect 0x0400) */\n+struct ice_aqc_get_topo {\n+\tu8 port_num;\n+\tu8 num_branches;\n+\t__le16 reserved1;\n+\t__le32 reserved2;\n+\t__le32 addr_high;\n+\t__le32 addr_low;\n+};\n+\n /* Add TSE (indirect 0x0401)\n  * Delete TSE (indirect 0x040F)\n  * Move TSE (indirect 0x0408)\n@@ -235,6 +274,12 @@ struct ice_aqc_txsched_topo_grp_info_hdr {\n \t__le16 reserved2;\n };\n \n+struct ice_aqc_get_topo_elem {\n+\tstruct ice_aqc_txsched_topo_grp_info_hdr hdr;\n+\tstruct ice_aqc_txsched_elem_data\n+\t\tgeneric[ICE_AQC_TOPO_MAX_LEVEL_NUM];\n+};\n+\n struct ice_aqc_delete_elem {\n \tstruct ice_aqc_txsched_topo_grp_info_hdr hdr;\n \t__le32 teid[1];\n@@ -280,6 +325,210 @@ struct ice_aqc_query_txsched_res_resp {\n \tstruct ice_aqc_layer_props layer_props[ICE_AQC_TOPO_MAX_LEVEL_NUM];\n };\n \n+/* Get PHY capabilities (indirect 0x0600) */\n+struct ice_aqc_get_phy_caps {\n+\tu8 lport_num;\n+\tu8 reserved;\n+\t__le16 param0;\n+\t/* 18.0 - Report qualified modules */\n+#define ICE_AQC_GET_PHY_RQM\t\tBIT(0)\n+\t/* 18.1 - 18.2 : Report mode\n+\t * 00b - Report NVM capabilities\n+\t * 01b - Report topology capabilities\n+\t * 10b - Report SW configured\n+\t */\n+#define ICE_AQC_REPORT_MODE_S\t\t1\n+#define ICE_AQC_REPORT_MODE_M\t\t(3 << ICE_AQC_REPORT_MODE_S)\n+#define ICE_AQC_REPORT_NVM_CAP\t\t0\n+#define ICE_AQC_REPORT_TOPO_CAP\t\tBIT(1)\n+#define ICE_AQC_REPORT_SW_CFG\t\tBIT(2)\n+\t__le32 reserved1;\n+\t__le32 addr_high;\n+\t__le32 addr_low;\n+};\n+\n+/* This is #define of PHY type (Extended):\n+ * The first set of defines is for phy_type_low.\n+ */\n+#define ICE_PHY_TYPE_LOW_100BASE_TX\t\tBIT_ULL(0)\n+#define ICE_PHY_TYPE_LOW_100M_SGMII\t\tBIT_ULL(1)\n+#define ICE_PHY_TYPE_LOW_1000BASE_T\t\tBIT_ULL(2)\n+#define ICE_PHY_TYPE_LOW_1000BASE_SX\t\tBIT_ULL(3)\n+#define ICE_PHY_TYPE_LOW_1000BASE_LX\t\tBIT_ULL(4)\n+#define ICE_PHY_TYPE_LOW_1000BASE_KX\t\tBIT_ULL(5)\n+#define ICE_PHY_TYPE_LOW_1G_SGMII\t\tBIT_ULL(6)\n+#define ICE_PHY_TYPE_LOW_2500BASE_T\t\tBIT_ULL(7)\n+#define ICE_PHY_TYPE_LOW_2500BASE_X\t\tBIT_ULL(8)\n+#define ICE_PHY_TYPE_LOW_2500BASE_KX\t\tBIT_ULL(9)\n+#define ICE_PHY_TYPE_LOW_5GBASE_T\t\tBIT_ULL(10)\n+#define ICE_PHY_TYPE_LOW_5GBASE_KR\t\tBIT_ULL(11)\n+#define ICE_PHY_TYPE_LOW_10GBASE_T\t\tBIT_ULL(12)\n+#define ICE_PHY_TYPE_LOW_10G_SFI_DA\t\tBIT_ULL(13)\n+#define ICE_PHY_TYPE_LOW_10GBASE_SR\t\tBIT_ULL(14)\n+#define ICE_PHY_TYPE_LOW_10GBASE_LR\t\tBIT_ULL(15)\n+#define ICE_PHY_TYPE_LOW_10GBASE_KR_CR1\t\tBIT_ULL(16)\n+#define ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC\tBIT_ULL(17)\n+#define ICE_PHY_TYPE_LOW_10G_SFI_C2C\t\tBIT_ULL(18)\n+#define ICE_PHY_TYPE_LOW_25GBASE_T\t\tBIT_ULL(19)\n+#define ICE_PHY_TYPE_LOW_25GBASE_CR\t\tBIT_ULL(20)\n+#define ICE_PHY_TYPE_LOW_25GBASE_CR_S\t\tBIT_ULL(21)\n+#define ICE_PHY_TYPE_LOW_25GBASE_CR1\t\tBIT_ULL(22)\n+#define ICE_PHY_TYPE_LOW_25GBASE_SR\t\tBIT_ULL(23)\n+#define ICE_PHY_TYPE_LOW_25GBASE_LR\t\tBIT_ULL(24)\n+#define ICE_PHY_TYPE_LOW_25GBASE_KR\t\tBIT_ULL(25)\n+#define ICE_PHY_TYPE_LOW_25GBASE_KR_S\t\tBIT_ULL(26)\n+#define ICE_PHY_TYPE_LOW_25GBASE_KR1\t\tBIT_ULL(27)\n+#define ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC\tBIT_ULL(28)\n+#define ICE_PHY_TYPE_LOW_25G_AUI_C2C\t\tBIT_ULL(29)\n+#define ICE_PHY_TYPE_LOW_40GBASE_CR4\t\tBIT_ULL(30)\n+#define ICE_PHY_TYPE_LOW_40GBASE_SR4\t\tBIT_ULL(31)\n+#define ICE_PHY_TYPE_LOW_40GBASE_LR4\t\tBIT_ULL(32)\n+#define ICE_PHY_TYPE_LOW_40GBASE_KR4\t\tBIT_ULL(33)\n+#define ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC\tBIT_ULL(34)\n+#define ICE_PHY_TYPE_LOW_40G_XLAUI\t\tBIT_ULL(35)\n+#define ICE_PHY_TYPE_LOW_MAX_INDEX\t\t63\n+\n+struct ice_aqc_get_phy_caps_data {\n+\t__le64 phy_type_low; /* Use values from ICE_PHY_TYPE_LOW_* */\n+\t__le64 reserved;\n+\tu8 caps;\n+#define ICE_AQC_PHY_EN_TX_LINK_PAUSE\t\t\tBIT(0)\n+#define ICE_AQC_PHY_EN_RX_LINK_PAUSE\t\t\tBIT(1)\n+#define ICE_AQC_PHY_LOW_POWER_MODE\t\t\tBIT(2)\n+#define ICE_AQC_PHY_EN_LINK\t\t\t\tBIT(3)\n+#define ICE_AQC_PHY_AN_MODE\t\t\t\tBIT(4)\n+#define ICE_AQC_GET_PHY_EN_MOD_QUAL\t\t\tBIT(5)\n+\tu8 low_power_ctrl;\n+#define ICE_AQC_PHY_EN_D3COLD_LOW_POWER_AUTONEG\t\tBIT(0)\n+\t__le16 eee_cap;\n+#define ICE_AQC_PHY_EEE_EN_100BASE_TX\t\t\tBIT(0)\n+#define ICE_AQC_PHY_EEE_EN_1000BASE_T\t\t\tBIT(1)\n+#define ICE_AQC_PHY_EEE_EN_10GBASE_T\t\t\tBIT(2)\n+#define ICE_AQC_PHY_EEE_EN_1000BASE_KX\t\t\tBIT(3)\n+#define ICE_AQC_PHY_EEE_EN_10GBASE_KR\t\t\tBIT(4)\n+#define ICE_AQC_PHY_EEE_EN_25GBASE_KR\t\t\tBIT(5)\n+#define ICE_AQC_PHY_EEE_EN_40GBASE_KR4\t\t\tBIT(6)\n+\t__le16 eeer_value;\n+\tu8 phy_id_oui[4]; /* PHY/Module ID connected on the port */\n+\tu8 link_fec_options;\n+#define ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN\t\tBIT(0)\n+#define ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ\t\tBIT(1)\n+#define ICE_AQC_PHY_FEC_25G_RS_528_REQ\t\t\tBIT(2)\n+#define ICE_AQC_PHY_FEC_25G_KR_REQ\t\t\tBIT(3)\n+#define ICE_AQC_PHY_FEC_25G_RS_544_REQ\t\t\tBIT(4)\n+#define ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN\t\tBIT(6)\n+#define ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN\t\tBIT(7)\n+\tu8 extended_compliance_code;\n+#define ICE_MODULE_TYPE_TOTAL_BYTE\t\t\t3\n+\tu8 module_type[ICE_MODULE_TYPE_TOTAL_BYTE];\n+#define ICE_AQC_MOD_TYPE_BYTE0_SFP_PLUS\t\t\t0xA0\n+#define ICE_AQC_MOD_TYPE_BYTE0_QSFP_PLUS\t\t0x80\n+#define ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE\tBIT(0)\n+#define ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE\tBIT(1)\n+#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_SR\t\tBIT(4)\n+#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_LR\t\tBIT(5)\n+#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_LRM\t\tBIT(6)\n+#define ICE_AQC_MOD_TYPE_BYTE1_10G_BASE_ER\t\tBIT(7)\n+#define ICE_AQC_MOD_TYPE_BYTE2_SFP_PLUS\t\t\t0xA0\n+#define ICE_AQC_MOD_TYPE_BYTE2_QSFP_PLUS\t\t0x86\n+\tu8 qualified_module_count;\n+#define ICE_AQC_QUAL_MOD_COUNT_MAX\t\t\t16\n+\tstruct {\n+\t\tu8 v_oui[3];\n+\t\tu8 rsvd1;\n+\t\tu8 v_part[16];\n+\t\t__le32 v_rev;\n+\t\t__le64 rsvd8;\n+\t} qual_modules[ICE_AQC_QUAL_MOD_COUNT_MAX];\n+};\n+\n+/* Get link status (indirect 0x0607), also used for Link Status Event */\n+struct ice_aqc_get_link_status {\n+\tu8 lport_num;\n+\tu8 reserved;\n+\t__le16 cmd_flags;\n+#define ICE_AQ_LSE_M\t\t\t0x3\n+#define ICE_AQ_LSE_NOP\t\t\t0x0\n+#define ICE_AQ_LSE_DIS\t\t\t0x2\n+#define ICE_AQ_LSE_ENA\t\t\t0x3\n+\t/* only response uses this flag */\n+#define ICE_AQ_LSE_IS_ENABLED\t\t0x1\n+\t__le32 reserved2;\n+\t__le32 addr_high;\n+\t__le32 addr_low;\n+};\n+\n+/* Get link status response data structure, also used for Link Status Event */\n+struct ice_aqc_get_link_status_data {\n+\tu8 topo_media_conflict;\n+#define ICE_AQ_LINK_TOPO_CONFLICT\tBIT(0)\n+#define ICE_AQ_LINK_MEDIA_CONFLICT\tBIT(1)\n+#define ICE_AQ_LINK_TOPO_CORRUPT\tBIT(2)\n+\tu8 reserved1;\n+\tu8 link_info;\n+#define ICE_AQ_LINK_UP\t\t\tBIT(0)\t/* Link Status */\n+#define ICE_AQ_LINK_FAULT\t\tBIT(1)\n+#define ICE_AQ_LINK_FAULT_TX\t\tBIT(2)\n+#define ICE_AQ_LINK_FAULT_RX\t\tBIT(3)\n+#define ICE_AQ_LINK_FAULT_REMOTE\tBIT(4)\n+#define ICE_AQ_LINK_UP_PORT\t\tBIT(5)\t/* External Port Link Status */\n+#define ICE_AQ_MEDIA_AVAILABLE\t\tBIT(6)\n+#define ICE_AQ_SIGNAL_DETECT\t\tBIT(7)\n+\tu8 an_info;\n+#define ICE_AQ_AN_COMPLETED\t\tBIT(0)\n+#define ICE_AQ_LP_AN_ABILITY\t\tBIT(1)\n+#define ICE_AQ_PD_FAULT\t\t\tBIT(2)\t/* Parallel Detection Fault */\n+#define ICE_AQ_FEC_EN\t\t\tBIT(3)\n+#define ICE_AQ_PHY_LOW_POWER\t\tBIT(4)\t/* Low Power State */\n+#define ICE_AQ_LINK_PAUSE_TX\t\tBIT(5)\n+#define ICE_AQ_LINK_PAUSE_RX\t\tBIT(6)\n+#define ICE_AQ_QUALIFIED_MODULE\t\tBIT(7)\n+\tu8 ext_info;\n+#define ICE_AQ_LINK_PHY_TEMP_ALARM\tBIT(0)\n+#define ICE_AQ_LINK_EXCESSIVE_ERRORS\tBIT(1)\t/* Excessive Link Errors */\n+\t/* Port TX Suspended */\n+#define ICE_AQ_LINK_TX_S\t\t2\n+#define ICE_AQ_LINK_TX_M\t\t(0x03 << ICE_AQ_LINK_TX_S)\n+#define ICE_AQ_LINK_TX_ACTIVE\t\t0\n+#define ICE_AQ_LINK_TX_DRAINED\t\t1\n+#define ICE_AQ_LINK_TX_FLUSHED\t\t3\n+\tu8 reserved2;\n+\t__le16 max_frame_size;\n+\tu8 cfg;\n+#define ICE_AQ_LINK_25G_KR_FEC_EN\tBIT(0)\n+#define ICE_AQ_LINK_25G_RS_528_FEC_EN\tBIT(1)\n+#define ICE_AQ_LINK_25G_RS_544_FEC_EN\tBIT(2)\n+\t/* Pacing Config */\n+#define ICE_AQ_CFG_PACING_S\t\t3\n+#define ICE_AQ_CFG_PACING_M\t\t(0xF << ICE_AQ_CFG_PACING_S)\n+#define ICE_AQ_CFG_PACING_TYPE_M\tBIT(7)\n+#define ICE_AQ_CFG_PACING_TYPE_AVG\t0\n+#define ICE_AQ_CFG_PACING_TYPE_FIXED\tICE_AQ_CFG_PACING_TYPE_M\n+\t/* External Device Power Ability */\n+\tu8 power_desc;\n+#define ICE_AQ_PWR_CLASS_M\t\t0x3\n+#define ICE_AQ_LINK_PWR_BASET_LOW_HIGH\t0\n+#define ICE_AQ_LINK_PWR_BASET_HIGH\t1\n+#define ICE_AQ_LINK_PWR_QSFP_CLASS_1\t0\n+#define ICE_AQ_LINK_PWR_QSFP_CLASS_2\t1\n+#define ICE_AQ_LINK_PWR_QSFP_CLASS_3\t2\n+#define ICE_AQ_LINK_PWR_QSFP_CLASS_4\t3\n+\t__le16 link_speed;\n+#define ICE_AQ_LINK_SPEED_10MB\t\tBIT(0)\n+#define ICE_AQ_LINK_SPEED_100MB\t\tBIT(1)\n+#define ICE_AQ_LINK_SPEED_1000MB\tBIT(2)\n+#define ICE_AQ_LINK_SPEED_2500MB\tBIT(3)\n+#define ICE_AQ_LINK_SPEED_5GB\t\tBIT(4)\n+#define ICE_AQ_LINK_SPEED_10GB\t\tBIT(5)\n+#define ICE_AQ_LINK_SPEED_20GB\t\tBIT(6)\n+#define ICE_AQ_LINK_SPEED_25GB\t\tBIT(7)\n+#define ICE_AQ_LINK_SPEED_40GB\t\tBIT(8)\n+#define ICE_AQ_LINK_SPEED_UNKNOWN\tBIT(15)\n+\t__le32 reserved3; /* Aligns next field to 8-byte boundary */\n+\t__le64 phy_type_low; /* Use values from ICE_PHY_TYPE_LOW_* */\n+\t__le64 reserved4;\n+};\n+\n /* NVM Read command (indirect 0x0701)\n  * NVM Erase commands (direct 0x0702)\n  * NVM Update commands (indirect 0x0703)\n@@ -332,12 +581,16 @@ struct ice_aq_desc {\n \t\tstruct ice_aqc_get_ver get_ver;\n \t\tstruct ice_aqc_q_shutdown q_shutdown;\n \t\tstruct ice_aqc_req_res res_owner;\n+\t\tstruct ice_aqc_manage_mac_read mac_read;\n \t\tstruct ice_aqc_clear_pxe clear_pxe;\n \t\tstruct ice_aqc_list_caps get_cap;\n+\t\tstruct ice_aqc_get_phy_caps get_phy;\n \t\tstruct ice_aqc_get_sw_cfg get_sw_conf;\n+\t\tstruct ice_aqc_get_topo get_topo;\n \t\tstruct ice_aqc_query_txsched_res query_sched_res;\n \t\tstruct ice_aqc_add_move_delete_elem add_move_delete_elem;\n \t\tstruct ice_aqc_nvm nvm;\n+\t\tstruct ice_aqc_get_link_status get_link_status;\n \t} params;\n };\n \n@@ -376,6 +629,9 @@ enum ice_adminq_opc {\n \tice_aqc_opc_list_func_caps\t\t\t= 0x000A,\n \tice_aqc_opc_list_dev_caps\t\t\t= 0x000B,\n \n+\t/* manage MAC address */\n+\tice_aqc_opc_manage_mac_read\t\t\t= 0x0107,\n+\n \t/* PXE */\n \tice_aqc_opc_clear_pxe_mode\t\t\t= 0x0110,\n \n@@ -385,9 +641,14 @@ enum ice_adminq_opc {\n \tice_aqc_opc_clear_pf_cfg\t\t\t= 0x02A4,\n \n \t/* transmit scheduler commands */\n+\tice_aqc_opc_get_dflt_topo\t\t\t= 0x0400,\n \tice_aqc_opc_delete_sched_elems\t\t\t= 0x040F,\n \tice_aqc_opc_query_sched_res\t\t\t= 0x0412,\n \n+\t/* PHY commands */\n+\tice_aqc_opc_get_phy_caps\t\t\t= 0x0600,\n+\tice_aqc_opc_get_link_status\t\t\t= 0x0607,\n+\n \t/* NVM commands */\n \tice_aqc_opc_nvm_read\t\t\t\t= 0x0701,\n \ndiff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c\nindex 10f8b2ce5d44..91f34d90a1f4 100644\n--- a/drivers/net/ethernet/intel/ice/ice_common.c\n+++ b/drivers/net/ethernet/intel/ice/ice_common.c\n@@ -50,13 +50,238 @@ enum ice_status ice_clear_pf_cfg(struct ice_hw *hw)\n \treturn ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);\n }\n \n+/**\n+ * ice_aq_manage_mac_read - manage MAC address read command\n+ * @hw: pointer to the hw struct\n+ * @buf: a virtual buffer to hold the manage MAC read response\n+ * @buf_size: Size of the virtual buffer\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * This function is used to return per PF station MAC address (0x0107).\n+ * NOTE: Upon successful completion of this command, MAC address information\n+ * is returned in user specified buffer. Please interpret user specified\n+ * buffer as \"manage_mac_read\" response.\n+ * Response such as various MAC addresses are stored in HW struct (port.mac)\n+ * ice_aq_discover_caps is expected to be called before this function is called.\n+ */\n+static enum ice_status\n+ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,\n+\t\t       struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_manage_mac_read_resp *resp;\n+\tstruct ice_aqc_manage_mac_read *cmd;\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\tu16 flags;\n+\n+\tcmd = &desc.params.mac_read;\n+\n+\tif (buf_size < sizeof(*resp))\n+\t\treturn ICE_ERR_BUF_TOO_SHORT;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_read);\n+\n+\tstatus = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);\n+\tif (status)\n+\t\treturn status;\n+\n+\tresp = (struct ice_aqc_manage_mac_read_resp *)buf;\n+\tflags = le16_to_cpu(cmd->flags) & ICE_AQC_MAN_MAC_READ_M;\n+\n+\tif (!(flags & ICE_AQC_MAN_MAC_LAN_ADDR_VALID)) {\n+\t\tice_debug(hw, ICE_DBG_LAN, \"got invalid MAC address\\n\");\n+\t\treturn ICE_ERR_CFG;\n+\t}\n+\n+\tether_addr_copy(hw->port_info->mac.lan_addr, resp->mac_addr);\n+\tether_addr_copy(hw->port_info->mac.perm_addr, resp->mac_addr);\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_aq_get_phy_caps - returns PHY capabilities\n+ * @pi: port information structure\n+ * @qual_mods: report qualified modules\n+ * @report_mode: report mode capabilities\n+ * @pcaps: structure for PHY capabilities to be filled\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Returns the various PHY capabilities supported on the Port (0x0600)\n+ */\n+static enum ice_status\n+ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,\n+\t\t    struct ice_aqc_get_phy_caps_data *pcaps,\n+\t\t    struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_get_phy_caps *cmd;\n+\tu16 pcaps_size = sizeof(*pcaps);\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\n+\tcmd = &desc.params.get_phy;\n+\n+\tif (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps);\n+\n+\tif (qual_mods)\n+\t\tcmd->param0 |= cpu_to_le16(ICE_AQC_GET_PHY_RQM);\n+\n+\tcmd->param0 |= cpu_to_le16(report_mode);\n+\tstatus = ice_aq_send_cmd(pi->hw, &desc, pcaps, pcaps_size, cd);\n+\n+\tif (!status && report_mode == ICE_AQC_REPORT_TOPO_CAP)\n+\t\tpi->phy.phy_type_low = le64_to_cpu(pcaps->phy_type_low);\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ice_get_media_type - Gets media type\n+ * @pi: port information structure\n+ */\n+static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)\n+{\n+\tstruct ice_link_status *hw_link_info;\n+\n+\tif (!pi)\n+\t\treturn ICE_MEDIA_UNKNOWN;\n+\n+\thw_link_info = &pi->phy.link_info;\n+\n+\tif (hw_link_info->phy_type_low) {\n+\t\tswitch (hw_link_info->phy_type_low) {\n+\t\tcase ICE_PHY_TYPE_LOW_1000BASE_SX:\n+\t\tcase ICE_PHY_TYPE_LOW_1000BASE_LX:\n+\t\tcase ICE_PHY_TYPE_LOW_10GBASE_SR:\n+\t\tcase ICE_PHY_TYPE_LOW_10GBASE_LR:\n+\t\tcase ICE_PHY_TYPE_LOW_10G_SFI_C2C:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_SR:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_LR:\n+\t\tcase ICE_PHY_TYPE_LOW_25G_AUI_C2C:\n+\t\tcase ICE_PHY_TYPE_LOW_40GBASE_SR4:\n+\t\tcase ICE_PHY_TYPE_LOW_40GBASE_LR4:\n+\t\t\treturn ICE_MEDIA_FIBER;\n+\t\tcase ICE_PHY_TYPE_LOW_100BASE_TX:\n+\t\tcase ICE_PHY_TYPE_LOW_1000BASE_T:\n+\t\tcase ICE_PHY_TYPE_LOW_2500BASE_T:\n+\t\tcase ICE_PHY_TYPE_LOW_5GBASE_T:\n+\t\tcase ICE_PHY_TYPE_LOW_10GBASE_T:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_T:\n+\t\t\treturn ICE_MEDIA_BASET;\n+\t\tcase ICE_PHY_TYPE_LOW_10G_SFI_DA:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_CR:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_CR_S:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_CR1:\n+\t\tcase ICE_PHY_TYPE_LOW_40GBASE_CR4:\n+\t\t\treturn ICE_MEDIA_DA;\n+\t\tcase ICE_PHY_TYPE_LOW_1000BASE_KX:\n+\t\tcase ICE_PHY_TYPE_LOW_2500BASE_KX:\n+\t\tcase ICE_PHY_TYPE_LOW_2500BASE_X:\n+\t\tcase ICE_PHY_TYPE_LOW_5GBASE_KR:\n+\t\tcase ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_KR:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_KR1:\n+\t\tcase ICE_PHY_TYPE_LOW_25GBASE_KR_S:\n+\t\tcase ICE_PHY_TYPE_LOW_40GBASE_KR4:\n+\t\t\treturn ICE_MEDIA_BACKPLANE;\n+\t\t}\n+\t}\n+\n+\treturn ICE_MEDIA_UNKNOWN;\n+}\n+\n+/**\n+ * ice_aq_get_link_info\n+ * @pi: port information structure\n+ * @ena_lse: enable/disable LinkStatusEvent reporting\n+ * @link: pointer to link status structure - optional\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Get Link Status (0x607). Returns the link status of the adapter.\n+ */\n+enum ice_status\n+ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,\n+\t\t     struct ice_link_status *link, struct ice_sq_cd *cd)\n+{\n+\tstruct ice_link_status *hw_link_info_old, *hw_link_info;\n+\tstruct ice_aqc_get_link_status_data link_data = { 0 };\n+\tstruct ice_aqc_get_link_status *resp;\n+\tenum ice_media_type *hw_media_type;\n+\tstruct ice_fc_info *hw_fc_info;\n+\tbool tx_pause, rx_pause;\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\tu16 cmd_flags;\n+\n+\tif (!pi)\n+\t\treturn ICE_ERR_PARAM;\n+\thw_link_info_old = &pi->phy.link_info_old;\n+\thw_media_type = &pi->phy.media_type;\n+\thw_link_info = &pi->phy.link_info;\n+\thw_fc_info = &pi->fc;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status);\n+\tcmd_flags = (ena_lse) ? ICE_AQ_LSE_ENA : ICE_AQ_LSE_DIS;\n+\tresp = &desc.params.get_link_status;\n+\tresp->cmd_flags = cpu_to_le16(cmd_flags);\n+\tresp->lport_num = pi->lport;\n+\n+\tstatus = ice_aq_send_cmd(pi->hw, &desc, &link_data, sizeof(link_data),\n+\t\t\t\t cd);\n+\n+\tif (status)\n+\t\treturn status;\n+\n+\t/* save off old link status information */\n+\t*hw_link_info_old = *hw_link_info;\n+\n+\t/* update current link status information */\n+\thw_link_info->link_speed = le16_to_cpu(link_data.link_speed);\n+\thw_link_info->phy_type_low = le64_to_cpu(link_data.phy_type_low);\n+\t*hw_media_type = ice_get_media_type(pi);\n+\thw_link_info->link_info = link_data.link_info;\n+\thw_link_info->an_info = link_data.an_info;\n+\thw_link_info->ext_info = link_data.ext_info;\n+\thw_link_info->max_frame_size = le16_to_cpu(link_data.max_frame_size);\n+\thw_link_info->pacing = link_data.cfg & ICE_AQ_CFG_PACING_M;\n+\n+\t/* update fc info */\n+\ttx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_TX);\n+\trx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_RX);\n+\tif (tx_pause && rx_pause)\n+\t\thw_fc_info->current_mode = ICE_FC_FULL;\n+\telse if (tx_pause)\n+\t\thw_fc_info->current_mode = ICE_FC_TX_PAUSE;\n+\telse if (rx_pause)\n+\t\thw_fc_info->current_mode = ICE_FC_RX_PAUSE;\n+\telse\n+\t\thw_fc_info->current_mode = ICE_FC_NONE;\n+\n+\thw_link_info->lse_ena =\n+\t\t!!(resp->cmd_flags & cpu_to_le16(ICE_AQ_LSE_IS_ENABLED));\n+\n+\t/* save link status information */\n+\tif (link)\n+\t\t*link = *hw_link_info;\n+\n+\t/* flag cleared so calling functions don't call AQ again */\n+\tpi->phy.get_link_info = false;\n+\n+\treturn status;\n+}\n+\n /**\n  * ice_init_hw - main hardware initialization routine\n  * @hw: pointer to the hardware structure\n  */\n enum ice_status ice_init_hw(struct ice_hw *hw)\n {\n+\tstruct ice_aqc_get_phy_caps_data *pcaps;\n \tenum ice_status status;\n+\tu16 mac_buf_len;\n+\tvoid *mac_buf;\n \n \t/* Set MAC type based on DeviceID */\n \tstatus = ice_set_mac_type(hw);\n@@ -112,8 +337,46 @@ enum ice_status ice_init_hw(struct ice_hw *hw)\n \t\tgoto err_unroll_alloc;\n \t}\n \n+\t/* Initialize port_info struct with scheduler data */\n+\tstatus = ice_sched_init_port(hw->port_info);\n+\tif (status)\n+\t\tgoto err_unroll_sched;\n+\n+\tpcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);\n+\tif (!pcaps) {\n+\t\tstatus = ICE_ERR_NO_MEMORY;\n+\t\tgoto err_unroll_sched;\n+\t}\n+\n+\t/* Initialize port_info struct with PHY capabilities */\n+\tstatus = ice_aq_get_phy_caps(hw->port_info, false,\n+\t\t\t\t     ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL);\n+\tdevm_kfree(ice_hw_to_dev(hw), pcaps);\n+\tif (status)\n+\t\tgoto err_unroll_sched;\n+\n+\t/* Initialize port_info struct with link information */\n+\tstatus = ice_aq_get_link_info(hw->port_info, false, NULL, NULL);\n+\tif (status)\n+\t\tgoto err_unroll_sched;\n+\n+\t/* Get port MAC information */\n+\tmac_buf_len = sizeof(struct ice_aqc_manage_mac_read_resp);\n+\tmac_buf = devm_kzalloc(ice_hw_to_dev(hw), mac_buf_len, GFP_KERNEL);\n+\n+\tif (!mac_buf)\n+\t\tgoto err_unroll_sched;\n+\n+\tstatus = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);\n+\tdevm_kfree(ice_hw_to_dev(hw), mac_buf);\n+\n+\tif (status)\n+\t\tgoto err_unroll_sched;\n+\n \treturn 0;\n \n+err_unroll_sched:\n+\tice_sched_cleanup_all(hw);\n err_unroll_alloc:\n \tdevm_kfree(ice_hw_to_dev(hw), hw->port_info);\n err_unroll_cqinit:\n@@ -129,6 +392,7 @@ void ice_deinit_hw(struct ice_hw *hw)\n {\n \tice_sched_cleanup_all(hw);\n \tice_shutdown_all_ctrlq(hw);\n+\n \tif (hw->port_info) {\n \t\tdevm_kfree(ice_hw_to_dev(hw), hw->port_info);\n \t\thw->port_info = NULL;\ndiff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h\nindex 63ca2a26a274..3e3b18fc421d 100644\n--- a/drivers/net/ethernet/intel/ice/ice_common.h\n+++ b/drivers/net/ethernet/intel/ice/ice_common.h\n@@ -49,4 +49,7 @@ 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 enum ice_status ice_clear_pf_cfg(struct ice_hw *hw);\n+enum ice_status\n+ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,\n+\t\t     struct ice_link_status *link, struct ice_sq_cd *cd);\n #endif /* _ICE_COMMON_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c\nindex 66e48ae4a3ed..0a547141b125 100644\n--- a/drivers/net/ethernet/intel/ice/ice_sched.c\n+++ b/drivers/net/ethernet/intel/ice/ice_sched.c\n@@ -17,6 +17,141 @@\n \n #include \"ice_sched.h\"\n \n+/**\n+ * ice_sched_add_root_node - Insert the Tx scheduler root node in SW DB\n+ * @pi: port information structure\n+ * @info: Scheduler element information from firmware\n+ *\n+ * This function inserts the root node of the scheduling tree topology\n+ * to the SW DB.\n+ */\n+static enum ice_status\n+ice_sched_add_root_node(struct ice_port_info *pi,\n+\t\t\tstruct ice_aqc_txsched_elem_data *info)\n+{\n+\tstruct ice_sched_node *root;\n+\tstruct ice_hw *hw;\n+\tu16 max_children;\n+\n+\tif (!pi)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\thw = pi->hw;\n+\n+\troot = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*root), GFP_KERNEL);\n+\tif (!root)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\tmax_children = le16_to_cpu(hw->layer_info[0].max_children);\n+\troot->children = devm_kcalloc(ice_hw_to_dev(hw), max_children,\n+\t\t\t\t      sizeof(*root), GFP_KERNEL);\n+\tif (!root->children) {\n+\t\tdevm_kfree(ice_hw_to_dev(hw), root);\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\t}\n+\n+\tmemcpy(&root->info, info, sizeof(*info));\n+\tpi->root = root;\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_sched_find_node_by_teid - Find the Tx scheduler node in SW DB\n+ * @start_node: pointer to the starting ice_sched_node struct in a sub-tree\n+ * @teid: node teid to search\n+ *\n+ * This function searches for a node matching the teid in the scheduling tree\n+ * from the SW DB. The search is recursive and is restricted by the number of\n+ * layers it has searched through; stopping at the max supported layer.\n+ *\n+ * This function needs to be called when holding the port_info->sched_lock\n+ */\n+struct ice_sched_node *\n+ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid)\n+{\n+\tu16 i;\n+\n+\t/* The TEID is same as that of the start_node */\n+\tif (ICE_TXSCHED_GET_NODE_TEID(start_node) == teid)\n+\t\treturn start_node;\n+\n+\t/* The node has no children or is at the max layer */\n+\tif (!start_node->num_children ||\n+\t    start_node->tx_sched_layer >= ICE_AQC_TOPO_MAX_LEVEL_NUM ||\n+\t    start_node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF)\n+\t\treturn NULL;\n+\n+\t/* Check if teid matches to any of the children nodes */\n+\tfor (i = 0; i < start_node->num_children; i++)\n+\t\tif (ICE_TXSCHED_GET_NODE_TEID(start_node->children[i]) == teid)\n+\t\t\treturn start_node->children[i];\n+\n+\t/* Search within each child's sub-tree */\n+\tfor (i = 0; i < start_node->num_children; i++) {\n+\t\tstruct ice_sched_node *tmp;\n+\n+\t\ttmp = ice_sched_find_node_by_teid(start_node->children[i],\n+\t\t\t\t\t\t  teid);\n+\t\tif (tmp)\n+\t\t\treturn tmp;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+/**\n+ * ice_sched_add_node - Insert the Tx scheduler node in SW DB\n+ * @pi: port information structure\n+ * @layer: Scheduler layer of the node\n+ * @info: Scheduler element information from firmware\n+ *\n+ * This function inserts a scheduler node to the SW DB.\n+ */\n+enum ice_status\n+ice_sched_add_node(struct ice_port_info *pi, u8 layer,\n+\t\t   struct ice_aqc_txsched_elem_data *info)\n+{\n+\tstruct ice_sched_node *parent;\n+\tstruct ice_sched_node *node;\n+\tstruct ice_hw *hw;\n+\tu16 max_children;\n+\n+\tif (!pi)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\thw = pi->hw;\n+\n+\t/* A valid parent node should be there */\n+\tparent = ice_sched_find_node_by_teid(pi->root,\n+\t\t\t\t\t     le32_to_cpu(info->parent_teid));\n+\tif (!parent) {\n+\t\tice_debug(hw, ICE_DBG_SCHED,\n+\t\t\t  \"Parent Node not found for parent_teid=0x%x\\n\",\n+\t\t\t  le32_to_cpu(info->parent_teid));\n+\t\treturn ICE_ERR_PARAM;\n+\t}\n+\n+\tnode = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL);\n+\tif (!node)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\tmax_children = le16_to_cpu(hw->layer_info[layer].max_children);\n+\tif (max_children) {\n+\t\tnode->children = devm_kcalloc(ice_hw_to_dev(hw), max_children,\n+\t\t\t\t\t      sizeof(*node), GFP_KERNEL);\n+\t\tif (!node->children) {\n+\t\t\tdevm_kfree(ice_hw_to_dev(hw), node);\n+\t\t\treturn ICE_ERR_NO_MEMORY;\n+\t\t}\n+\t}\n+\n+\tnode->in_use = true;\n+\tnode->parent = parent;\n+\tnode->tx_sched_layer = layer;\n+\tparent->children[parent->num_children++] = node;\n+\tmemcpy(&node->info, info, sizeof(*info));\n+\treturn 0;\n+}\n+\n /**\n  * ice_aq_delete_sched_elems - delete scheduler elements\n  * @hw: pointer to the hw struct\n@@ -208,6 +343,36 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)\n \tdevm_kfree(ice_hw_to_dev(hw), node);\n }\n \n+/**\n+ * ice_aq_get_dflt_topo - gets default scheduler topology\n+ * @hw: pointer to the hw struct\n+ * @lport: logical port number\n+ * @buf: pointer to buffer\n+ * @buf_size: buffer size in bytes\n+ * @num_branches: returns total number of queue to port branches\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Get default scheduler topology (0x400)\n+ */\n+static enum ice_status\n+ice_aq_get_dflt_topo(struct ice_hw *hw, u8 lport,\n+\t\t     struct ice_aqc_get_topo_elem *buf, u16 buf_size,\n+\t\t     u8 *num_branches, struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_get_topo *cmd;\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\n+\tcmd = &desc.params.get_topo;\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_dflt_topo);\n+\tcmd->port_num = lport;\n+\tstatus = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);\n+\tif (!status && num_branches)\n+\t\t*num_branches = cmd->num_branches;\n+\n+\treturn status;\n+}\n+\n /**\n  * ice_aq_query_sched_res - query scheduler resource\n  * @hw: pointer to the hw struct\n@@ -311,6 +476,169 @@ void ice_sched_cleanup_all(struct ice_hw *hw)\n \thw->max_cgds = 0;\n }\n \n+/**\n+ * ice_rm_dflt_leaf_node - remove the default leaf node in the tree\n+ * @pi: port information structure\n+ *\n+ * This function removes the leaf node that was created by the FW\n+ * during initialization\n+ */\n+static void\n+ice_rm_dflt_leaf_node(struct ice_port_info *pi)\n+{\n+\tstruct ice_sched_node *node;\n+\n+\tnode = pi->root;\n+\twhile (node) {\n+\t\tif (!node->num_children)\n+\t\t\tbreak;\n+\t\tnode = node->children[0];\n+\t}\n+\tif (node && node->info.data.elem_type == ICE_AQC_ELEM_TYPE_LEAF) {\n+\t\tu32 teid = le32_to_cpu(node->info.node_teid);\n+\t\tenum ice_status status;\n+\n+\t\t/* remove the default leaf node */\n+\t\tstatus = ice_sched_remove_elems(pi->hw, node->parent, 1, &teid);\n+\t\tif (!status)\n+\t\t\tice_free_sched_node(pi, node);\n+\t}\n+}\n+\n+/**\n+ * ice_sched_rm_dflt_nodes - free the default nodes in the tree\n+ * @pi: port information structure\n+ *\n+ * This function frees all the nodes except root and TC that were created by\n+ * the FW during initialization\n+ */\n+static void\n+ice_sched_rm_dflt_nodes(struct ice_port_info *pi)\n+{\n+\tstruct ice_sched_node *node;\n+\n+\tice_rm_dflt_leaf_node(pi);\n+\t/* remove the default nodes except TC and root nodes */\n+\tnode = pi->root;\n+\twhile (node) {\n+\t\tif (node->tx_sched_layer >= pi->hw->sw_entry_point_layer &&\n+\t\t    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_TC &&\n+\t\t    node->info.data.elem_type != ICE_AQC_ELEM_TYPE_ROOT_PORT) {\n+\t\t\tice_free_sched_node(pi, node);\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (!node->num_children)\n+\t\t\tbreak;\n+\t\tnode = node->children[0];\n+\t}\n+}\n+\n+/**\n+ * ice_sched_init_port - Initialize scheduler by querying information from FW\n+ * @pi: port info structure for the tree to cleanup\n+ *\n+ * This function is the initial call to find the total number of Tx scheduler\n+ * resources, default topology created by firmware and storing the information\n+ * in SW DB.\n+ */\n+enum ice_status ice_sched_init_port(struct ice_port_info *pi)\n+{\n+\tstruct ice_aqc_get_topo_elem *buf;\n+\tenum ice_status status;\n+\tstruct ice_hw *hw;\n+\tu8 num_branches;\n+\tu16 num_elems;\n+\tu8 i, j;\n+\n+\tif (!pi)\n+\t\treturn ICE_ERR_PARAM;\n+\thw = pi->hw;\n+\n+\t/* Query the Default Topology from FW */\n+\tbuf = devm_kcalloc(ice_hw_to_dev(hw), ICE_TXSCHED_MAX_BRANCHES,\n+\t\t\t   sizeof(*buf), GFP_KERNEL);\n+\tif (!buf)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\t/* Query default scheduling tree topology */\n+\tstatus = ice_aq_get_dflt_topo(hw, pi->lport, buf,\n+\t\t\t\t      sizeof(*buf) * ICE_TXSCHED_MAX_BRANCHES,\n+\t\t\t\t      &num_branches, NULL);\n+\tif (status)\n+\t\tgoto err_init_port;\n+\n+\t/* num_branches should be between 1-8 */\n+\tif (num_branches < 1 || num_branches > ICE_TXSCHED_MAX_BRANCHES) {\n+\t\tice_debug(hw, ICE_DBG_SCHED, \"num_branches unexpected %d\\n\",\n+\t\t\t  num_branches);\n+\t\tstatus = ICE_ERR_PARAM;\n+\t\tgoto err_init_port;\n+\t}\n+\n+\t/* get the number of elements on the default/first branch */\n+\tnum_elems = le16_to_cpu(buf[0].hdr.num_elems);\n+\n+\t/* num_elems should always be between 1-9 */\n+\tif (num_elems < 1 || num_elems > ICE_AQC_TOPO_MAX_LEVEL_NUM) {\n+\t\tice_debug(hw, ICE_DBG_SCHED, \"num_elems unexpected %d\\n\",\n+\t\t\t  num_elems);\n+\t\tstatus = ICE_ERR_PARAM;\n+\t\tgoto err_init_port;\n+\t}\n+\n+\t/* If the last node is a leaf node then the index of the Q group\n+\t * layer is two less than the number of elements.\n+\t */\n+\tif (num_elems > 2 && buf[0].generic[num_elems - 1].data.elem_type ==\n+\t    ICE_AQC_ELEM_TYPE_LEAF)\n+\t\tpi->last_node_teid =\n+\t\t\tle32_to_cpu(buf[0].generic[num_elems - 2].node_teid);\n+\telse\n+\t\tpi->last_node_teid =\n+\t\t\tle32_to_cpu(buf[0].generic[num_elems - 1].node_teid);\n+\n+\t/* Insert the Tx Sched root node */\n+\tstatus = ice_sched_add_root_node(pi, &buf[0].generic[0]);\n+\tif (status)\n+\t\tgoto err_init_port;\n+\n+\t/* Parse the default tree and cache the information */\n+\tfor (i = 0; i < num_branches; i++) {\n+\t\tnum_elems = le16_to_cpu(buf[i].hdr.num_elems);\n+\n+\t\t/* Skip root element as already inserted */\n+\t\tfor (j = 1; j < num_elems; j++) {\n+\t\t\t/* update the sw entry point */\n+\t\t\tif (buf[0].generic[j].data.elem_type ==\n+\t\t\t    ICE_AQC_ELEM_TYPE_ENTRY_POINT)\n+\t\t\t\thw->sw_entry_point_layer = j;\n+\n+\t\t\tstatus = ice_sched_add_node(pi, j, &buf[i].generic[j]);\n+\t\t\tif (status)\n+\t\t\t\tgoto err_init_port;\n+\t\t}\n+\t}\n+\n+\t/* Remove the default nodes. */\n+\tif (pi->root)\n+\t\tice_sched_rm_dflt_nodes(pi);\n+\n+\t/* initialize the port for handling the scheduler tree */\n+\tpi->port_state = ICE_SCHED_PORT_STATE_READY;\n+\tmutex_init(&pi->sched_lock);\n+\tINIT_LIST_HEAD(&pi->agg_list);\n+\tINIT_LIST_HEAD(&pi->vsi_info_list);\n+\n+err_init_port:\n+\tif (status && pi->root) {\n+\t\tice_free_sched_node(pi, pi->root);\n+\t\tpi->root = NULL;\n+\t}\n+\n+\tdevm_kfree(ice_hw_to_dev(hw), buf);\n+\treturn status;\n+}\n+\n /**\n  * ice_sched_query_res_alloc - query the FW for num of logical sched layers\n  * @hw: pointer to the HW struct\ndiff --git a/drivers/net/ethernet/intel/ice/ice_sched.h b/drivers/net/ethernet/intel/ice/ice_sched.h\nindex fb93acf340ed..6a9c0ae4220d 100644\n--- a/drivers/net/ethernet/intel/ice/ice_sched.h\n+++ b/drivers/net/ethernet/intel/ice/ice_sched.h\n@@ -35,8 +35,14 @@ struct ice_sched_agg_info {\n };\n \n /* FW AQ command calls */\n+enum ice_status ice_sched_init_port(struct ice_port_info *pi);\n enum ice_status ice_sched_query_res_alloc(struct ice_hw *hw);\n void ice_sched_cleanup_all(struct ice_hw *hw);\n+struct ice_sched_node *\n+ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid);\n+enum ice_status\n+ice_sched_add_node(struct ice_port_info *pi, u8 layer,\n+\t\t   struct ice_aqc_txsched_elem_data *info);\n void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node);\n struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc);\n #endif /* _ICE_SCHED_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_status.h b/drivers/net/ethernet/intel/ice/ice_status.h\nindex 1fb6eb8301cf..47ab8c4d1c96 100644\n--- a/drivers/net/ethernet/intel/ice/ice_status.h\n+++ b/drivers/net/ethernet/intel/ice/ice_status.h\n@@ -29,6 +29,7 @@ enum ice_status {\n \tICE_ERR_NO_MEMORY\t\t\t= -11,\n \tICE_ERR_CFG\t\t\t\t= -12,\n \tICE_ERR_OUT_OF_RANGE\t\t\t= -13,\n+\tICE_ERR_BUF_TOO_SHORT\t\t\t= -52,\n \tICE_ERR_NVM_BLANK_MODE\t\t\t= -53,\n \tICE_ERR_AQ_ERROR\t\t\t= -100,\n \tICE_ERR_AQ_TIMEOUT\t\t\t= -101,\ndiff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h\nindex 69a8c1a5ce84..cb9104ca969d 100644\n--- a/drivers/net/ethernet/intel/ice/ice_type.h\n+++ b/drivers/net/ethernet/intel/ice/ice_type.h\n@@ -26,6 +26,7 @@\n /* debug masks - set these bits in hw->debug_mask to control output */\n #define ICE_DBG_INIT\t\tBIT_ULL(1)\n #define ICE_DBG_NVM\t\tBIT_ULL(7)\n+#define ICE_DBG_LAN\t\tBIT_ULL(8)\n #define ICE_DBG_SW\t\tBIT_ULL(13)\n #define ICE_DBG_SCHED\t\tBIT_ULL(14)\n #define ICE_DBG_RES\t\tBIT_ULL(17)\n@@ -44,12 +45,56 @@ enum ice_aq_res_access_type {\n \tICE_RES_WRITE\n };\n \n+enum ice_fc_mode {\n+\tICE_FC_NONE = 0,\n+\tICE_FC_RX_PAUSE,\n+\tICE_FC_TX_PAUSE,\n+\tICE_FC_FULL,\n+\tICE_FC_PFC,\n+\tICE_FC_DFLT\n+};\n+\n /* Various MAC types */\n enum ice_mac_type {\n \tICE_MAC_UNKNOWN = 0,\n \tICE_MAC_GENERIC,\n };\n \n+/* Media Types */\n+enum ice_media_type {\n+\tICE_MEDIA_UNKNOWN = 0,\n+\tICE_MEDIA_FIBER,\n+\tICE_MEDIA_BASET,\n+\tICE_MEDIA_BACKPLANE,\n+\tICE_MEDIA_DA,\n+};\n+\n+struct ice_link_status {\n+\t/* Refer to ice_aq_phy_type for bits definition */\n+\tu64 phy_type_low;\n+\tu16 max_frame_size;\n+\tu16 link_speed;\n+\tbool lse_ena;\t/* Link Status Event notification */\n+\tu8 link_info;\n+\tu8 an_info;\n+\tu8 ext_info;\n+\tu8 pacing;\n+\tu8 req_speeds;\n+\t/* Refer to #define from module_type[ICE_MODULE_TYPE_TOTAL_BYTE] of\n+\t * ice_aqc_get_phy_caps structure\n+\t */\n+\tu8 module_type[ICE_MODULE_TYPE_TOTAL_BYTE];\n+};\n+\n+/* PHY info such as phy_type, etc... */\n+struct ice_phy_info {\n+\tstruct ice_link_status link_info;\n+\tstruct ice_link_status link_info_old;\n+\tu64 phy_type_low;\n+\tenum ice_media_type media_type;\n+\tbool get_link_info;\n+};\n+\n /* Common HW capabilities for SW use */\n struct ice_hw_common_caps {\n \t/* TX/RX queues */\n@@ -82,6 +127,12 @@ struct ice_hw_dev_caps {\n \tu32 num_vsi_allocd_to_host;\t/* Excluding EMP VSI */\n };\n \n+/* MAC info */\n+struct ice_mac_info {\n+\tu8 lan_addr[ETH_ALEN];\n+\tu8 perm_addr[ETH_ALEN];\n+};\n+\n /* Various RESET request, These are not tied with HW reset types */\n enum ice_reset_req {\n \tICE_RESET_PFR\t= 0,\n@@ -95,6 +146,12 @@ struct ice_bus_info {\n \tu8 func;\n };\n \n+/* Flow control (FC) parameters */\n+struct ice_fc_info {\n+\tenum ice_fc_mode current_mode;\t/* FC mode in effect */\n+\tenum ice_fc_mode req_mode;\t/* FC mode requested by caller */\n+};\n+\n /* NVM Information */\n struct ice_nvm_info {\n \tu32 eetrack;              /* NVM data version */\n@@ -106,6 +163,7 @@ struct ice_nvm_info {\n \n /* Max number of port to queue branches w.r.t topology */\n #define ICE_MAX_TRAFFIC_CLASS 8\n+#define ICE_TXSCHED_MAX_BRANCHES ICE_MAX_TRAFFIC_CLASS\n \n struct ice_sched_node {\n \tstruct ice_sched_node *parent;\n@@ -122,6 +180,9 @@ struct ice_sched_node {\n #define ICE_SCHED_NODE_OWNER_LAN\t0\n };\n \n+/* Access Macros for Tx Sched Elements data */\n+#define ICE_TXSCHED_GET_NODE_TEID(x) le32_to_cpu((x)->info.node_teid)\n+\n /* The aggregator type determines if identifier is for a VSI group,\n  * aggregator group, aggregator of queues, or queue group.\n  */\n@@ -152,6 +213,7 @@ struct ice_sched_tx_policy {\n struct ice_port_info {\n \tstruct ice_sched_node *root;\t/* Root Node per Port */\n \tstruct ice_hw *hw;\t\t/* back pointer to hw instance */\n+\tu32 last_node_teid;\t\t/* scheduler last node info */\n \tu16 sw_id;\t\t\t/* Initial switch ID belongs to port */\n \tu16 pf_vf_num;\n \tu8 port_state;\n@@ -159,6 +221,9 @@ struct ice_port_info {\n #define ICE_SCHED_PORT_STATE_READY\t0x1\n \tu16 dflt_tx_vsi_num;\n \tu16 dflt_rx_vsi_num;\n+\tstruct ice_fc_info fc;\n+\tstruct ice_mac_info mac;\n+\tstruct ice_phy_info phy;\n \tstruct mutex sched_lock;\t/* protect access to TXSched tree */\n \tstruct ice_sched_tx_policy sched_policy;\n \tstruct list_head vsi_info_list;\n",
    "prefixes": [
        "v2",
        "05/15"
    ]
}