Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_main.c
index aa4fb50..aebcf73 100644 (file)
@@ -45,7 +45,6 @@
 #include "en_tc.h"
 #include "en_rep.h"
 #include "en_accel/ipsec.h"
-#include "en_accel/ipsec_rxtx.h"
 #include "en_accel/en_accel.h"
 #include "en_accel/tls.h"
 #include "accel/ipsec.h"
@@ -65,7 +64,6 @@
 #include "en/hv_vhca_stats.h"
 #include "en/devlink.h"
 #include "lib/mlx5.h"
-#include "fpga/ipsec.h"
 
 bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
 {
@@ -276,7 +274,7 @@ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
        MLX5_SET(mkc, mkc, lw, 1);
        MLX5_SET(mkc, mkc, lr, 1);
        MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT);
-
+       mlx5e_mkey_set_relaxed_ordering(mdev, mkc);
        MLX5_SET(mkc, mkc, qpn, 0xffffff);
        MLX5_SET(mkc, mkc, pd, mdev->mlx5e_res.pdn);
        MLX5_SET64(mkc, mkc, len, npages << page_shift);
@@ -419,7 +417,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
                err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->mpwqe.wq,
                                        &rq->wq_ctrl);
                if (err)
-                       return err;
+                       goto err_rq_wq_destroy;
 
                rq->mpwqe.wq.db = &rq->mpwqe.wq.db[MLX5_RCV_DBR];
 
@@ -428,29 +426,6 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
                pool_size = MLX5_MPWRQ_PAGES_PER_WQE <<
                        mlx5e_mpwqe_get_log_rq_size(params, xsk);
 
-               rq->post_wqes = mlx5e_post_rx_mpwqes;
-               rq->dealloc_wqe = mlx5e_dealloc_rx_mpwqe;
-
-               rq->handle_rx_cqe = c->priv->profile->rx_handlers.handle_rx_cqe_mpwqe;
-#ifdef CONFIG_MLX5_EN_IPSEC
-               if (MLX5_IPSEC_DEV(mdev)) {
-                       err = -EINVAL;
-                       netdev_err(c->netdev, "MPWQE RQ with IPSec offload not supported\n");
-                       goto err_rq_wq_destroy;
-               }
-#endif
-               if (!rq->handle_rx_cqe) {
-                       err = -EINVAL;
-                       netdev_err(c->netdev, "RX handler of MPWQE RQ is not set, err %d\n", err);
-                       goto err_rq_wq_destroy;
-               }
-
-               rq->mpwqe.skb_from_cqe_mpwrq = xsk ?
-                       mlx5e_xsk_skb_from_cqe_mpwrq_linear :
-                       mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL) ?
-                               mlx5e_skb_from_cqe_mpwrq_linear :
-                               mlx5e_skb_from_cqe_mpwrq_nonlinear;
-
                rq->mpwqe.log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk);
                rq->mpwqe.num_strides =
                        BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk));
@@ -470,7 +445,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
                err = mlx5_wq_cyc_create(mdev, &rqp->wq, rqc_wq, &rq->wqe.wq,
                                         &rq->wq_ctrl);
                if (err)
-                       return err;
+                       goto err_rq_wq_destroy;
 
                rq->wqe.wq.db = &rq->wqe.wq.db[MLX5_RCV_DBR];
 
@@ -492,30 +467,13 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
                if (err)
                        goto err_free;
 
-               rq->post_wqes = mlx5e_post_rx_wqes;
-               rq->dealloc_wqe = mlx5e_dealloc_rx_wqe;
-
-#ifdef CONFIG_MLX5_EN_IPSEC
-               if ((mlx5_fpga_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_DEVICE) &&
-                   c->priv->ipsec)
-                       rq->handle_rx_cqe = mlx5e_ipsec_handle_rx_cqe;
-               else
-#endif
-                       rq->handle_rx_cqe = c->priv->profile->rx_handlers.handle_rx_cqe;
-               if (!rq->handle_rx_cqe) {
-                       err = -EINVAL;
-                       netdev_err(c->netdev, "RX handler of RQ is not set, err %d\n", err);
-                       goto err_free;
-               }
-
-               rq->wqe.skb_from_cqe = xsk ?
-                       mlx5e_xsk_skb_from_cqe_linear :
-                       mlx5e_rx_is_linear_skb(params, NULL) ?
-                               mlx5e_skb_from_cqe_linear :
-                               mlx5e_skb_from_cqe_nonlinear;
                rq->mkey_be = c->mkey_be;
        }
 
