net/mlx5: fix metadata item validation for ingress flows
[dpdk.git] / drivers / net / hns3 / hns3_ethdev.c
index 8c57b63..dbd48de 100644 (file)
@@ -130,7 +130,7 @@ hns3_proc_imp_reset_event(struct hns3_adapter *hns, bool is_delay,
 {
        struct hns3_hw *hw = &hns->hw;
 
-       rte_atomic16_set(&hw->reset.disable_cmd, 1);
+       __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
        hns3_atomic_set_bit(HNS3_IMP_RESET, &hw->reset.pending);
        *vec_val = BIT(HNS3_VECTOR0_IMPRESET_INT_B);
        if (!is_delay) {
@@ -150,7 +150,7 @@ hns3_proc_global_reset_event(struct hns3_adapter *hns, bool is_delay,
 {
        struct hns3_hw *hw = &hns->hw;
 
-       rte_atomic16_set(&hw->reset.disable_cmd, 1);
+       __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
        hns3_atomic_set_bit(HNS3_GLOBAL_RESET, &hw->reset.pending);
        *vec_val = BIT(HNS3_VECTOR0_GLOBALRESET_INT_B);
        if (!is_delay) {
@@ -2343,6 +2343,7 @@ hns3_dev_configure(struct rte_eth_dev *dev)
        uint16_t nb_rx_q = dev->data->nb_rx_queues;
        uint16_t nb_tx_q = dev->data->nb_tx_queues;
        struct rte_eth_rss_conf rss_conf;
+       uint32_t max_rx_pkt_len;
        uint16_t mtu;
        bool gro_en;
        int ret;
@@ -2396,12 +2397,18 @@ hns3_dev_configure(struct rte_eth_dev *dev)
         * according to the maximum RX packet length.
         */
        if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
-               /*
-                * Security of max_rx_pkt_len is guaranteed in dpdk frame.
-                * Maximum value of max_rx_pkt_len is HNS3_MAX_FRAME_LEN, so it
-                * can safely assign to "uint16_t" type variable.
-                */
-               mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(conf->rxmode.max_rx_pkt_len);
+               max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
+               if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
+                   max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
+                       hns3_err(hw, "maximum Rx packet length must be greater "
+                                "than %u and less than %u when jumbo frame enabled.",
+                                (uint16_t)HNS3_DEFAULT_FRAME_LEN,
+                                (uint16_t)HNS3_MAX_FRAME_LEN);
+                       ret = -EINVAL;
+                       goto cfg_err;
+               }
+
+               mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
                ret = hns3_dev_mtu_set(dev, mtu);
                if (ret)
                        goto cfg_err;
@@ -2593,7 +2600,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 
        info->vmdq_queue_num = 0;
 
-       info->reta_size = HNS3_RSS_IND_TBL_SIZE;
+       info->reta_size = hw->rss_ind_tbl_size;
        info->hash_key_size = HNS3_RSS_KEY_SIZE;
        info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT;
 
@@ -2983,6 +2990,20 @@ hns3_parse_dev_specifications(struct hns3_hw *hw, struct hns3_cmd_desc *desc)
        hw->intr.int_ql_max = rte_le_to_cpu_16(req0->intr_ql_max);
 }
 
+static int
+hns3_check_dev_specifications(struct hns3_hw *hw)
+{
+       if (hw->rss_ind_tbl_size == 0 ||
+           hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) {
+               hns3_err(hw, "the size of hash lookup table configured (%u)"
+                             " exceeds the maximum(%u)", hw->rss_ind_tbl_size,
+                             HNS3_RSS_IND_TBL_SIZE_MAX);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int
 hns3_query_dev_specifications(struct hns3_hw *hw)
 {
@@ -3003,7 +3024,7 @@ hns3_query_dev_specifications(struct hns3_hw *hw)
 
        hns3_parse_dev_specifications(hw, desc);
 
-       return 0;
+       return hns3_check_dev_specifications(hw);
 }
 
 static int
@@ -3918,6 +3939,26 @@ hns3_buffer_alloc(struct hns3_hw *hw)
        return ret;
 }
 
+static int
+hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init)
+{
+       struct hns3_firmware_compat_cmd *req;
+       struct hns3_cmd_desc desc;
+       uint32_t compat = 0;
+
+       hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false);
+       req = (struct hns3_firmware_compat_cmd *)desc.data;
+
+       if (is_init) {
+               hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1);
+               hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0);
+       }
+
+       req->compat = rte_cpu_to_le_32(compat);
+
+       return hns3_cmd_send(hw, &desc, 1);
+}
+
 static int
 hns3_mac_init(struct hns3_hw *hw)
 {
@@ -4610,6 +4651,15 @@ hns3_init_hardware(struct hns3_adapter *hns)
                goto err_mac_init;
        }
 
+       /*
+        * Requiring firmware to enable some features, driver can
+        * still work without it.
+        */
+       ret = hns3_firmware_compat_config(hw, true);
+       if (ret)
+               PMD_INIT_LOG(WARNING, "firmware compatible features not "
+                            "supported, ret = %d.", ret);
+
        return 0;
 
 err_mac_init:
@@ -4746,6 +4796,7 @@ hns3_init_pf(struct rte_eth_dev *eth_dev)
 err_enable_intr:
        hns3_fdir_filter_uninit(hns);
 err_fdir:
+       (void)hns3_firmware_compat_config(hw, false);
        hns3_uninit_umv_space(hw);
 err_init_hw:
        hns3_tqp_stats_uninit(hw);
@@ -4780,6 +4831,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev)
        (void)hns3_config_gro(hw, false);
        hns3_promisc_uninit(hw);
        hns3_fdir_filter_uninit(hns);
