[v3,01/38] net/ice/base: add switch resource allocation and free
Checks
Commit Message
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 <paul.m.stillwell.jr@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
drivers/net/ice/base/ice_switch.c | 150 ++++++++++++++++++++++++++++++++++++++
drivers/net/ice/base/ice_switch.h | 5 ++
2 files changed, 155 insertions(+)
Comments
> -----Original Message-----
> From: Zhang, Qi Z
> Sent: Monday, March 11, 2019 3:04 PM
> To: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>
> Cc: dev@dpdk.org; Stillwell Jr, Paul M <paul.m.stillwell.jr@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> Subject: [PATCH v3 01/38] net/ice/base: add switch resource allocation and
> free
>
> 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.
>
Is or are?
> Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
> ---
> 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);
> --
> 2.13.6
@@ -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
@@ -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);