Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1049841/?format=api
{ "id": 1049841, "url": "http://patchwork.ozlabs.org/api/patches/1049841/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20190228232432.31659-3-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": "<20190228232432.31659-3-anirudh.venkataramanan@intel.com>", "list_archive_url": null, "date": "2019-02-28T23:24:23", "name": "[S16,02/11] ice: Add code for DCB initialization part 2/4", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "3077cc490424d4f3f667537ea2a8489263369eac", "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/20190228232432.31659-3-anirudh.venkataramanan@intel.com/mbox/", "series": [ { "id": 94826, "url": "http://patchwork.ozlabs.org/api/series/94826/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=94826", "date": "2019-02-28T23:24:25", "name": "Add support for Data Center Bridging (DCB)", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/94826/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1049841/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1049841/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.138; helo=whitealder.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=intel.com" ], "Received": [ "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 449TD32JXzz9s70\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 1 Mar 2019 10:24:51 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 9DF0B86416;\n\tThu, 28 Feb 2019 23:24:49 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id 7uCJaPO58X+c; Thu, 28 Feb 2019 23:24:43 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 5A6BE86A4F;\n\tThu, 28 Feb 2019 23:24:41 +0000 (UTC)", "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id BD0221BF410\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 28 Feb 2019 23:24:37 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id BAB5687A2F\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 28 Feb 2019 23:24:37 +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 ubUDM6pry-WF for <intel-wired-lan@lists.osuosl.org>;\n\tThu, 28 Feb 2019 23:24:34 +0000 (UTC)", "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id 92019877E4\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tThu, 28 Feb 2019 23:24:34 +0000 (UTC)", "from fmsmga003.fm.intel.com ([10.253.24.29])\n\tby orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t28 Feb 2019 15:24:33 -0800", "from shasta.jf.intel.com ([10.166.241.11])\n\tby FMSMGA003.fm.intel.com with ESMTP; 28 Feb 2019 15:24:33 -0800" ], "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.58,425,1544515200\"; d=\"scan'208\";a=\"137127718\"", "From": "Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>", "To": "intel-wired-lan@lists.osuosl.org", "Date": "Thu, 28 Feb 2019 15:24:23 -0800", "Message-Id": "<20190228232432.31659-3-anirudh.venkataramanan@intel.com>", "X-Mailer": "git-send-email 2.14.5", "In-Reply-To": "<20190228232432.31659-1-anirudh.venkataramanan@intel.com>", "References": "<20190228232432.31659-1-anirudh.venkataramanan@intel.com>", "Subject": "[Intel-wired-lan] [PATCH S16 02/11] ice: Add code for DCB\n\tinitialization part 2/4", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.29", "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": "This patch introduces a new top level function ice_init_dcb (and\nrelated lower level helper functions) which continues the DCB init\nflow.\n\nThis function uses ice_get_dcb_cfg to get, parse and store the DCB\nconfiguration. Once this is done, it sets itself up to be notified\nby the firmware on LLDP MIB change events.\n\nReviewed-by: Bruce Allan <bruce.w.allan@intel.com>\nSigned-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>\n---\n drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | 79 +++\n drivers/net/ethernet/intel/ice/ice_dcb.c | 819 ++++++++++++++++++++++++\n drivers/net/ethernet/intel/ice/ice_dcb.h | 99 +++\n drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 2 +-\n drivers/net/ethernet/intel/ice/ice_status.h | 1 +\n drivers/net/ethernet/intel/ice/ice_type.h | 58 ++\n 6 files changed, 1057 insertions(+), 1 deletion(-)", "diff": "diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\nindex 4809e5ac55f4..bbceaca11541 100644\n--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\n+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h\n@@ -1132,6 +1132,48 @@ struct ice_aqc_pf_vf_msg {\n \t__le32 addr_low;\n };\n \n+/* Get LLDP MIB (indirect 0x0A00)\n+ * Note: This is also used by the LLDP MIB Change Event (0x0A01)\n+ * as the format is the same.\n+ */\n+struct ice_aqc_lldp_get_mib {\n+\tu8 type;\n+#define ICE_AQ_LLDP_MIB_TYPE_S\t\t\t0\n+#define ICE_AQ_LLDP_MIB_TYPE_M\t\t\t(0x3 << ICE_AQ_LLDP_MIB_TYPE_S)\n+#define ICE_AQ_LLDP_MIB_LOCAL\t\t\t0\n+#define ICE_AQ_LLDP_MIB_REMOTE\t\t\t1\n+#define ICE_AQ_LLDP_MIB_LOCAL_AND_REMOTE\t2\n+#define ICE_AQ_LLDP_BRID_TYPE_S\t\t\t2\n+#define ICE_AQ_LLDP_BRID_TYPE_M\t\t\t(0x3 << ICE_AQ_LLDP_BRID_TYPE_S)\n+#define ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID\t0\n+#define ICE_AQ_LLDP_BRID_TYPE_NON_TPMR\t\t1\n+/* Tx pause flags in the 0xA01 event use ICE_AQ_LLDP_TX_* */\n+#define ICE_AQ_LLDP_TX_S\t\t\t0x4\n+#define ICE_AQ_LLDP_TX_M\t\t\t(0x03 << ICE_AQ_LLDP_TX_S)\n+#define ICE_AQ_LLDP_TX_ACTIVE\t\t\t0\n+#define ICE_AQ_LLDP_TX_SUSPENDED\t\t1\n+#define ICE_AQ_LLDP_TX_FLUSHED\t\t\t3\n+/* The following bytes are reserved for the Get LLDP MIB command (0x0A00)\n+ * and in the LLDP MIB Change Event (0x0A01). They are valid for the\n+ * Get LLDP MIB (0x0A00) response only.\n+ */\n+\tu8 reserved1;\n+\t__le16 local_len;\n+\t__le16 remote_len;\n+\tu8 reserved2[2];\n+\t__le32 addr_high;\n+\t__le32 addr_low;\n+};\n+\n+/* Configure LLDP MIB Change Event (direct 0x0A01) */\n+/* For MIB Change Event use ice_aqc_lldp_get_mib structure above */\n+struct ice_aqc_lldp_set_mib_change {\n+\tu8 command;\n+#define ICE_AQ_LLDP_MIB_UPDATE_ENABLE\t\t0x0\n+#define ICE_AQ_LLDP_MIB_UPDATE_DIS\t\t0x1\n+\tu8 reserved[15];\n+};\n+\n /* Start LLDP (direct 0x0A06) */\n struct ice_aqc_lldp_start {\n \tu8 command;\n@@ -1140,6 +1182,36 @@ struct ice_aqc_lldp_start {\n \tu8 reserved[15];\n };\n \n+/* Get CEE DCBX Oper Config (0x0A07)\n+ * The command uses the generic descriptor struct and\n+ * returns the struct below as an indirect response.\n+ */\n+struct ice_aqc_get_cee_dcb_cfg_resp {\n+\tu8 oper_num_tc;\n+\tu8 oper_prio_tc[4];\n+\tu8 oper_tc_bw[8];\n+\tu8 oper_pfc_en;\n+\t__le16 oper_app_prio;\n+#define ICE_AQC_CEE_APP_FCOE_S\t\t0\n+#define ICE_AQC_CEE_APP_FCOE_M\t\t(0x7 << ICE_AQC_CEE_APP_FCOE_S)\n+#define ICE_AQC_CEE_APP_ISCSI_S\t\t3\n+#define ICE_AQC_CEE_APP_ISCSI_M\t\t(0x7 << ICE_AQC_CEE_APP_ISCSI_S)\n+#define ICE_AQC_CEE_APP_FIP_S\t\t8\n+#define ICE_AQC_CEE_APP_FIP_M\t\t(0x7 << ICE_AQC_CEE_APP_FIP_S)\n+\t__le32 tlv_status;\n+#define ICE_AQC_CEE_PG_STATUS_S\t\t0\n+#define ICE_AQC_CEE_PG_STATUS_M\t\t(0x7 << ICE_AQC_CEE_PG_STATUS_S)\n+#define ICE_AQC_CEE_PFC_STATUS_S\t3\n+#define ICE_AQC_CEE_PFC_STATUS_M\t(0x7 << ICE_AQC_CEE_PFC_STATUS_S)\n+#define ICE_AQC_CEE_FCOE_STATUS_S\t8\n+#define ICE_AQC_CEE_FCOE_STATUS_M\t(0x7 << ICE_AQC_CEE_FCOE_STATUS_S)\n+#define ICE_AQC_CEE_ISCSI_STATUS_S\t11\n+#define ICE_AQC_CEE_ISCSI_STATUS_M\t(0x7 << ICE_AQC_CEE_ISCSI_STATUS_S)\n+#define ICE_AQC_CEE_FIP_STATUS_S\t16\n+#define ICE_AQC_CEE_FIP_STATUS_M\t(0x7 << ICE_AQC_CEE_FIP_STATUS_S)\n+\tu8 reserved[12];\n+};\n+\n /* Stop/Start LLDP Agent (direct 0x0A09)\n * Used for stopping/starting specific LLDP agent. e.g. DCBx.\n * The same structure is used for the response, with the command field\n@@ -1411,6 +1483,8 @@ struct ice_aq_desc {\n \t\tstruct ice_aqc_query_txsched_res query_sched_res;\n \t\tstruct ice_aqc_nvm nvm;\n \t\tstruct ice_aqc_pf_vf_msg virt;\n+\t\tstruct ice_aqc_lldp_get_mib lldp_get_mib;\n+\t\tstruct ice_aqc_lldp_set_mib_change lldp_set_event;\n \t\tstruct ice_aqc_lldp_start lldp_start;\n \t\tstruct ice_aqc_lldp_stop_start_specific_agent lldp_agent_ctrl;\n \t\tstruct ice_aqc_get_set_rss_lut get_set_rss_lut;\n@@ -1445,6 +1519,8 @@ struct ice_aq_desc {\n /* error codes */\n enum ice_aq_err {\n \tICE_AQ_RC_OK\t\t= 0, /* Success */\n+\tICE_AQ_RC_EPERM\t\t= 1, /* Operation not permitted */\n+\tICE_AQ_RC_ENOENT\t= 2, /* No such element */\n \tICE_AQ_RC_ENOMEM\t= 9, /* Out of memory */\n \tICE_AQ_RC_EBUSY\t\t= 12, /* Device or resource busy */\n \tICE_AQ_RC_EEXIST\t= 13, /* Object already exists */\n@@ -1515,7 +1591,10 @@ enum ice_adminq_opc {\n \tice_mbx_opc_send_msg_to_pf\t\t\t= 0x0801,\n \tice_mbx_opc_send_msg_to_vf\t\t\t= 0x0802,\n \t/* LLDP commands */\n+\tice_aqc_opc_lldp_get_mib\t\t\t= 0x0A00,\n+\tice_aqc_opc_lldp_set_mib_change\t\t\t= 0x0A01,\n \tice_aqc_opc_lldp_start\t\t\t\t= 0x0A06,\n+\tice_aqc_opc_get_cee_dcb_cfg\t\t\t= 0x0A07,\n \tice_aqc_opc_lldp_stop_start_specific_agent\t= 0x0A09,\n \n \t/* RSS commands */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_dcb.c b/drivers/net/ethernet/intel/ice/ice_dcb.c\nindex 19ab7433e330..b59c145fb958 100644\n--- a/drivers/net/ethernet/intel/ice/ice_dcb.c\n+++ b/drivers/net/ethernet/intel/ice/ice_dcb.c\n@@ -5,6 +5,78 @@\n #include \"ice_sched.h\"\n #include \"ice_dcb.h\"\n \n+/**\n+ * ice_aq_get_lldp_mib\n+ * @hw: pointer to the HW struct\n+ * @bridge_type: type of bridge requested\n+ * @mib_type: Local, Remote or both Local and Remote MIBs\n+ * @buf: pointer to the caller-supplied buffer to store the MIB block\n+ * @buf_size: size of the buffer (in bytes)\n+ * @local_len: length of the returned Local LLDP MIB\n+ * @remote_len: length of the returned Remote LLDP MIB\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Requests the complete LLDP MIB (entire packet). (0x0A00)\n+ */\n+static enum ice_status\n+ice_aq_get_lldp_mib(struct ice_hw *hw, u8 bridge_type, u8 mib_type, void *buf,\n+\t\t u16 buf_size, u16 *local_len, u16 *remote_len,\n+\t\t struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_lldp_get_mib *cmd;\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\n+\tcmd = &desc.params.lldp_get_mib;\n+\n+\tif (buf_size == 0 || !buf)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_get_mib);\n+\n+\tcmd->type = mib_type & ICE_AQ_LLDP_MIB_TYPE_M;\n+\tcmd->type |= (bridge_type << ICE_AQ_LLDP_BRID_TYPE_S) &\n+\t\tICE_AQ_LLDP_BRID_TYPE_M;\n+\n+\tdesc.datalen = cpu_to_le16(buf_size);\n+\n+\tstatus = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);\n+\tif (!status) {\n+\t\tif (local_len)\n+\t\t\t*local_len = le16_to_cpu(cmd->local_len);\n+\t\tif (remote_len)\n+\t\t\t*remote_len = le16_to_cpu(cmd->remote_len);\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ice_aq_cfg_lldp_mib_change\n+ * @hw: pointer to the HW struct\n+ * @ena_update: Enable or Disable event posting\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Enable or Disable posting of an event on ARQ when LLDP MIB\n+ * associated with the interface changes (0x0A01)\n+ */\n+static enum ice_status\n+ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update,\n+\t\t\t struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_lldp_set_mib_change *cmd;\n+\tstruct ice_aq_desc desc;\n+\n+\tcmd = &desc.params.lldp_set_event;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_mib_change);\n+\n+\tif (!ena_update)\n+\t\tcmd->command |= ICE_AQ_LLDP_MIB_UPDATE_DIS;\n+\n+\treturn ice_aq_send_cmd(hw, &desc, NULL, 0, cd);\n+}\n+\n /**\n * ice_aq_start_lldp\n * @hw: pointer to the HW struct\n@@ -41,6 +113,523 @@ u8 ice_get_dcbx_status(struct ice_hw *hw)\n \t\t PRTDCB_GENS_DCBX_STATUS_S);\n }\n \n+/**\n+ * ice_parse_ieee_ets_common_tlv\n+ * @buf: Data buffer to be parsed for ETS CFG/REC data\n+ * @ets_cfg: Container to store parsed data\n+ *\n+ * Parses the common data of IEEE 802.1Qaz ETS CFG/REC TLV\n+ */\n+static void\n+ice_parse_ieee_ets_common_tlv(u8 *buf, struct ice_dcb_ets_cfg *ets_cfg)\n+{\n+\tu8 offset = 0;\n+\tint i;\n+\n+\t/* Priority Assignment Table (4 octets)\n+\t * Octets:| 1 | 2 | 3 | 4 |\n+\t * -----------------------------------------\n+\t * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|\n+\t * -----------------------------------------\n+\t * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|\n+\t * -----------------------------------------\n+\t */\n+\tfor (i = 0; i < 4; i++) {\n+\t\tets_cfg->prio_table[i * 2] =\n+\t\t\t((buf[offset] & ICE_IEEE_ETS_PRIO_1_M) >>\n+\t\t\t ICE_IEEE_ETS_PRIO_1_S);\n+\t\tets_cfg->prio_table[i * 2 + 1] =\n+\t\t\t((buf[offset] & ICE_IEEE_ETS_PRIO_0_M) >>\n+\t\t\t ICE_IEEE_ETS_PRIO_0_S);\n+\t\toffset++;\n+\t}\n+\n+\t/* TC Bandwidth Table (8 octets)\n+\t * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |\n+\t * ---------------------------------\n+\t * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|\n+\t * ---------------------------------\n+\t *\n+\t * TSA Assignment Table (8 octets)\n+\t * Octets:| 9 | 10| 11| 12| 13| 14| 15| 16|\n+\t * ---------------------------------\n+\t * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|\n+\t * ---------------------------------\n+\t */\n+\tice_for_each_traffic_class(i) {\n+\t\tets_cfg->tcbwtable[i] = buf[offset];\n+\t\tets_cfg->tsatable[i] = buf[ICE_MAX_TRAFFIC_CLASS + offset++];\n+\t}\n+}\n+\n+/**\n+ * ice_parse_ieee_etscfg_tlv\n+ * @tlv: IEEE 802.1Qaz ETS CFG TLV\n+ * @dcbcfg: Local store to update ETS CFG data\n+ *\n+ * Parses IEEE 802.1Qaz ETS CFG TLV\n+ */\n+static void\n+ice_parse_ieee_etscfg_tlv(struct ice_lldp_org_tlv *tlv,\n+\t\t\t struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tstruct ice_dcb_ets_cfg *etscfg;\n+\tu8 *buf = tlv->tlvinfo;\n+\n+\t/* First Octet post subtype\n+\t * --------------------------\n+\t * |will-|CBS | Re- | Max |\n+\t * |ing | |served| TCs |\n+\t * --------------------------\n+\t * |1bit | 1bit|3 bits|3bits|\n+\t */\n+\tetscfg = &dcbcfg->etscfg;\n+\tetscfg->willing = ((buf[0] & ICE_IEEE_ETS_WILLING_M) >>\n+\t\t\t ICE_IEEE_ETS_WILLING_S);\n+\tetscfg->cbs = ((buf[0] & ICE_IEEE_ETS_CBS_M) >> ICE_IEEE_ETS_CBS_S);\n+\tetscfg->maxtcs = ((buf[0] & ICE_IEEE_ETS_MAXTC_M) >>\n+\t\t\t ICE_IEEE_ETS_MAXTC_S);\n+\n+\t/* Begin parsing at Priority Assignment Table (offset 1 in buf) */\n+\tice_parse_ieee_ets_common_tlv(&buf[1], etscfg);\n+}\n+\n+/**\n+ * ice_parse_ieee_etsrec_tlv\n+ * @tlv: IEEE 802.1Qaz ETS REC TLV\n+ * @dcbcfg: Local store to update ETS REC data\n+ *\n+ * Parses IEEE 802.1Qaz ETS REC TLV\n+ */\n+static void\n+ice_parse_ieee_etsrec_tlv(struct ice_lldp_org_tlv *tlv,\n+\t\t\t struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tu8 *buf = tlv->tlvinfo;\n+\n+\t/* Begin parsing at Priority Assignment Table (offset 1 in buf) */\n+\tice_parse_ieee_ets_common_tlv(&buf[1], &dcbcfg->etsrec);\n+}\n+\n+/**\n+ * ice_parse_ieee_pfccfg_tlv\n+ * @tlv: IEEE 802.1Qaz PFC CFG TLV\n+ * @dcbcfg: Local store to update PFC CFG data\n+ *\n+ * Parses IEEE 802.1Qaz PFC CFG TLV\n+ */\n+static void\n+ice_parse_ieee_pfccfg_tlv(struct ice_lldp_org_tlv *tlv,\n+\t\t\t struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tu8 *buf = tlv->tlvinfo;\n+\n+\t/* ----------------------------------------\n+\t * |will-|MBC | Re- | PFC | PFC Enable |\n+\t * |ing | |served| cap | |\n+\t * -----------------------------------------\n+\t * |1bit | 1bit|2 bits|4bits| 1 octet |\n+\t */\n+\tdcbcfg->pfc.willing = ((buf[0] & ICE_IEEE_PFC_WILLING_M) >>\n+\t\t\t ICE_IEEE_PFC_WILLING_S);\n+\tdcbcfg->pfc.mbc = ((buf[0] & ICE_IEEE_PFC_MBC_M) >> ICE_IEEE_PFC_MBC_S);\n+\tdcbcfg->pfc.pfccap = ((buf[0] & ICE_IEEE_PFC_CAP_M) >>\n+\t\t\t ICE_IEEE_PFC_CAP_S);\n+\tdcbcfg->pfc.pfcena = buf[1];\n+}\n+\n+/**\n+ * ice_parse_ieee_app_tlv\n+ * @tlv: IEEE 802.1Qaz APP TLV\n+ * @dcbcfg: Local store to update APP PRIO data\n+ *\n+ * Parses IEEE 802.1Qaz APP PRIO TLV\n+ */\n+static void\n+ice_parse_ieee_app_tlv(struct ice_lldp_org_tlv *tlv,\n+\t\t struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tu16 offset = 0;\n+\tu16 typelen;\n+\tint i = 0;\n+\tu16 len;\n+\tu8 *buf;\n+\n+\ttypelen = ntohs(tlv->typelen);\n+\tlen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);\n+\tbuf = tlv->tlvinfo;\n+\n+\t/* Removing sizeof(ouisubtype) and reserved byte from len.\n+\t * Remaining len div 3 is number of APP TLVs.\n+\t */\n+\tlen -= (sizeof(tlv->ouisubtype) + 1);\n+\n+\t/* Move offset to App Priority Table */\n+\toffset++;\n+\n+\t/* Application Priority Table (3 octets)\n+\t * Octets:| 1 | 2 | 3 |\n+\t * -----------------------------------------\n+\t * |Priority|Rsrvd| Sel | Protocol ID |\n+\t * -----------------------------------------\n+\t * Bits:|23 21|20 19|18 16|15 0|\n+\t * -----------------------------------------\n+\t */\n+\twhile (offset < len) {\n+\t\tdcbcfg->app[i].priority = ((buf[offset] &\n+\t\t\t\t\t ICE_IEEE_APP_PRIO_M) >>\n+\t\t\t\t\t ICE_IEEE_APP_PRIO_S);\n+\t\tdcbcfg->app[i].selector = ((buf[offset] &\n+\t\t\t\t\t ICE_IEEE_APP_SEL_M) >>\n+\t\t\t\t\t ICE_IEEE_APP_SEL_S);\n+\t\tdcbcfg->app[i].prot_id = (buf[offset + 1] << 0x8) |\n+\t\t\tbuf[offset + 2];\n+\t\t/* Move to next app */\n+\t\toffset += 3;\n+\t\ti++;\n+\t\tif (i >= ICE_DCBX_MAX_APPS)\n+\t\t\tbreak;\n+\t}\n+\n+\tdcbcfg->numapps = i;\n+}\n+\n+/**\n+ * ice_parse_ieee_tlv\n+ * @tlv: IEEE 802.1Qaz TLV\n+ * @dcbcfg: Local store to update ETS REC data\n+ *\n+ * Get the TLV subtype and send it to parsing function\n+ * based on the subtype value\n+ */\n+static void\n+ice_parse_ieee_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tu32 ouisubtype;\n+\tu8 subtype;\n+\n+\touisubtype = ntohl(tlv->ouisubtype);\n+\tsubtype = (u8)((ouisubtype & ICE_LLDP_TLV_SUBTYPE_M) >>\n+\t\t ICE_LLDP_TLV_SUBTYPE_S);\n+\tswitch (subtype) {\n+\tcase ICE_IEEE_SUBTYPE_ETS_CFG:\n+\t\tice_parse_ieee_etscfg_tlv(tlv, dcbcfg);\n+\t\tbreak;\n+\tcase ICE_IEEE_SUBTYPE_ETS_REC:\n+\t\tice_parse_ieee_etsrec_tlv(tlv, dcbcfg);\n+\t\tbreak;\n+\tcase ICE_IEEE_SUBTYPE_PFC_CFG:\n+\t\tice_parse_ieee_pfccfg_tlv(tlv, dcbcfg);\n+\t\tbreak;\n+\tcase ICE_IEEE_SUBTYPE_APP_PRI:\n+\t\tice_parse_ieee_app_tlv(tlv, dcbcfg);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n+ * ice_parse_cee_pgcfg_tlv\n+ * @tlv: CEE DCBX PG CFG TLV\n+ * @dcbcfg: Local store to update ETS CFG data\n+ *\n+ * Parses CEE DCBX PG CFG TLV\n+ */\n+static void\n+ice_parse_cee_pgcfg_tlv(struct ice_cee_feat_tlv *tlv,\n+\t\t\tstruct ice_dcbx_cfg *dcbcfg)\n+{\n+\tstruct ice_dcb_ets_cfg *etscfg;\n+\tu8 *buf = tlv->tlvinfo;\n+\tu16 offset = 0;\n+\tint i;\n+\n+\tetscfg = &dcbcfg->etscfg;\n+\n+\tif (tlv->en_will_err & ICE_CEE_FEAT_TLV_WILLING_M)\n+\t\tetscfg->willing = 1;\n+\n+\tetscfg->cbs = 0;\n+\t/* Priority Group Table (4 octets)\n+\t * Octets:| 1 | 2 | 3 | 4 |\n+\t * -----------------------------------------\n+\t * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|\n+\t * -----------------------------------------\n+\t * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|\n+\t * -----------------------------------------\n+\t */\n+\tfor (i = 0; i < 4; i++) {\n+\t\tetscfg->prio_table[i * 2] =\n+\t\t\t((buf[offset] & ICE_CEE_PGID_PRIO_1_M) >>\n+\t\t\t ICE_CEE_PGID_PRIO_1_S);\n+\t\tetscfg->prio_table[i * 2 + 1] =\n+\t\t\t((buf[offset] & ICE_CEE_PGID_PRIO_0_M) >>\n+\t\t\t ICE_CEE_PGID_PRIO_0_S);\n+\t\toffset++;\n+\t}\n+\n+\t/* PG Percentage Table (8 octets)\n+\t * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |\n+\t * ---------------------------------\n+\t * |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7|\n+\t * ---------------------------------\n+\t */\n+\tice_for_each_traffic_class(i)\n+\t\tetscfg->tcbwtable[i] = buf[offset++];\n+\n+\t/* Number of TCs supported (1 octet) */\n+\tetscfg->maxtcs = buf[offset];\n+}\n+\n+/**\n+ * ice_parse_cee_pfccfg_tlv\n+ * @tlv: CEE DCBX PFC CFG TLV\n+ * @dcbcfg: Local store to update PFC CFG data\n+ *\n+ * Parses CEE DCBX PFC CFG TLV\n+ */\n+static void\n+ice_parse_cee_pfccfg_tlv(struct ice_cee_feat_tlv *tlv,\n+\t\t\t struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tu8 *buf = tlv->tlvinfo;\n+\n+\tif (tlv->en_will_err & ICE_CEE_FEAT_TLV_WILLING_M)\n+\t\tdcbcfg->pfc.willing = 1;\n+\n+\t/* ------------------------\n+\t * | PFC Enable | PFC TCs |\n+\t * ------------------------\n+\t * | 1 octet | 1 octet |\n+\t */\n+\tdcbcfg->pfc.pfcena = buf[0];\n+\tdcbcfg->pfc.pfccap = buf[1];\n+}\n+\n+/**\n+ * ice_parse_cee_app_tlv\n+ * @tlv: CEE DCBX APP TLV\n+ * @dcbcfg: Local store to update APP PRIO data\n+ *\n+ * Parses CEE DCBX APP PRIO TLV\n+ */\n+static void\n+ice_parse_cee_app_tlv(struct ice_cee_feat_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tu16 len, typelen, offset = 0;\n+\tstruct ice_cee_app_prio *app;\n+\tu8 i;\n+\n+\ttypelen = ntohs(tlv->hdr.typelen);\n+\tlen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);\n+\n+\tdcbcfg->numapps = len / sizeof(*app);\n+\tif (!dcbcfg->numapps)\n+\t\treturn;\n+\tif (dcbcfg->numapps > ICE_DCBX_MAX_APPS)\n+\t\tdcbcfg->numapps = ICE_DCBX_MAX_APPS;\n+\n+\tfor (i = 0; i < dcbcfg->numapps; i++) {\n+\t\tu8 up, selector;\n+\n+\t\tapp = (struct ice_cee_app_prio *)(tlv->tlvinfo + offset);\n+\t\tfor (up = 0; up < ICE_MAX_USER_PRIORITY; up++)\n+\t\t\tif (app->prio_map & BIT(up))\n+\t\t\t\tbreak;\n+\n+\t\tdcbcfg->app[i].priority = up;\n+\n+\t\t/* Get Selector from lower 2 bits, and convert to IEEE */\n+\t\tselector = (app->upper_oui_sel & ICE_CEE_APP_SELECTOR_M);\n+\t\tswitch (selector) {\n+\t\tcase ICE_CEE_APP_SEL_ETHTYPE:\n+\t\t\tdcbcfg->app[i].selector = ICE_APP_SEL_ETHTYPE;\n+\t\t\tbreak;\n+\t\tcase ICE_CEE_APP_SEL_TCPIP:\n+\t\t\tdcbcfg->app[i].selector = ICE_APP_SEL_TCPIP;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\t/* Keep selector as it is for unknown types */\n+\t\t\tdcbcfg->app[i].selector = selector;\n+\t\t}\n+\n+\t\tdcbcfg->app[i].prot_id = ntohs(app->protocol);\n+\t\t/* Move to next app */\n+\t\toffset += sizeof(*app);\n+\t}\n+}\n+\n+/**\n+ * ice_parse_cee_tlv\n+ * @tlv: CEE DCBX TLV\n+ * @dcbcfg: Local store to update DCBX config data\n+ *\n+ * Get the TLV subtype and send it to parsing function\n+ * based on the subtype value\n+ */\n+static void\n+ice_parse_cee_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tstruct ice_cee_feat_tlv *sub_tlv;\n+\tu8 subtype, feat_tlv_count = 0;\n+\tu16 len, tlvlen, typelen;\n+\tu32 ouisubtype;\n+\n+\touisubtype = ntohl(tlv->ouisubtype);\n+\tsubtype = (u8)((ouisubtype & ICE_LLDP_TLV_SUBTYPE_M) >>\n+\t\t ICE_LLDP_TLV_SUBTYPE_S);\n+\t/* Return if not CEE DCBX */\n+\tif (subtype != ICE_CEE_DCBX_TYPE)\n+\t\treturn;\n+\n+\ttypelen = ntohs(tlv->typelen);\n+\ttlvlen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);\n+\tlen = sizeof(tlv->typelen) + sizeof(ouisubtype) +\n+\t\tsizeof(struct ice_cee_ctrl_tlv);\n+\t/* Return if no CEE DCBX Feature TLVs */\n+\tif (tlvlen <= len)\n+\t\treturn;\n+\n+\tsub_tlv = (struct ice_cee_feat_tlv *)((char *)tlv + len);\n+\twhile (feat_tlv_count < ICE_CEE_MAX_FEAT_TYPE) {\n+\t\tu16 sublen;\n+\n+\t\ttypelen = ntohs(sub_tlv->hdr.typelen);\n+\t\tsublen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);\n+\t\tsubtype = (u8)((typelen & ICE_LLDP_TLV_TYPE_M) >>\n+\t\t\t ICE_LLDP_TLV_TYPE_S);\n+\t\tswitch (subtype) {\n+\t\tcase ICE_CEE_SUBTYPE_PG_CFG:\n+\t\t\tice_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);\n+\t\t\tbreak;\n+\t\tcase ICE_CEE_SUBTYPE_PFC_CFG:\n+\t\t\tice_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);\n+\t\t\tbreak;\n+\t\tcase ICE_CEE_SUBTYPE_APP_PRI:\n+\t\t\tice_parse_cee_app_tlv(sub_tlv, dcbcfg);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn;\t/* Invalid Sub-type return */\n+\t\t}\n+\t\tfeat_tlv_count++;\n+\t\t/* Move to next sub TLV */\n+\t\tsub_tlv = (struct ice_cee_feat_tlv *)\n+\t\t\t ((char *)sub_tlv + sizeof(sub_tlv->hdr.typelen) +\n+\t\t\t sublen);\n+\t}\n+}\n+\n+/**\n+ * ice_parse_org_tlv\n+ * @tlv: Organization specific TLV\n+ * @dcbcfg: Local store to update ETS REC data\n+ *\n+ * Currently only IEEE 802.1Qaz TLV is supported, all others\n+ * will be returned\n+ */\n+static void\n+ice_parse_org_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tu32 ouisubtype;\n+\tu32 oui;\n+\n+\touisubtype = ntohl(tlv->ouisubtype);\n+\toui = ((ouisubtype & ICE_LLDP_TLV_OUI_M) >> ICE_LLDP_TLV_OUI_S);\n+\tswitch (oui) {\n+\tcase ICE_IEEE_8021QAZ_OUI:\n+\t\tice_parse_ieee_tlv(tlv, dcbcfg);\n+\t\tbreak;\n+\tcase ICE_CEE_DCBX_OUI:\n+\t\tice_parse_cee_tlv(tlv, dcbcfg);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+/**\n+ * ice_lldp_to_dcb_cfg\n+ * @lldpmib: LLDPDU to be parsed\n+ * @dcbcfg: store for LLDPDU data\n+ *\n+ * Parse DCB configuration from the LLDPDU\n+ */\n+static enum ice_status\n+ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tstruct ice_lldp_org_tlv *tlv;\n+\tenum ice_status ret = 0;\n+\tu16 offset = 0;\n+\tu16 typelen;\n+\tu16 type;\n+\tu16 len;\n+\n+\tif (!lldpmib || !dcbcfg)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\t/* set to the start of LLDPDU */\n+\tlldpmib += ETH_HLEN;\n+\ttlv = (struct ice_lldp_org_tlv *)lldpmib;\n+\twhile (1) {\n+\t\ttypelen = ntohs(tlv->typelen);\n+\t\ttype = ((typelen & ICE_LLDP_TLV_TYPE_M) >> ICE_LLDP_TLV_TYPE_S);\n+\t\tlen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);\n+\t\toffset += sizeof(typelen) + len;\n+\n+\t\t/* END TLV or beyond LLDPDU size */\n+\t\tif (type == ICE_TLV_TYPE_END || offset > ICE_LLDPDU_SIZE)\n+\t\t\tbreak;\n+\n+\t\tswitch (type) {\n+\t\tcase ICE_TLV_TYPE_ORG:\n+\t\t\tice_parse_org_tlv(tlv, dcbcfg);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* Move to next TLV */\n+\t\ttlv = (struct ice_lldp_org_tlv *)\n+\t\t ((char *)tlv + sizeof(tlv->typelen) + len);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/**\n+ * ice_aq_get_dcb_cfg\n+ * @hw: pointer to the HW struct\n+ * @mib_type: mib type for the query\n+ * @bridgetype: bridge type for the query (remote)\n+ * @dcbcfg: store for LLDPDU data\n+ *\n+ * Query DCB configuration from the firmware\n+ */\n+static enum ice_status\n+ice_aq_get_dcb_cfg(struct ice_hw *hw, u8 mib_type, u8 bridgetype,\n+\t\t struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tenum ice_status ret;\n+\tu8 *lldpmib;\n+\n+\t/* Allocate the LLDPDU */\n+\tlldpmib = devm_kzalloc(ice_hw_to_dev(hw), ICE_LLDPDU_SIZE, GFP_KERNEL);\n+\tif (!lldpmib)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\tret = ice_aq_get_lldp_mib(hw, bridgetype, mib_type, (void *)lldpmib,\n+\t\t\t\t ICE_LLDPDU_SIZE, NULL, NULL, NULL);\n+\n+\tif (!ret)\n+\t\t/* Parse LLDP MIB to get DCB configuration */\n+\t\tret = ice_lldp_to_dcb_cfg(lldpmib, dcbcfg);\n+\n+\tdevm_kfree(ice_hw_to_dev(hw), lldpmib);\n+\n+\treturn ret;\n+}\n+\n /**\n * ice_aq_start_stop_dcbx - Start/Stop DCBx service in FW\n * @hw: pointer to the HW struct\n@@ -83,3 +672,233 @@ ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent,\n \n \treturn status;\n }\n+\n+/**\n+ * ice_aq_get_cee_dcb_cfg\n+ * @hw: pointer to the HW struct\n+ * @buff: response buffer that stores CEE operational configuration\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Get CEE DCBX mode operational configuration from firmware (0x0A07)\n+ */\n+static enum ice_status\n+ice_aq_get_cee_dcb_cfg(struct ice_hw *hw,\n+\t\t struct ice_aqc_get_cee_dcb_cfg_resp *buff,\n+\t\t struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aq_desc desc;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_cee_dcb_cfg);\n+\n+\treturn ice_aq_send_cmd(hw, &desc, (void *)buff, sizeof(*buff), cd);\n+}\n+\n+/**\n+ * ice_cee_to_dcb_cfg\n+ * @cee_cfg: pointer to CEE configuration struct\n+ * @dcbcfg: DCB configuration struct\n+ *\n+ * Convert CEE configuration from firmware to DCB configuration\n+ */\n+static void\n+ice_cee_to_dcb_cfg(struct ice_aqc_get_cee_dcb_cfg_resp *cee_cfg,\n+\t\t struct ice_dcbx_cfg *dcbcfg)\n+{\n+\tu32 status, tlv_status = le32_to_cpu(cee_cfg->tlv_status);\n+\tu32 ice_aqc_cee_status_mask, ice_aqc_cee_status_shift;\n+\tu16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);\n+\tu8 i, err, sync, oper, app_index, ice_app_sel_type;\n+\tu16 ice_aqc_cee_app_mask, ice_aqc_cee_app_shift;\n+\tu16 ice_app_prot_id_type;\n+\n+\t/* CEE PG data to ETS config */\n+\tdcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;\n+\n+\t/* Note that the FW creates the oper_prio_tc nibbles reversed\n+\t * from those in the CEE Priority Group sub-TLV.\n+\t */\n+\tfor (i = 0; i < ICE_MAX_TRAFFIC_CLASS / 2; i++) {\n+\t\tdcbcfg->etscfg.prio_table[i * 2] =\n+\t\t\t((cee_cfg->oper_prio_tc[i] & ICE_CEE_PGID_PRIO_0_M) >>\n+\t\t\t ICE_CEE_PGID_PRIO_0_S);\n+\t\tdcbcfg->etscfg.prio_table[i * 2 + 1] =\n+\t\t\t((cee_cfg->oper_prio_tc[i] & ICE_CEE_PGID_PRIO_1_M) >>\n+\t\t\t ICE_CEE_PGID_PRIO_1_S);\n+\t}\n+\n+\tice_for_each_traffic_class(i) {\n+\t\tdcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];\n+\n+\t\tif (dcbcfg->etscfg.prio_table[i] == ICE_CEE_PGID_STRICT) {\n+\t\t\t/* Map it to next empty TC */\n+\t\t\tdcbcfg->etscfg.prio_table[i] = cee_cfg->oper_num_tc - 1;\n+\t\t\tdcbcfg->etscfg.tsatable[i] = ICE_IEEE_TSA_STRICT;\n+\t\t} else {\n+\t\t\tdcbcfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS;\n+\t\t}\n+\t}\n+\n+\t/* CEE PFC data to ETS config */\n+\tdcbcfg->pfc.pfcena = cee_cfg->oper_pfc_en;\n+\tdcbcfg->pfc.pfccap = ICE_MAX_TRAFFIC_CLASS;\n+\n+\tapp_index = 0;\n+\tfor (i = 0; i < 3; i++) {\n+\t\tif (i == 0) {\n+\t\t\t/* FCoE APP */\n+\t\t\tice_aqc_cee_status_mask = ICE_AQC_CEE_FCOE_STATUS_M;\n+\t\t\tice_aqc_cee_status_shift = ICE_AQC_CEE_FCOE_STATUS_S;\n+\t\t\tice_aqc_cee_app_mask = ICE_AQC_CEE_APP_FCOE_M;\n+\t\t\tice_aqc_cee_app_shift = ICE_AQC_CEE_APP_FCOE_S;\n+\t\t\tice_app_sel_type = ICE_APP_SEL_ETHTYPE;\n+\t\t\tice_app_prot_id_type = ICE_APP_PROT_ID_FCOE;\n+\t\t} else if (i == 1) {\n+\t\t\t/* iSCSI APP */\n+\t\t\tice_aqc_cee_status_mask = ICE_AQC_CEE_ISCSI_STATUS_M;\n+\t\t\tice_aqc_cee_status_shift = ICE_AQC_CEE_ISCSI_STATUS_S;\n+\t\t\tice_aqc_cee_app_mask = ICE_AQC_CEE_APP_ISCSI_M;\n+\t\t\tice_aqc_cee_app_shift = ICE_AQC_CEE_APP_ISCSI_S;\n+\t\t\tice_app_sel_type = ICE_APP_SEL_TCPIP;\n+\t\t\tice_app_prot_id_type = ICE_APP_PROT_ID_ISCSI;\n+\t\t} else {\n+\t\t\t/* FIP APP */\n+\t\t\tice_aqc_cee_status_mask = ICE_AQC_CEE_FIP_STATUS_M;\n+\t\t\tice_aqc_cee_status_shift = ICE_AQC_CEE_FIP_STATUS_S;\n+\t\t\tice_aqc_cee_app_mask = ICE_AQC_CEE_APP_FIP_M;\n+\t\t\tice_aqc_cee_app_shift = ICE_AQC_CEE_APP_FIP_S;\n+\t\t\tice_app_sel_type = ICE_APP_SEL_ETHTYPE;\n+\t\t\tice_app_prot_id_type = ICE_APP_PROT_ID_FIP;\n+\t\t}\n+\n+\t\tstatus = (tlv_status & ice_aqc_cee_status_mask) >>\n+\t\t\t ice_aqc_cee_status_shift;\n+\t\terr = (status & ICE_TLV_STATUS_ERR) ? 1 : 0;\n+\t\tsync = (status & ICE_TLV_STATUS_SYNC) ? 1 : 0;\n+\t\toper = (status & ICE_TLV_STATUS_OPER) ? 1 : 0;\n+\t\t/* Add FCoE/iSCSI/FIP APP if Error is False and\n+\t\t * Oper/Sync is True\n+\t\t */\n+\t\tif (!err && sync && oper) {\n+\t\t\tdcbcfg->app[app_index].priority =\n+\t\t\t\t(app_prio & ice_aqc_cee_app_mask) >>\n+\t\t\t\tice_aqc_cee_app_shift;\n+\t\t\tdcbcfg->app[app_index].selector = ice_app_sel_type;\n+\t\t\tdcbcfg->app[app_index].prot_id = ice_app_prot_id_type;\n+\t\t\tapp_index++;\n+\t\t}\n+\t}\n+\n+\tdcbcfg->numapps = app_index;\n+}\n+\n+/**\n+ * ice_get_ieee_dcb_cfg\n+ * @pi: port information structure\n+ * @dcbx_mode: mode of DCBX (IEEE or CEE)\n+ *\n+ * Get IEEE or CEE mode DCB configuration from the Firmware\n+ */\n+static enum ice_status\n+ice_get_ieee_or_cee_dcb_cfg(struct ice_port_info *pi, u8 dcbx_mode)\n+{\n+\tstruct ice_dcbx_cfg *dcbx_cfg = NULL;\n+\tenum ice_status ret;\n+\n+\tif (!pi)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tif (dcbx_mode == ICE_DCBX_MODE_IEEE)\n+\t\tdcbx_cfg = &pi->local_dcbx_cfg;\n+\telse if (dcbx_mode == ICE_DCBX_MODE_CEE)\n+\t\tdcbx_cfg = &pi->desired_dcbx_cfg;\n+\n+\t/* Get Local DCB Config in case of ICE_DCBX_MODE_IEEE\n+\t * or get CEE DCB Desired Config in case of ICE_DCBX_MODE_CEE\n+\t */\n+\tret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_LOCAL,\n+\t\t\t\t ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbx_cfg);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\t/* Get Remote DCB Config */\n+\tdcbx_cfg = &pi->remote_dcbx_cfg;\n+\tret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_REMOTE,\n+\t\t\t\t ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbx_cfg);\n+\t/* Don't treat ENOENT as an error for Remote MIBs */\n+\tif (pi->hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)\n+\t\tret = 0;\n+\n+out:\n+\treturn ret;\n+}\n+\n+/**\n+ * ice_get_dcb_cfg\n+ * @pi: port information structure\n+ *\n+ * Get DCB configuration from the Firmware\n+ */\n+static enum ice_status ice_get_dcb_cfg(struct ice_port_info *pi)\n+{\n+\tstruct ice_aqc_get_cee_dcb_cfg_resp cee_cfg;\n+\tstruct ice_dcbx_cfg *dcbx_cfg;\n+\tenum ice_status ret;\n+\n+\tif (!pi)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tret = ice_aq_get_cee_dcb_cfg(pi->hw, &cee_cfg, NULL);\n+\tif (!ret) {\n+\t\t/* CEE mode */\n+\t\tdcbx_cfg = &pi->local_dcbx_cfg;\n+\t\tdcbx_cfg->dcbx_mode = ICE_DCBX_MODE_CEE;\n+\t\tdcbx_cfg->tlv_status = le32_to_cpu(cee_cfg.tlv_status);\n+\t\tice_cee_to_dcb_cfg(&cee_cfg, dcbx_cfg);\n+\t\tret = ice_get_ieee_or_cee_dcb_cfg(pi, ICE_DCBX_MODE_CEE);\n+\t} else if (pi->hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) {\n+\t\t/* CEE mode not enabled try querying IEEE data */\n+\t\tdcbx_cfg = &pi->local_dcbx_cfg;\n+\t\tdcbx_cfg->dcbx_mode = ICE_DCBX_MODE_IEEE;\n+\t\tret = ice_get_ieee_or_cee_dcb_cfg(pi, ICE_DCBX_MODE_IEEE);\n+\t}\n+\n+\treturn ret;\n+}\n+\n+/**\n+ * ice_init_dcb\n+ * @hw: pointer to the HW struct\n+ *\n+ * Update DCB configuration from the Firmware\n+ */\n+enum ice_status ice_init_dcb(struct ice_hw *hw)\n+{\n+\tstruct ice_port_info *pi = hw->port_info;\n+\tenum ice_status ret = 0;\n+\n+\tif (!hw->func_caps.common_cap.dcb)\n+\t\treturn ICE_ERR_NOT_SUPPORTED;\n+\n+\tpi->is_sw_lldp = true;\n+\n+\t/* Get DCBX status */\n+\tpi->dcbx_status = ice_get_dcbx_status(hw);\n+\n+\tif (pi->dcbx_status == ICE_DCBX_STATUS_DONE ||\n+\t pi->dcbx_status == ICE_DCBX_STATUS_IN_PROGRESS) {\n+\t\t/* Get current DCBX configuration */\n+\t\tret = ice_get_dcb_cfg(pi);\n+\t\tpi->is_sw_lldp = (hw->adminq.sq_last_status == ICE_AQ_RC_EPERM);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t} else if (pi->dcbx_status == ICE_DCBX_STATUS_DIS) {\n+\t\treturn ICE_ERR_NOT_READY;\n+\t}\n+\n+\t/* Configure the LLDP MIB change event */\n+\tret = ice_aq_cfg_lldp_mib_change(hw, true, NULL);\n+\tif (!ret)\n+\t\tpi->is_sw_lldp = false;\n+\n+\treturn ret;\n+}\ndiff --git a/drivers/net/ethernet/intel/ice/ice_dcb.h b/drivers/net/ethernet/intel/ice/ice_dcb.h\nindex 05ed9fd2fe38..f0f47567113b 100644\n--- a/drivers/net/ethernet/intel/ice/ice_dcb.h\n+++ b/drivers/net/ethernet/intel/ice/ice_dcb.h\n@@ -8,8 +8,107 @@\n \n #define ICE_DCBX_STATUS_IN_PROGRESS\t1\n #define ICE_DCBX_STATUS_DONE\t\t2\n+#define ICE_DCBX_STATUS_DIS\t\t7\n+\n+#define ICE_TLV_TYPE_END\t\t0\n+#define ICE_TLV_TYPE_ORG\t\t127\n+\n+#define ICE_IEEE_8021QAZ_OUI\t\t0x0080C2\n+#define ICE_IEEE_SUBTYPE_ETS_CFG\t9\n+#define ICE_IEEE_SUBTYPE_ETS_REC\t10\n+#define ICE_IEEE_SUBTYPE_PFC_CFG\t11\n+#define ICE_IEEE_SUBTYPE_APP_PRI\t12\n+\n+#define ICE_CEE_DCBX_OUI\t\t0x001B21\n+#define ICE_CEE_DCBX_TYPE\t\t2\n+#define ICE_CEE_SUBTYPE_PG_CFG\t\t2\n+#define ICE_CEE_SUBTYPE_PFC_CFG\t\t3\n+#define ICE_CEE_SUBTYPE_APP_PRI\t\t4\n+#define ICE_CEE_MAX_FEAT_TYPE\t\t3\n+/* Defines for LLDP TLV header */\n+#define ICE_LLDP_TLV_LEN_S\t\t0\n+#define ICE_LLDP_TLV_LEN_M\t\t(0x01FF << ICE_LLDP_TLV_LEN_S)\n+#define ICE_LLDP_TLV_TYPE_S\t\t9\n+#define ICE_LLDP_TLV_TYPE_M\t\t(0x7F << ICE_LLDP_TLV_TYPE_S)\n+#define ICE_LLDP_TLV_SUBTYPE_S\t\t0\n+#define ICE_LLDP_TLV_SUBTYPE_M\t\t(0xFF << ICE_LLDP_TLV_SUBTYPE_S)\n+#define ICE_LLDP_TLV_OUI_S\t\t8\n+#define ICE_LLDP_TLV_OUI_M\t\t(0xFFFFFFUL << ICE_LLDP_TLV_OUI_S)\n+\n+/* Defines for IEEE ETS TLV */\n+#define ICE_IEEE_ETS_MAXTC_S\t0\n+#define ICE_IEEE_ETS_MAXTC_M\t\t(0x7 << ICE_IEEE_ETS_MAXTC_S)\n+#define ICE_IEEE_ETS_CBS_S\t\t6\n+#define ICE_IEEE_ETS_CBS_M\t\tBIT(ICE_IEEE_ETS_CBS_S)\n+#define ICE_IEEE_ETS_WILLING_S\t\t7\n+#define ICE_IEEE_ETS_WILLING_M\t\tBIT(ICE_IEEE_ETS_WILLING_S)\n+#define ICE_IEEE_ETS_PRIO_0_S\t\t0\n+#define ICE_IEEE_ETS_PRIO_0_M\t\t(0x7 << ICE_IEEE_ETS_PRIO_0_S)\n+#define ICE_IEEE_ETS_PRIO_1_S\t\t4\n+#define ICE_IEEE_ETS_PRIO_1_M\t\t(0x7 << ICE_IEEE_ETS_PRIO_1_S)\n+#define ICE_CEE_PGID_PRIO_0_S\t\t0\n+#define ICE_CEE_PGID_PRIO_0_M\t\t(0xF << ICE_CEE_PGID_PRIO_0_S)\n+#define ICE_CEE_PGID_PRIO_1_S\t\t4\n+#define ICE_CEE_PGID_PRIO_1_M\t\t(0xF << ICE_CEE_PGID_PRIO_1_S)\n+#define ICE_CEE_PGID_STRICT\t\t15\n+\n+/* Defines for IEEE TSA types */\n+#define ICE_IEEE_TSA_STRICT\t\t0\n+#define ICE_IEEE_TSA_ETS\t\t2\n+\n+/* Defines for IEEE PFC TLV */\n+#define ICE_IEEE_PFC_CAP_S\t\t0\n+#define ICE_IEEE_PFC_CAP_M\t\t(0xF << ICE_IEEE_PFC_CAP_S)\n+#define ICE_IEEE_PFC_MBC_S\t\t6\n+#define ICE_IEEE_PFC_MBC_M\t\tBIT(ICE_IEEE_PFC_MBC_S)\n+#define ICE_IEEE_PFC_WILLING_S\t\t7\n+#define ICE_IEEE_PFC_WILLING_M\t\tBIT(ICE_IEEE_PFC_WILLING_S)\n+\n+/* Defines for IEEE APP TLV */\n+#define ICE_IEEE_APP_SEL_S\t\t0\n+#define ICE_IEEE_APP_SEL_M\t\t(0x7 << ICE_IEEE_APP_SEL_S)\n+#define ICE_IEEE_APP_PRIO_S\t\t5\n+#define ICE_IEEE_APP_PRIO_M\t\t(0x7 << ICE_IEEE_APP_PRIO_S)\n+\n+/* IEEE 802.1AB LLDP Organization specific TLV */\n+struct ice_lldp_org_tlv {\n+\t__be16 typelen;\n+\t__be32 ouisubtype;\n+\tu8 tlvinfo[1];\n+} __packed;\n+\n+struct ice_cee_tlv_hdr {\n+\t__be16 typelen;\n+\tu8 operver;\n+\tu8 maxver;\n+};\n+\n+struct ice_cee_ctrl_tlv {\n+\tstruct ice_cee_tlv_hdr hdr;\n+\t__be32 seqno;\n+\t__be32 ackno;\n+};\n+\n+struct ice_cee_feat_tlv {\n+\tstruct ice_cee_tlv_hdr hdr;\n+\tu8 en_will_err; /* Bits: |En|Will|Err|Reserved(5)| */\n+#define ICE_CEE_FEAT_TLV_ENA_M\t\t0x80\n+#define ICE_CEE_FEAT_TLV_WILLING_M\t0x40\n+#define ICE_CEE_FEAT_TLV_ERR_M\t\t0x20\n+\tu8 subtype;\n+\tu8 tlvinfo[1];\n+};\n+\n+struct ice_cee_app_prio {\n+\t__be16 protocol;\n+\tu8 upper_oui_sel; /* Bits: |Upper OUI(6)|Selector(2)| */\n+#define ICE_CEE_APP_SELECTOR_M\t0x03\n+\t__be16 lower_oui;\n+\tu8 prio_map;\n+} __packed;\n \n u8 ice_get_dcbx_status(struct ice_hw *hw);\n+enum ice_status ice_init_dcb(struct ice_hw *hw);\n #ifdef CONFIG_DCB\n enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd);\n enum ice_status\ndiff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c\nindex 424a745d9783..9f7c3d4d3f01 100644\n--- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c\n+++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c\n@@ -38,5 +38,5 @@ int ice_init_pf_dcb(struct ice_pf *pf)\n \t\tice_aq_start_stop_dcbx(hw, true, &dcbx_status, NULL);\n \t}\n \n-\treturn 0;\n+\treturn ice_init_dcb(hw);\n }\ndiff --git a/drivers/net/ethernet/intel/ice/ice_status.h b/drivers/net/ethernet/intel/ice/ice_status.h\nindex 683f48824a29..17afe6acb18a 100644\n--- a/drivers/net/ethernet/intel/ice/ice_status.h\n+++ b/drivers/net/ethernet/intel/ice/ice_status.h\n@@ -12,6 +12,7 @@ enum ice_status {\n \tICE_ERR_PARAM\t\t\t\t= -1,\n \tICE_ERR_NOT_IMPL\t\t\t= -2,\n \tICE_ERR_NOT_READY\t\t\t= -3,\n+\tICE_ERR_NOT_SUPPORTED\t\t\t= -4,\n \tICE_ERR_BAD_PTR\t\t\t\t= -5,\n \tICE_ERR_INVAL_SIZE\t\t\t= -6,\n \tICE_ERR_DEVICE_NOT_SUPPORTED\t\t= -8,\ndiff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h\nindex e21ea271b48e..d276e9a952db 100644\n--- a/drivers/net/ethernet/intel/ice/ice_type.h\n+++ b/drivers/net/ethernet/intel/ice/ice_type.h\n@@ -262,6 +262,59 @@ struct ice_sched_tx_policy {\n \tu8 rdma_ena;\n };\n \n+/* CEE or IEEE 802.1Qaz ETS Configuration data */\n+struct ice_dcb_ets_cfg {\n+\tu8 willing;\n+\tu8 cbs;\n+\tu8 maxtcs;\n+\tu8 prio_table[ICE_MAX_TRAFFIC_CLASS];\n+\tu8 tcbwtable[ICE_MAX_TRAFFIC_CLASS];\n+\tu8 tsatable[ICE_MAX_TRAFFIC_CLASS];\n+};\n+\n+/* CEE or IEEE 802.1Qaz PFC Configuration data */\n+struct ice_dcb_pfc_cfg {\n+\tu8 willing;\n+\tu8 mbc;\n+\tu8 pfccap;\n+\tu8 pfcena;\n+};\n+\n+/* CEE or IEEE 802.1Qaz Application Priority data */\n+struct ice_dcb_app_priority_table {\n+\tu16 prot_id;\n+\tu8 priority;\n+\tu8 selector;\n+};\n+\n+#define ICE_MAX_USER_PRIORITY\t8\n+#define ICE_DCBX_MAX_APPS\t32\n+#define ICE_LLDPDU_SIZE\t\t1500\n+#define ICE_TLV_STATUS_OPER\t0x1\n+#define ICE_TLV_STATUS_SYNC\t0x2\n+#define ICE_TLV_STATUS_ERR\t0x4\n+#define ICE_APP_PROT_ID_FCOE\t0x8906\n+#define ICE_APP_PROT_ID_ISCSI\t0x0cbc\n+#define ICE_APP_PROT_ID_FIP\t0x8914\n+#define ICE_APP_SEL_ETHTYPE\t0x1\n+#define ICE_APP_SEL_TCPIP\t0x2\n+#define ICE_CEE_APP_SEL_ETHTYPE\t0x0\n+#define ICE_CEE_APP_SEL_TCPIP\t0x1\n+\n+struct ice_dcbx_cfg {\n+\tu32 numapps;\n+\tu32 tlv_status; /* CEE mode TLV status */\n+\tstruct ice_dcb_ets_cfg etscfg;\n+\tstruct ice_dcb_ets_cfg etsrec;\n+\tstruct ice_dcb_pfc_cfg pfc;\n+\tstruct ice_dcb_app_priority_table app[ICE_DCBX_MAX_APPS];\n+\tu8 dcbx_mode;\n+#define ICE_DCBX_MODE_CEE\t0x1\n+#define ICE_DCBX_MODE_IEEE\t0x2\n+\tu8 app_mode;\n+#define ICE_DCBX_APPS_NON_WILLING\t0x1\n+};\n+\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@@ -279,8 +332,13 @@ struct ice_port_info {\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_dcbx_cfg local_dcbx_cfg;\t/* Oper/Local Cfg */\n+\t/* DCBX info */\n+\tstruct ice_dcbx_cfg remote_dcbx_cfg;\t/* Peer Cfg */\n+\tstruct ice_dcbx_cfg desired_dcbx_cfg;\t/* CEE Desired Cfg */\n \t/* LLDP/DCBX Status */\n \tu8 dcbx_status;\n+\tu8 is_sw_lldp;\n \tu8 lport;\n #define ICE_LPORT_MASK\t\t0xff\n \tu8 is_vf;\n", "prefixes": [ "S16", "02/11" ] }