net/sfc/base: support equal stride super-buffer Rx mode
[dpdk.git] / drivers / net / qede / qede_ethdev.c
index 6a51e3d..1202300 100644 (file)
@@ -499,6 +499,9 @@ qede_start_vport(struct qede_dev *qdev, uint16_t mtu)
        return 0;
 }
 
+#define QEDE_NPAR_TX_SWITCHING         "npar_tx_switching"
+#define QEDE_VF_TX_SWITCHING           "vf_tx_switching"
+
 /* Activate or deactivate vport via vport-update */
 int qede_activate_vport(struct rte_eth_dev *eth_dev, bool flg)
 {
@@ -516,10 +519,12 @@ int qede_activate_vport(struct rte_eth_dev *eth_dev, bool flg)
        params.vport_active_rx_flg = flg;
        params.vport_active_tx_flg = flg;
        if (!qdev->enable_tx_switching) {
-               if (IS_VF(edev)) {
+               if ((QEDE_NPAR_TX_SWITCHING != NULL) ||
+                   ((QEDE_VF_TX_SWITCHING != NULL) && IS_VF(edev))) {
                        params.update_tx_switching_flg = 1;
                        params.tx_switching_flg = !flg;
-                       DP_INFO(edev, "VF tx-switching is disabled\n");
+                       DP_INFO(edev, "%s tx-switching is disabled\n",
+                               QEDE_NPAR_TX_SWITCHING ? "NPAR" : "VF");
                }
        }
        for_each_hwfn(edev, i) {
@@ -781,6 +786,36 @@ qede_geneve_enable(struct rte_eth_dev *eth_dev, uint8_t clss,
        return rc;
 }
 
+static int
+qede_ipgre_enable(struct rte_eth_dev *eth_dev, uint8_t clss,
+                 bool enable)
+{
+       struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+       struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+       enum _ecore_status_t rc = ECORE_INVAL;
+       struct ecore_tunnel_info tunn;
+
+       memset(&tunn, 0, sizeof(struct ecore_tunnel_info));
+       tunn.ip_gre.b_update_mode = true;
+       tunn.ip_gre.b_mode_enabled = enable;
+       tunn.ip_gre.tun_cls = clss;
+       tunn.ip_gre.tun_cls = clss;
+       tunn.b_update_rx_cls = true;
+       tunn.b_update_tx_cls = true;
+
+       rc = qede_tunnel_update(qdev, &tunn);
+       if (rc == ECORE_SUCCESS) {
+               qdev->ipgre.enable = enable;
+               DP_INFO(edev, "IPGRE is %s\n",
+                       enable ? "enabled" : "disabled");
+       } else {
+               DP_ERR(edev, "Failed to update tunn_clss %u\n",
+                      clss);
+       }
+
+       return rc;
+}
+
 static int
 qede_tunn_enable(struct rte_eth_dev *eth_dev, uint8_t clss,
                 enum rte_eth_tunnel_type tunn_type, bool enable)
@@ -794,6 +829,9 @@ qede_tunn_enable(struct rte_eth_dev *eth_dev, uint8_t clss,
        case RTE_TUNNEL_TYPE_GENEVE:
                rc = qede_geneve_enable(eth_dev, clss, enable);
                break;
+       case RTE_TUNNEL_TYPE_IP_IN_GRE:
+               rc = qede_ipgre_enable(eth_dev, clss, enable);
+               break;
        default:
                rc = -EINVAL;
                break;
@@ -1000,10 +1038,10 @@ qede_mac_addr_remove(struct rte_eth_dev *eth_dev, uint32_t index)
        ether_addr_copy(&eth_dev->data->mac_addrs[index],
                        (struct ether_addr *)&ucast.mac);
 
-       ecore_filter_ucast_cmd(edev, &ucast, ECORE_SPQ_MODE_CB, NULL);
+       qede_mac_int_ops(eth_dev, &ucast, false);
 }
 
-static void
+static int
 qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
 {
        struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
@@ -1012,12 +1050,11 @@ qede_mac_addr_set(struct rte_eth_dev *eth_dev, struct ether_addr *mac_addr)
        if (IS_VF(edev) && !ecore_vf_check_mac(ECORE_LEADING_HWFN(edev),
                                               mac_addr->addr_bytes)) {
                DP_ERR(edev, "Setting MAC address is not allowed\n");
-               ether_addr_copy(&qdev->primary_mac,
-                               &eth_dev->data->mac_addrs[0]);
-               return;
+               return -EPERM;
        }
 
        qede_mac_addr_add(eth_dev, mac_addr, 0, 0);
+       return 0;
 }
 
 static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool flg)
@@ -1337,13 +1374,15 @@ static void qede_dev_stop(struct rte_eth_dev *eth_dev)
        /* Disable traffic */
        ecore_hw_stop_fastpath(edev); /* TBD - loop */
 
+       if (IS_PF(edev))
+               qede_mac_addr_remove(eth_dev, 0);
+
        DP_INFO(edev, "Device is stopped\n");
 }
 
-#define QEDE_TX_SWITCHING              "vf_txswitch"
-
 const char *valid_args[] = {
-       QEDE_TX_SWITCHING,
+       QEDE_NPAR_TX_SWITCHING,
+       QEDE_VF_TX_SWITCHING,
        NULL,
 };
 
@@ -1362,7 +1401,8 @@ static int qede_args_check(const char *key, const char *val, void *opaque)
                return errno;
        }
 
-       if (strcmp(QEDE_TX_SWITCHING, key) == 0)
+       if ((strcmp(QEDE_NPAR_TX_SWITCHING, key) == 0) ||
+           (strcmp(QEDE_VF_TX_SWITCHING, key) == 0))
                qdev->enable_tx_switching = !!tmp;
 
        return ret;
