From patchwork Mon Mar 11 07:04:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Zhang X-Patchwork-Id: 51030 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C3D6E4C93; Mon, 11 Mar 2019 08:02:57 +0100 (CET) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by dpdk.org (Postfix) with ESMTP id 276282BE5 for ; Mon, 11 Mar 2019 08:02:54 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Mar 2019 00:02:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,467,1544515200"; d="scan'208";a="124385950" Received: from dpdk51.sh.intel.com ([10.67.110.160]) by orsmga008.jf.intel.com with ESMTP; 11 Mar 2019 00:02:51 -0700 From: Qi Zhang To: wenzhuo.lu@intel.com, qiming.yang@intel.com Cc: dev@dpdk.org, paul.m.stillwell.jr@intel.com, ferruh.yigit@intel.com, Qi Zhang Date: Mon, 11 Mar 2019 15:04:04 +0800 Message-Id: <20190311070441.5501-2-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20190311070441.5501-1-qi.z.zhang@intel.com> References: <20190228055650.25237-1-qi.z.zhang@intel.com> <20190311070441.5501-1-qi.z.zhang@intel.com> Subject: [dpdk-dev] [PATCH v3 01/38] net/ice/base: add switch resource allocation and free X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add two APIs ice_alloc_sw and ice_free_sw to support switch related resource allocation and free. These APIs is required when we enable switch flow. Signed-off-by: Paul M Stillwell Jr Signed-off-by: Qi Zhang --- drivers/net/ice/base/ice_switch.c | 150 ++++++++++++++++++++++++++++++++++++++ drivers/net/ice/base/ice_switch.h | 5 ++ 2 files changed, 155 insertions(+) diff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c index 0379cd045..a7b712e17 100644 --- a/drivers/net/ice/base/ice_switch.c +++ b/drivers/net/ice/base/ice_switch.c @@ -129,6 +129,156 @@ ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp *buf, } +/** + * ice_alloc_sw - allocate resources specific to switch + * @hw: pointer to the HW struct + * @ena_stats: true to turn on VEB stats + * @shared_res: true for shared resource, false for dedicated resource + * @sw_id: switch ID returned + * @counter_id: VEB counter ID returned + * + * allocates switch resources (SWID and VEB counter) (0x0208) + */ +enum ice_status +ice_alloc_sw(struct ice_hw *hw, bool ena_stats, bool shared_res, u16 *sw_id, + u16 *counter_id) +{ + struct ice_aqc_alloc_free_res_elem *sw_buf; + struct ice_aqc_res_elem *sw_ele; + enum ice_status status; + u16 buf_len; + + buf_len = sizeof(*sw_buf); + sw_buf = (struct ice_aqc_alloc_free_res_elem *) + ice_malloc(hw, buf_len); + if (!sw_buf) + return ICE_ERR_NO_MEMORY; + + /* Prepare buffer for switch ID. + * The number of resource entries in buffer is passed as 1 since only a + * single switch/VEB instance is allocated, and hence a single sw_id + * is requested. + */ + sw_buf->num_elems = CPU_TO_LE16(1); + sw_buf->res_type = + CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID | + (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED : + ICE_AQC_RES_TYPE_FLAG_DEDICATED)); + + status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, + ice_aqc_opc_alloc_res, NULL); + + if (status) + goto ice_alloc_sw_exit; + + sw_ele = &sw_buf->elem[0]; + *sw_id = LE16_TO_CPU(sw_ele->e.sw_resp); + + if (ena_stats) { + /* Prepare buffer for VEB Counter */ + enum ice_adminq_opc opc = ice_aqc_opc_alloc_res; + struct ice_aqc_alloc_free_res_elem *counter_buf; + struct ice_aqc_res_elem *counter_ele; + + counter_buf = (struct ice_aqc_alloc_free_res_elem *) + ice_malloc(hw, buf_len); + if (!counter_buf) { + status = ICE_ERR_NO_MEMORY; + goto ice_alloc_sw_exit; + } + + /* The number of resource entries in buffer is passed as 1 since + * only a single switch/VEB instance is allocated, and hence a + * single VEB counter is requested. + */ + counter_buf->num_elems = CPU_TO_LE16(1); + counter_buf->res_type = + CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER | + ICE_AQC_RES_TYPE_FLAG_DEDICATED); + status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len, + opc, NULL); + + if (status) { + ice_free(hw, counter_buf); + goto ice_alloc_sw_exit; + } + counter_ele = &counter_buf->elem[0]; + *counter_id = LE16_TO_CPU(counter_ele->e.sw_resp); + ice_free(hw, counter_buf); + } + +ice_alloc_sw_exit: + ice_free(hw, sw_buf); + return status; +} + +/** + * ice_free_sw - free resources specific to switch + * @hw: pointer to the HW struct + * @sw_id: switch ID returned + * @counter_id: VEB counter ID returned + * + * free switch resources (SWID and VEB counter) (0x0209) + * + * NOTE: This function frees multiple resources. It continues + * releasing other resources even after it encounters error. + * The error code returned is the last error it encountered. + */ +enum ice_status ice_free_sw(struct ice_hw *hw, u16 sw_id, u16 counter_id) +{ + struct ice_aqc_alloc_free_res_elem *sw_buf, *counter_buf; + enum ice_status status, ret_status; + u16 buf_len; + + buf_len = sizeof(*sw_buf); + sw_buf = (struct ice_aqc_alloc_free_res_elem *) + ice_malloc(hw, buf_len); + if (!sw_buf) + return ICE_ERR_NO_MEMORY; + + /* Prepare buffer to free for switch ID res. + * The number of resource entries in buffer is passed as 1 since only a + * single switch/VEB instance is freed, and hence a single sw_id + * is released. + */ + sw_buf->num_elems = CPU_TO_LE16(1); + sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID); + sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(sw_id); + + ret_status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, + ice_aqc_opc_free_res, NULL); + + if (ret_status) + ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n"); + + /* Prepare buffer to free for VEB Counter resource */ + counter_buf = (struct ice_aqc_alloc_free_res_elem *) + ice_malloc(hw, buf_len); + if (!counter_buf) { + ice_free(hw, sw_buf); + return ICE_ERR_NO_MEMORY; + } + + /* The number of resource entries in buffer is passed as 1 since only a + * single switch/VEB instance is freed, and hence a single VEB counter + * is released + */ + counter_buf->num_elems = CPU_TO_LE16(1); + counter_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER); + counter_buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id); + + status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len, + ice_aqc_opc_free_res, NULL); + if (status) { + ice_debug(hw, ICE_DBG_SW, + "VEB counter resource could not be freed\n"); + ret_status = status; + } + + ice_free(hw, counter_buf); + ice_free(hw, sw_buf); + return ret_status; +} /** * ice_aq_add_vsi diff --git a/drivers/net/ice/base/ice_switch.h b/drivers/net/ice/base/ice_switch.h index 66a172fc2..dd21781f7 100644 --- a/drivers/net/ice/base/ice_switch.h +++ b/drivers/net/ice/base/ice_switch.h @@ -290,6 +290,11 @@ ice_free_vlan_res_counter(struct ice_hw *hw, u16 counter_id); /* Switch/bridge related commands */ enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw); enum ice_status +ice_alloc_sw(struct ice_hw *hw, bool ena_stats, bool shared_res, u16 *sw_id, + u16 *counter_id); +enum ice_status +ice_free_sw(struct ice_hw *hw, u16 sw_id, u16 counter_id); +enum ice_status ice_add_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list); enum ice_status ice_add_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_lst); enum ice_status ice_remove_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_lst);