+       err = mlx5e_rq_set_handlers(rq, params, xsk);
+       if (err)
+               goto err_free;
+
        if (xsk) {
                err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
                                                 MEM_TYPE_XSK_BUFF_POOL, NULL);
@@ -3104,6 +3062,25 @@ void mlx5e_timestamp_init(struct mlx5e_priv *priv)
        priv->tstamp.rx_filter = HWTSTAMP_FILTER_NONE;
 }
 
+static void mlx5e_modify_admin_state(struct mlx5_core_dev *mdev,
+                                    enum mlx5_port_status state)
+{
+       struct mlx5_eswitch *esw = mdev->priv.eswitch;
+       int vport_admin_state;
+
+       mlx5_set_port_admin_status(mdev, state);
+
+       if (!MLX5_ESWITCH_MANAGER(mdev) ||  mlx5_eswitch_mode(esw) == MLX5_ESWITCH_OFFLOADS)
+               return;
+
+       if (state == MLX5_PORT_UP)
+               vport_admin_state = MLX5_VPORT_ADMIN_STATE_AUTO;
+       else
+               vport_admin_state = MLX5_VPORT_ADMIN_STATE_DOWN;
+
+       mlx5_eswitch_set_vport_state(esw, MLX5_VPORT_UPLINK, vport_admin_state);
+}
+
 int mlx5e_open_locked(struct net_device *netdev)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -3136,7 +3113,7 @@ int mlx5e_open(struct net_device *netdev)
        mutex_lock(&priv->state_lock);
        err = mlx5e_open_locked(netdev);
        if (!err)
-               mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
+               mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_UP);
        mutex_unlock(&priv->state_lock);
 
        return err;
@@ -3170,7 +3147,7 @@ int mlx5e_close(struct net_device *netdev)
                return -ENODEV;
 
        mutex_lock(&priv->state_lock);
-       mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_DOWN);
+       mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_DOWN);
        err = mlx5e_close_locked(netdev);
        mutex_unlock(&priv->state_lock);
 
@@ -4214,83 +4191,6 @@ int mlx5e_get_vf_stats(struct net_device *dev,
 }
 #endif
 
-struct mlx5e_vxlan_work {
-       struct work_struct      work;
-       struct mlx5e_priv       *priv;
-       u16                     port;
-};
-
-static void mlx5e_vxlan_add_work(struct work_struct *work)
-{
-       struct mlx5e_vxlan_work *vxlan_work =
-               container_of(work, struct mlx5e_vxlan_work, work);
-       struct mlx5e_priv *priv = vxlan_work->priv;
-       u16 port = vxlan_work->port;
-
-       mutex_lock(&priv->state_lock);
-       mlx5_vxlan_add_port(priv->mdev->vxlan, port);
-       mutex_unlock(&priv->state_lock);
-
-       kfree(vxlan_work);
-}
-
-static void mlx5e_vxlan_del_work(struct work_struct *work)
-{
-       struct mlx5e_vxlan_work *vxlan_work =
-               container_of(work, struct mlx5e_vxlan_work, work);
-       struct mlx5e_priv *priv         = vxlan_work->priv;
-       u16 port = vxlan_work->port;
-
-       mutex_lock(&priv->state_lock);
-       mlx5_vxlan_del_port(priv->mdev->vxlan, port);
-       mutex_unlock(&priv->state_lock);
-       kfree(vxlan_work);
-}
-
-static void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
-{
-       struct mlx5e_vxlan_work *vxlan_work;
-
-       vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC);
-       if (!vxlan_work)
-               return;
-
-       if (add)
-               INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
-       else
-               INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);
-
-       vxlan_work->priv = priv;
-       vxlan_work->port = port;
-       queue_work(priv->wq, &vxlan_work->work);
-}
-
-void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
-{
-       struct mlx5e_priv *priv = netdev_priv(netdev);
-
-       if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
-               return;
-
-       if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
-               return;
-
-       mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
-}
-
-void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
-{
-       struct mlx5e_priv *priv = netdev_priv(netdev);
-
-       if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
-               return;
-
-       if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
-               return;
-
-       mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
-}
-
 static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
                                                     struct sk_buff *skb,
                                                     netdev_features_t features)
