net/ice: fix flow director programming status check
[dpdk.git] / drivers / net / ice / ice_ethdev.c
index e4fd5bc..2e919c5 100644 (file)
@@ -14,6 +14,8 @@
 #include "base/ice_flow.h"
 #include "base/ice_dcb.h"
 #include "base/ice_common.h"
+
+#include "rte_pmd_ice.h"
 #include "ice_ethdev.h"
 #include "ice_rxtx.h"
 #include "ice_generic_flow.h"
@@ -30,6 +32,37 @@ static const char * const ice_valid_args[] = {
        NULL
 };
 
+static const struct rte_mbuf_dynfield ice_proto_xtr_metadata_param = {
+       .name = "ice_dynfield_proto_xtr_metadata",
+       .size = sizeof(uint32_t),
+       .align = __alignof__(uint32_t),
+       .flags = 0,
+};
+
+struct proto_xtr_ol_flag {
+       const struct rte_mbuf_dynflag param;
+       uint64_t *ol_flag;
+       bool required;
+};
+
+static struct proto_xtr_ol_flag ice_proto_xtr_ol_flag_params[] = {
+       [PROTO_XTR_VLAN] = {
+               .param = { .name = "ice_dynflag_proto_xtr_vlan" },
+               .ol_flag = &rte_net_ice_dynflag_proto_xtr_vlan_mask },
+       [PROTO_XTR_IPV4] = {
+               .param = { .name = "ice_dynflag_proto_xtr_ipv4" },
+               .ol_flag = &rte_net_ice_dynflag_proto_xtr_ipv4_mask },
+       [PROTO_XTR_IPV6] = {
+               .param = { .name = "ice_dynflag_proto_xtr_ipv6" },
+               .ol_flag = &rte_net_ice_dynflag_proto_xtr_ipv6_mask },
+       [PROTO_XTR_IPV6_FLOW] = {
+               .param = { .name = "ice_dynflag_proto_xtr_ipv6_flow" },
+               .ol_flag = &rte_net_ice_dynflag_proto_xtr_ipv6_flow_mask },
+       [PROTO_XTR_TCP] = {
+               .param = { .name = "ice_dynflag_proto_xtr_tcp" },
+               .ol_flag = &rte_net_ice_dynflag_proto_xtr_tcp_mask },
+};
+
 #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100
 
 /* DDP package search path */
@@ -69,9 +102,6 @@ static int ice_dev_set_link_down(struct rte_eth_dev *dev);
 
 static int ice_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 static int ice_vlan_offload_set(struct rte_eth_dev *dev, int mask);
-static int ice_vlan_tpid_set(struct rte_eth_dev *dev,
-                            enum rte_vlan_type vlan_type,
-                            uint16_t tpid);
 static int ice_rss_reta_update(struct rte_eth_dev *dev,
                               struct rte_eth_rss_reta_entry64 *reta_conf,
                               uint16_t reta_size);
@@ -128,6 +158,9 @@ static const struct rte_pci_id pci_id_ice_map[] = {
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810C_BACKPLANE) },
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810C_QSFP) },
        { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810C_SFP) },
+       { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810_XXV_BACKPLANE) },
+       { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810_XXV_QSFP) },
+       { RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E810_XXV_SFP) },
        { .vendor_id = 0, /* sentinel */ },
 };
 
@@ -156,7 +189,6 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
        .mac_addr_remove              = ice_macaddr_remove,
        .vlan_filter_set              = ice_vlan_filter_set,
        .vlan_offload_set             = ice_vlan_offload_set,
-       .vlan_tpid_set                = ice_vlan_tpid_set,
        .reta_update                  = ice_rss_reta_update,
        .reta_query                   = ice_rss_reta_query,
        .rss_hash_update              = ice_rss_hash_update,
@@ -1385,6 +1417,9 @@ ice_init_proto_xtr(struct rte_eth_dev *dev)
                        ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
        struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
        struct ice_hw *hw = ICE_PF_TO_HW(pf);
