net/hns3: fix mailbox error message
[dpdk.git] / drivers / net / hns3 / hns3_flow.c
index 3e387ac..4511a49 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018-2019 Hisilicon Limited.
+ * Copyright(c) 2018-2021 HiSilicon Limited.
  */
 
 #include <rte_flow_driver.h>
@@ -44,8 +44,7 @@ static enum rte_flow_item_type first_items[] = {
        RTE_FLOW_ITEM_TYPE_NVGRE,
        RTE_FLOW_ITEM_TYPE_VXLAN,
        RTE_FLOW_ITEM_TYPE_GENEVE,
-       RTE_FLOW_ITEM_TYPE_VXLAN_GPE,
-       RTE_FLOW_ITEM_TYPE_MPLS
+       RTE_FLOW_ITEM_TYPE_VXLAN_GPE
 };
 
 static enum rte_flow_item_type L2_next_items[] = {
@@ -65,8 +64,7 @@ static enum rte_flow_item_type L3_next_items[] = {
 static enum rte_flow_item_type L4_next_items[] = {
        RTE_FLOW_ITEM_TYPE_VXLAN,
        RTE_FLOW_ITEM_TYPE_GENEVE,
-       RTE_FLOW_ITEM_TYPE_VXLAN_GPE,
-       RTE_FLOW_ITEM_TYPE_MPLS
+       RTE_FLOW_ITEM_TYPE_VXLAN_GPE
 };
 
 static enum rte_flow_item_type tunnel_next_items[] = {
@@ -160,7 +158,10 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id,
 {
        struct hns3_adapter *hns = dev->data->dev_private;
        struct hns3_pf *pf = &hns->pf;
+       struct hns3_hw *hw = &hns->hw;
        struct hns3_flow_counter *cnt;
+       uint64_t value;
+       int ret;
 
        cnt = hns3_counter_lookup(dev, id);
        if (cnt) {
@@ -173,6 +174,13 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id,
                return 0;
        }
 
+       /* Clear the counter by read ops because the counter is read-clear */
+       ret = hns3_get_count(hw, id, &value);
+       if (ret)
+               return rte_flow_error_set(error, EIO,
+                                         RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+                                         "Clear counter failed!");
+
        cnt = rte_zmalloc("hns3 counter", sizeof(*cnt), 0);
        if (cnt == NULL)
                return rte_flow_error_set(error, ENOMEM,
@@ -1118,8 +1126,7 @@ is_tunnel_packet(enum rte_flow_item_type type)
        if (type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE ||
            type == RTE_FLOW_ITEM_TYPE_VXLAN ||
            type == RTE_FLOW_ITEM_TYPE_NVGRE ||
-           type == RTE_FLOW_ITEM_TYPE_GENEVE ||
-           type == RTE_FLOW_ITEM_TYPE_MPLS)
+           type == RTE_FLOW_ITEM_TYPE_GENEVE)
                return true;
        return false;
 }
@@ -1207,9 +1214,18 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev,
 }
 
 void
-hns3_filterlist_init(struct rte_eth_dev *dev)
+hns3_flow_init(struct rte_eth_dev *dev)
 {
+       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct hns3_process_private *process_list = dev->process_private;
+       pthread_mutexattr_t attr;
+
+       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+               pthread_mutexattr_init(&attr);
+               pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+               pthread_mutex_init(&hw->flows_lock, &attr);
+               dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE;
+       }
 
        TAILQ_INIT(&process_list->fdir_list);
        TAILQ_INIT(&process_list->filter_rss_list);
@@ -1489,14 +1505,14 @@ hns3_update_indir_table(struct rte_eth_dev *dev,
 {
        struct hns3_adapter *hns = dev->data->dev_private;
        struct hns3_hw *hw = &hns->hw;
-       uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE];
+       uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE_MAX];
        uint16_t j;
        uint32_t i;
 
        /* Fill in redirection table */
        memcpy(indir_tbl, hw->rss_info.rss_indirection_tbl,
               sizeof(hw->rss_info.rss_indirection_tbl));
-       for (i = 0, j = 0; i < HNS3_RSS_IND_TBL_SIZE; i++, j++) {
+       for (i = 0, j = 0; i < hw->rss_ind_tbl_size; i++, j++) {
                j %= num;
                if (conf->queue[j] >= hw->alloc_rss_size) {
                        hns3_err(hw, "queue id(%u) set to redirection table "
@@ -1507,7 +1523,7 @@ hns3_update_indir_table(struct rte_eth_dev *dev,
                indir_tbl[i] = conf->queue[j];
        }
 
-       return hns3_set_rss_indir_table(hw, indir_tbl, HNS3_RSS_IND_TBL_SIZE);
+       return hns3_set_rss_indir_table(hw, indir_tbl, hw->rss_ind_tbl_size);
 }
 
 static int
@@ -1809,17 +1825,18 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 
                flow->counter_id = fdir_rule.act_cnt.id;
        }
+
+       fdir_rule_ptr = rte_zmalloc("hns3 fdir rule",
+                                   sizeof(struct hns3_fdir_rule_ele),
+                                   0);
+       if (fdir_rule_ptr == NULL) {
+               hns3_err(hw, "failed to allocate fdir_rule memory.");
+               ret = -ENOMEM;
+               goto err_fdir;
+       }
+
        ret = hns3_fdir_filter_program(hns, &fdir_rule, false);
        if (!ret) {
-               fdir_rule_ptr = rte_zmalloc("hns3 fdir rule",
-                                           sizeof(struct hns3_fdir_rule_ele),
-                                           0);
-               if (fdir_rule_ptr == NULL) {
-                       hns3_err(hw, "Failed to allocate fdir_rule memory");
-                       ret = -ENOMEM;
-                       goto err_fdir;
-               }
-
                memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule,
                        sizeof(struct hns3_fdir_rule));
                TAILQ_INSERT_TAIL(&process_list->fdir_list,
@@ -1830,10 +1847,10 @@ hns3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                return flow;
        }
 
+       rte_free(fdir_rule_ptr);
 err_fdir:
        if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER)
                hns3_counter_release(dev, fdir_rule.act_cnt.id);
-
 err:
        rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
                           "Failed to create flow");
@@ -1994,43 +2011,100 @@ hns3_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow,
        return 0;
 }
 
+static int
+hns3_flow_validate_wrap(struct rte_eth_dev *dev,
+                       const struct rte_flow_attr *attr,
+                       const struct rte_flow_item pattern[],
+                       const struct rte_flow_action actions[],
+                       struct rte_flow_error *error)
+{
+       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       int ret;
+
+       pthread_mutex_lock(&hw->flows_lock);
+       ret = hns3_flow_validate(dev, attr, pattern, actions, error);
+       pthread_mutex_unlock(&hw->flows_lock);
+
+       return ret;
+}
+
+static struct rte_flow *
+hns3_flow_create_wrap(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
+                     const struct rte_flow_item pattern[],
+                     const struct rte_flow_action actions[],
+                     struct rte_flow_error *error)
+{
+       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct rte_flow *flow;
+
+       pthread_mutex_lock(&hw->flows_lock);
+       flow = hns3_flow_create(dev, attr, pattern, actions, error);
+       pthread_mutex_unlock(&hw->flows_lock);
+
+       return flow;
+}
+
+static int
+hns3_flow_destroy_wrap(struct rte_eth_dev *dev, struct rte_flow *flow,
+                      struct rte_flow_error *error)
+{
+       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       int ret;
+
+       pthread_mutex_lock(&hw->flows_lock);
+       ret = hns3_flow_destroy(dev, flow, error);
+       pthread_mutex_unlock(&hw->flows_lock);
+
+       return ret;
+}
+
+static int
+hns3_flow_flush_wrap(struct rte_eth_dev *dev, struct rte_flow_error *error)
+{
+       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       int ret;
+
+       pthread_mutex_lock(&hw->flows_lock);
+       ret = hns3_flow_flush(dev, error);
+       pthread_mutex_unlock(&hw->flows_lock);
+
+       return ret;
+}
+
+static int
+hns3_flow_query_wrap(struct rte_eth_dev *dev, struct rte_flow *flow,
+                    const struct rte_flow_action *actions, void *data,
+                    struct rte_flow_error *error)
+{
+       struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       int ret;
+
+       pthread_mutex_lock(&hw->flows_lock);
+       ret = hns3_flow_query(dev, flow, actions, data, error);
+       pthread_mutex_unlock(&hw->flows_lock);
+
+       return ret;
+}
+
 static const struct rte_flow_ops hns3_flow_ops = {
-       .validate = hns3_flow_validate,
-       .create = hns3_flow_create,
-       .destroy = hns3_flow_destroy,
-       .flush = hns3_flow_flush,
-       .query = hns3_flow_query,
+       .validate = hns3_flow_validate_wrap,
+       .create = hns3_flow_create_wrap,
+       .destroy = hns3_flow_destroy_wrap,
+       .flush = hns3_flow_flush_wrap,
+       .query = hns3_flow_query_wrap,
        .isolate = NULL,
 };
 
-/*
- * The entry of flow API.
- * @param dev
- *   Pointer to Ethernet device.
- * @return
- *   0 on success, a negative errno value otherwise is set.
- */
 int
-hns3_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type,
-                    enum rte_filter_op filter_op, void *arg)
+hns3_dev_flow_ops_get(struct rte_eth_dev *dev,
+                     const struct rte_flow_ops **ops)
 {
        struct hns3_hw *hw;
-       int ret = 0;
 
        hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       switch (filter_type) {
-       case RTE_ETH_FILTER_GENERIC:
-               if (filter_op != RTE_ETH_FILTER_GET)
-                       return -EINVAL;
-               if (hw->adapter_state >= HNS3_NIC_CLOSED)
-                       return -ENODEV;
-               *(const void **)arg = &hns3_flow_ops;
-               break;
-       default:
-               hns3_err(hw, "Filter type (%d) not supported", filter_type);
-               ret = -EOPNOTSUPP;
-               break;
-       }
+       if (hw->adapter_state >= HNS3_NIC_CLOSED)
+               return -ENODEV;
 
-       return ret;
+       *ops = &hns3_flow_ops;
+       return 0;
 }