+       (void)hns3_firmware_compat_config(hw, false);
        hns3_uninit_umv_space(hw);
        hns3_tqp_stats_uninit(hw);
        hns3_pf_disable_irq0(hw);
@@ -5025,7 +5077,7 @@ hns3_do_stop(struct hns3_adapter *hns)
                return ret;
        hw->mac.link_status = ETH_LINK_DOWN;
 
-       if (rte_atomic16_read(&hw->reset.disable_cmd) == 0) {
+       if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) {
                hns3_configure_all_mac_addr(hns, true);
                ret = hns3_reset_all_tqps(hns);
                if (ret) {
@@ -5568,7 +5620,7 @@ hns3_prepare_reset(struct hns3_adapter *hns)
                 * any mailbox handling or command to firmware is only valid
                 * after hns3_cmd_init is called.
                 */
-               rte_atomic16_set(&hw->reset.disable_cmd, 1);
+               __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
                hw->reset.stats.request_cnt++;
                break;
        case HNS3_IMP_RESET:
@@ -5628,7 +5680,7 @@ hns3_stop_service(struct hns3_adapter *hns)
         * from table space. Hence, for function reset software intervention is
         * required to delete the entries
         */
-       if (rte_atomic16_read(&hw->reset.disable_cmd) == 0)
+       if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0)
                hns3_configure_all_mc_mac_addr(hns, true);
        rte_spinlock_unlock(&hw->lock);
 
@@ -5750,8 +5802,10 @@ hns3_reset_service(void *param)
         * The interrupt may have been lost. It is necessary to handle
         * the interrupt to recover from the error.
         */
-       if (rte_atomic16_read(&hns->hw.reset.schedule) == SCHEDULE_DEFERRED) {
-               rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_REQUESTED);
+       if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) ==
+                           SCHEDULE_DEFERRED) {
+               __atomic_store_n(&hw->reset.schedule, SCHEDULE_REQUESTED,
+                                 __ATOMIC_RELAXED);
                hns3_err(hw, "Handling interrupts in delayed tasks");
                hns3_interrupt_handler(&rte_eth_devices[hw->data->port_id]);
                reset_level = hns3_get_reset_level(hns, &hw->reset.pending);
@@ -5760,7 +5814,7 @@ hns3_reset_service(void *param)
                        hns3_atomic_set_bit(HNS3_IMP_RESET, &hw->reset.pending);
                }
        }
-       rte_atomic16_set(&hns->hw.reset.schedule, SCHEDULE_NONE);
+       __atomic_store_n(&hw->reset.schedule, SCHEDULE_NONE, __ATOMIC_RELAXED);
 
        /*
         * Check if there is any ongoing reset in the hardware. This status can
@@ -6280,7 +6334,8 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)
 
        hw->adapter_state = HNS3_NIC_INITIALIZED;
 
-       if (rte_atomic16_read(&hns->hw.reset.schedule) == SCHEDULE_PENDING) {
+       if (__atomic_load_n(&hw->reset.schedule, __ATOMIC_RELAXED) ==
+                           SCHEDULE_PENDING) {
                hns3_err(hw, "Reschedule reset service after dev_init");
                hns3_schedule_reset(hns);
        } else {