+       const struct proto_xtr_ol_flag *ol_flag;
+       bool proto_xtr_enable = false;
+       int offset;
        uint16_t i;
 
        if (!ice_proto_xtr_support(hw)) {
@@ -1398,10 +1433,56 @@ ice_init_proto_xtr(struct rte_eth_dev *dev)
                return;
        }
 
-       for (i = 0; i < pf->lan_nb_qps; i++)
+       for (i = 0; i < pf->lan_nb_qps; i++) {
                pf->proto_xtr[i] = ad->devargs.proto_xtr[i] != PROTO_XTR_NONE ?
                                   ad->devargs.proto_xtr[i] :
                                   ad->devargs.proto_xtr_dflt;
+
+               if (pf->proto_xtr[i] != PROTO_XTR_NONE) {
+                       uint8_t type = pf->proto_xtr[i];
+
+                       ice_proto_xtr_ol_flag_params[type].required = true;
+                       proto_xtr_enable = true;
+               }
+       }
+
+       if (likely(!proto_xtr_enable))
+               return;
+
+       offset = rte_mbuf_dynfield_register(&ice_proto_xtr_metadata_param);
+       if (unlikely(offset == -1)) {
+               PMD_DRV_LOG(ERR,
+                           "Protocol extraction metadata is disabled in mbuf with error %d",
+                           -rte_errno);
+               return;
+       }
+
+       PMD_DRV_LOG(DEBUG,
+                   "Protocol extraction metadata offset in mbuf is : %d",
+                   offset);
+       rte_net_ice_dynfield_proto_xtr_metadata_offs = offset;
+
+       for (i = 0; i < RTE_DIM(ice_proto_xtr_ol_flag_params); i++) {
+               ol_flag = &ice_proto_xtr_ol_flag_params[i];
+
+               if (!ol_flag->required)
+                       continue;
+
+               offset = rte_mbuf_dynflag_register(&ol_flag->param);
+               if (unlikely(offset == -1)) {
+                       PMD_DRV_LOG(ERR,
+                                   "Protocol extraction offload '%s' failed to register with error %d",
+                                   ol_flag->param.name, -rte_errno);
+
+                       rte_net_ice_dynfield_proto_xtr_metadata_offs = -1;
+                       break;
+               }
+
+               PMD_DRV_LOG(DEBUG,
+                           "Protocol extraction offload '%s' offset in mbuf is : %d",
+                           ol_flag->param.name, offset);
+               *ol_flag->ol_flag = 1ULL << offset;
+       }
 }
 
 /*  Initialize SW parameters of PF */
@@ -2161,10 +2242,12 @@ ice_dev_init(struct rte_eth_dev *dev)
        /* get base queue pairs index  in the device */
        ice_base_queue_get(pf);
 
-       ret = ice_flow_init(ad);
-       if (ret) {
-               PMD_INIT_LOG(ERR, "Failed to initialize flow");
-               return ret;
+       if (!ad->is_safe_mode) {
+               ret = ice_flow_init(ad);
+               if (ret) {
+                       PMD_INIT_LOG(ERR, "Failed to initialize flow");
+                       return ret;
+               }
        }
 
        ret = ice_reset_fxp_resource(hw);
@@ -2277,7 +2360,10 @@ ice_dev_stop(struct rte_eth_dev *dev)
        /* Clear all queues and release mbufs */
        ice_clear_queues(dev);
 
-       ice_dev_set_link_down(dev);
+       if (pf->init_link_up)
+               ice_dev_set_link_up(dev);
+       else
+               ice_dev_set_link_down(dev);
 
        /* Clean datapath event and queue/vec mapping */
        rte_intr_efd_disable(intr_handle);
@@ -2308,7 +2394,8 @@ ice_dev_close(struct rte_eth_dev *dev)
 
        ice_dev_stop(dev);
 
-       ice_flow_uninit(ad);
+       if (!ad->is_safe_mode)
+               ice_flow_uninit(ad);
 
        /* release all queue resource */
        ice_free_queues(dev);
@@ -2316,6 +2403,7 @@ ice_dev_close(struct rte_eth_dev *dev)
        ice_res_pool_destroy(&pf->msix_pool);
        ice_release_vsi(pf->main_vsi);
        ice_sched_cleanup_all(hw);
+       ice_free_hw_tbls(hw);
        rte_free(hw->port_info);
        hw->port_info = NULL;
        ice_shutdown_all_ctrlq(hw);
@@ -2357,6 +2445,9 @@ ice_dev_configure(struct rte_eth_dev *dev)
        ad->rx_bulk_alloc_allowed = true;
        ad->tx_simple_allowed = true;
 
+       if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
+               dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;
+
        return 0;
 }
 