@@ -1508,7 +1548,6 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
 
        PMD_INIT_FUNC_TRACE(edev);
 
-       dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
        dev_info->min_rx_bufsize = (uint32_t)QEDE_MIN_RX_BUFF_SIZE;
        dev_info->max_rx_pktlen = (uint32_t)ETH_TX_MAX_NON_LSO_PKT_LEN;
        dev_info->rx_desc_lim = qede_rx_desc_lim;
@@ -2078,6 +2117,7 @@ qede_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev)
                RTE_PTYPE_TUNNEL_VXLAN,
                RTE_PTYPE_L4_FRAG,
                RTE_PTYPE_TUNNEL_GENEVE,
+               RTE_PTYPE_TUNNEL_GRE,
                /* Inner */
                RTE_PTYPE_INNER_L2_ETHER,
                RTE_PTYPE_INNER_L2_ETHER_VLAN,
@@ -2404,6 +2444,9 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
                dev->data->dev_started = 0;
                qede_dev_stop(dev);
                restart = true;
+       } else {
+               if (IS_PF(edev))
+                       qede_mac_addr_remove(dev, 0);
        }
        rte_delay_ms(1000);
        qede_start_vport(qdev, mtu); /* Recreate vport */
@@ -2431,7 +2474,9 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
                dev->data->dev_conf.rxmode.jumbo_frame = 0;
 
        /* Restore config lost due to vport stop */
-       qede_mac_addr_set(dev, &qdev->primary_mac);
+       if (IS_PF(edev))
+               qede_mac_addr_set(dev, &qdev->primary_mac);
+
        if (dev->data->promiscuous)
                qede_promiscuous_enable(dev);
        else
@@ -2501,7 +2546,6 @@ qede_udp_dst_port_del(struct rte_eth_dev *eth_dev,
                                        ECORE_TUNN_CLSS_MAC_VLAN, false);
 
                break;
-
        case RTE_TUNNEL_TYPE_GENEVE:
                if (qdev->geneve.udp_port != tunnel_udp->udp_port) {
                        DP_ERR(edev, "UDP port %u doesn't exist\n",
@@ -2591,7 +2635,6 @@ qede_udp_dst_port_add(struct rte_eth_dev *eth_dev,
 
                qdev->vxlan.udp_port = udp_port;
                break;
-
        case RTE_TUNNEL_TYPE_GENEVE:
                if (qdev->geneve.udp_port == tunnel_udp->udp_port) {
                        DP_INFO(edev,
@@ -2629,7 +2672,6 @@ qede_udp_dst_port_add(struct rte_eth_dev *eth_dev,
 
                qdev->geneve.udp_port = udp_port;
                break;
-
        default:
                return ECORE_INVAL;
        }
@@ -2795,7 +2837,8 @@ qede_tunn_filter_config(struct rte_eth_dev *eth_dev,
                        qdev->geneve.filter_type = conf->filter_type;
                }
 
-               if (!qdev->vxlan.enable || !qdev->geneve.enable)
+               if (!qdev->vxlan.enable || !qdev->geneve.enable ||
+                   !qdev->ipgre.enable)
                        return qede_tunn_enable(eth_dev, clss,
                                                conf->tunnel_type,
                                                true);
@@ -2831,15 +2874,14 @@ int qede_dev_filter_ctrl(struct rte_eth_dev *eth_dev,
                switch (filter_conf->tunnel_type) {
                case RTE_TUNNEL_TYPE_VXLAN:
                case RTE_TUNNEL_TYPE_GENEVE:
+               case RTE_TUNNEL_TYPE_IP_IN_GRE:
                        DP_INFO(edev,
                                "Packet steering to the specified Rx queue"
                                " is not supported with UDP tunneling");
                        return(qede_tunn_filter_config(eth_dev, filter_op,
                                                      filter_conf));
-               /* Place holders for future tunneling support */
                case RTE_TUNNEL_TYPE_TEREDO:
                case RTE_TUNNEL_TYPE_NVGRE:
-               case RTE_TUNNEL_TYPE_IP_IN_GRE:
                case RTE_L2_TUNNEL_TYPE_E_TAG:
                        DP_ERR(edev, "Unsupported tunnel type %d\n",
                                filter_conf->tunnel_type);
@@ -3138,19 +3180,23 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
        /* VF tunnel offloads is enabled by default in PF driver */
        adapter->vxlan.num_filters = 0;
        adapter->geneve.num_filters = 0;
+       adapter->ipgre.num_filters = 0;
        if (is_vf) {
                adapter->vxlan.enable = true;
                adapter->vxlan.filter_type = ETH_TUNNEL_FILTER_IMAC |
                                             ETH_TUNNEL_FILTER_IVLAN;
                adapter->vxlan.udp_port = QEDE_VXLAN_DEF_PORT;
                adapter->geneve.enable = true;
-
                adapter->geneve.filter_type = ETH_TUNNEL_FILTER_IMAC |
                                              ETH_TUNNEL_FILTER_IVLAN;
                adapter->geneve.udp_port = QEDE_GENEVE_DEF_PORT;
+               adapter->ipgre.enable = true;
+               adapter->ipgre.filter_type = ETH_TUNNEL_FILTER_IMAC |
+                                            ETH_TUNNEL_FILTER_IVLAN;
        } else {
                adapter->vxlan.enable = false;
                adapter->geneve.enable = false;
+               adapter->ipgre.enable = false;
        }
 
        DP_INFO(edev, "MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",