@@ -4602,8 +4502,8 @@ const struct net_device_ops mlx5e_netdev_ops = {
        .ndo_change_mtu          = mlx5e_change_nic_mtu,
        .ndo_do_ioctl            = mlx5e_ioctl,
        .ndo_set_tx_maxrate      = mlx5e_set_tx_maxrate,
-       .ndo_udp_tunnel_add      = mlx5e_add_vxlan_port,
-       .ndo_udp_tunnel_del      = mlx5e_del_vxlan_port,
+       .ndo_udp_tunnel_add      = udp_tunnel_nic_add_port,
+       .ndo_udp_tunnel_del      = udp_tunnel_nic_del_port,
        .ndo_features_check      = mlx5e_features_check,
        .ndo_tx_timeout          = mlx5e_tx_timeout,
        .ndo_bpf                 = mlx5e_xdp,
@@ -4874,6 +4774,39 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
        }
 }
 
+static int mlx5e_vxlan_set_port(struct net_device *netdev, unsigned int table,
+                               unsigned int entry, struct udp_tunnel_info *ti)
+{
+       struct mlx5e_priv *priv = netdev_priv(netdev);
+
+       return mlx5_vxlan_add_port(priv->mdev->vxlan, ntohs(ti->port));
+}
+
+static int mlx5e_vxlan_unset_port(struct net_device *netdev, unsigned int table,
+                                 unsigned int entry, struct udp_tunnel_info *ti)
+{
+       struct mlx5e_priv *priv = netdev_priv(netdev);
+
+       return mlx5_vxlan_del_port(priv->mdev->vxlan, ntohs(ti->port));
+}
+
+void mlx5e_vxlan_set_netdev_info(struct mlx5e_priv *priv)
+{
+       if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
+               return;
+
+       priv->nic_info.set_port = mlx5e_vxlan_set_port;
+       priv->nic_info.unset_port = mlx5e_vxlan_unset_port;
+       priv->nic_info.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
+                               UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN;
+       priv->nic_info.tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN;
+       /* Don't count the space hard-coded to the IANA port */
+       priv->nic_info.tables[0].n_entries =
+               mlx5_vxlan_max_udp_ports(priv->mdev) - 1;
+
+       priv->netdev->udp_tunnel_nic_info = &priv->nic_info;
+}
+
 static void mlx5e_build_nic_netdev(struct net_device *netdev)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4917,6 +4850,8 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
        netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_FILTER;
        netdev->hw_features      |= NETIF_F_HW_VLAN_STAG_TX;
 
+       mlx5e_vxlan_set_netdev_info(priv);
+
        if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev) ||
            mlx5e_any_tunnel_proto_supported(mdev)) {
                netdev->hw_enc_features |= NETIF_F_HW_CSUM;
@@ -5201,7 +5136,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
 
        /* Marking the link as currently not needed by the Driver */
        if (!netif_running(netdev))
-               mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);
+               mlx5e_modify_admin_state(mdev, MLX5_PORT_DOWN);
 
        mlx5e_set_netdev_mtu_boundaries(priv);
        mlx5e_set_dev_port_mtu(priv);
@@ -5222,8 +5157,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
        rtnl_lock();
        if (netif_running(netdev))
                mlx5e_open(netdev);
-       if (mlx5_vxlan_allowed(priv->mdev->vxlan))
-               udp_tunnel_get_rx_info(netdev);
+       udp_tunnel_nic_reset_ntf(priv->netdev);
        netif_device_attach(netdev);
        rtnl_unlock();
 }
@@ -5238,8 +5172,6 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
        rtnl_lock();
        if (netif_running(priv->netdev))
                mlx5e_close(priv->netdev);
-       if (mlx5_vxlan_allowed(priv->mdev->vxlan))
-               udp_tunnel_drop_rx_info(priv->netdev);
        netif_device_detach(priv->netdev);
        rtnl_unlock();
 
@@ -5270,8 +5202,7 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
        .update_rx         = mlx5e_update_nic_rx,
        .update_stats      = mlx5e_update_ndo_stats,
        .update_carrier    = mlx5e_update_carrier,
-       .rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe,
-       .rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
+       .rx_handlers       = &mlx5e_rx_handlers_nic,
        .max_tc            = MLX5E_MAX_NUM_TC,
        .rq_groups         = MLX5E_NUM_RQ_GROUPS(XSK),
        .stats_grps        = mlx5e_nic_stats_grps,
@@ -5409,6 +5340,8 @@ err_cleanup_tx:
        profile->cleanup_tx(priv);
 
 out:
+       set_bit(MLX5E_STATE_DESTROYING, &priv->state);
+       cancel_work_sync(&priv->update_stats_work);
        return err;
 }