@@ -2370,6 +2461,7 @@ static int ice_init_rss(struct ice_pf *pf)
        uint16_t i, nb_q;
        int ret = 0;
        bool is_safe_mode = pf->adapter->is_safe_mode;
+       uint32_t reg;
 
        rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
        nb_q = dev->data->nb_rx_queues;
@@ -2413,6 +2505,12 @@ static int ice_init_rss(struct ice_pf *pf)
        if (ret)
                return -EINVAL;
 
+       /* Enable registers for symmetric_toeplitz function. */
+       reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
+       reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) |
+               (1 << VSIQF_HASH_CTL_HASH_SCHEME_S);
+       ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg);
+
        /* configure RSS for IPv4 with input set IPv4 src/dst */
        ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4,
                              ICE_FLOW_SEG_HDR_IPV4, 0);
@@ -2463,6 +2561,23 @@ static int ice_init_rss(struct ice_pf *pf)
                PMD_DRV_LOG(ERR, "%s SCTP_IPV4 rss flow fail %d",
                                __func__, ret);
 
+       /* configure RSS for gtpu with input set TEID */
+       ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_GTP_U_IPV4_TEID,
+                               ICE_FLOW_SEG_HDR_GTPU_IP, 0);
+       if (ret)
+               PMD_DRV_LOG(ERR, "%s GTPU_TEID rss flow fail %d",
+                               __func__, ret);
+
+       /**
+        * configure RSS for pppoe/pppod with input set
+        * Source MAC and Session ID
+        */
+       ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_PPPOE_SESS_ID_ETH,
+                               ICE_FLOW_SEG_HDR_PPPOE, 0);
+       if (ret)
+               PMD_DRV_LOG(ERR, "%s PPPoE/PPPoD_SessionID rss flow fail %d",
+                               __func__, ret);
+
        return 0;
 }
 
@@ -2615,6 +2730,7 @@ ice_rxq_intr_setup(struct rte_eth_dev *dev)
 
        /* Enable FDIR MSIX interrupt */
        if (pf->fdir.fdir_vsi) {
+               pf->fdir.fdir_vsi->nb_used_qps = 1;
                ice_vsi_queues_bind_intr(pf->fdir.fdir_vsi);
                ice_vsi_enable_queues_intr(pf->fdir.fdir_vsi);
        }
@@ -2624,6 +2740,27 @@ ice_rxq_intr_setup(struct rte_eth_dev *dev)
        return 0;
 }
 
+static void
+ice_get_init_link_status(struct rte_eth_dev *dev)
+{
+       struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+       bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
+       struct ice_link_status link_status;
+       int ret;
+
+       ret = ice_aq_get_link_info(hw->port_info, enable_lse,
+                                  &link_status, NULL);
+       if (ret != ICE_SUCCESS) {
+               PMD_DRV_LOG(ERR, "Failed to get link info");
+               pf->init_link_up = false;
+               return;
+       }
+
+       if (link_status.link_info & ICE_AQ_LINK_UP)
+               pf->init_link_up = true;
+}
+
 static int
 ice_dev_start(struct rte_eth_dev *dev)
 {
@@ -2633,6 +2770,7 @@ ice_dev_start(struct rte_eth_dev *dev)
        struct ice_vsi *vsi = pf->main_vsi;
        uint16_t nb_rxq = 0;
        uint16_t nb_txq, i;
+       uint16_t max_frame_size;
        int mask, ret;
 
        /* program Tx queues' context in hardware */
@@ -2693,6 +2831,8 @@ ice_dev_start(struct rte_eth_dev *dev)
        if (ret != ICE_SUCCESS)
                PMD_DRV_LOG(WARNING, "Fail to set phy mask");
 
+       ice_get_init_link_status(dev);
+
        ice_dev_set_link_up(dev);
 
        /* Call get_link_info aq commond to enable/disable LSE */
@@ -2700,6 +2840,14 @@ ice_dev_start(struct rte_eth_dev *dev)
 
        pf->adapter_stopped = false;
 
+       /* Set the max frame size to default value*/
+       max_frame_size = pf->dev_data->dev_conf.rxmode.max_rx_pkt_len ?
+               pf->dev_data->dev_conf.rxmode.max_rx_pkt_len :
+               ICE_FRAME_SIZE_MAX;
+
+       /* Set the max frame size to HW*/
+       ice_aq_set_mac_cfg(hw, max_frame_size, NULL);
+
        return 0;
 
        /* stop the started queues if failed to start all queues */
@@ -2776,7 +2924,8 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                        DEV_RX_OFFLOAD_TCP_CKSUM |
                        DEV_RX_OFFLOAD_QINQ_STRIP |
                        DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
-                       DEV_RX_OFFLOAD_VLAN_EXTEND;
+                       DEV_RX_OFFLOAD_VLAN_EXTEND |
+                       DEV_RX_OFFLOAD_RSS_HASH;
                dev_info->tx_offload_capa |=
                        DEV_TX_OFFLOAD_QINQ_INSERT |
                        DEV_TX_OFFLOAD_IPV4_CKSUM |
@@ -3316,56 +3465,6 @@ ice_vlan_offload_set(struct rte_eth_dev *dev, int mask)
        return 0;
 }
 
-static int
-ice_vlan_tpid_set(struct rte_eth_dev *dev,
-                 enum rte_vlan_type vlan_type,
-                 uint16_t tpid)
-{
-       struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint64_t reg_r = 0, reg_w = 0;
-       uint16_t reg_id = 0;
-       int ret = 0;
-       int qinq = dev->data->dev_conf.rxmode.offloads &
-                  DEV_RX_OFFLOAD_VLAN_EXTEND;
-
-       switch (vlan_type) {
-       case ETH_VLAN_TYPE_OUTER:
-               if (qinq)
-                       reg_id = 3;
-               else
-                       reg_id = 5;
-               break;
-       case ETH_VLAN_TYPE_INNER:
-               if (qinq) {
-                       reg_id = 5;
-               } else {
-                       PMD_DRV_LOG(ERR,
-                                   "Unsupported vlan type in single vlan.");
-                       return -EINVAL;
-               }
-               break;
-       default:
-               PMD_DRV_LOG(ERR, "Unsupported vlan type %d", vlan_type);
-               return -EINVAL;
-       }
-       reg_r = ICE_READ_REG(hw, GL_SWT_L2TAGCTRL(reg_id));
-       PMD_DRV_LOG(DEBUG, "Debug read from ICE GL_SWT_L2TAGCTRL[%d]: "
-                   "0x%08"PRIx64"", reg_id, reg_r);
-
-       reg_w = reg_r & (~(GL_SWT_L2TAGCTRL_ETHERTYPE_M));
-       reg_w |= ((uint64_t)tpid << GL_SWT_L2TAGCTRL_ETHERTYPE_S);
-       if (reg_r == reg_w) {
-               PMD_DRV_LOG(DEBUG, "No need to write");
-               return 0;
-       }
-
-       ICE_WRITE_REG(hw, GL_SWT_L2TAGCTRL(reg_id), reg_w);
-       PMD_DRV_LOG(DEBUG, "Debug write 0x%08"PRIx64" to "
-                   "ICE GL_SWT_L2TAGCTRL[%d]", reg_w, reg_id);
-
-       return ret;
-}
-
 static int
 ice_get_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size)
 {