Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox...
[linux-block.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_main.c
index 457cc39423f2ba26c6c40798904f5293e55d064f..afbc1e81f36a4ee7252763368500d5e07a693e02 100644 (file)
@@ -545,8 +545,10 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
        }
        err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
                                         MEM_TYPE_PAGE_POOL, rq->page_pool);
-       if (err)
+       if (err) {
+               page_pool_free(rq->page_pool);
                goto err_free;
+       }
 
        for (i = 0; i < wq_sz; i++) {
                if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
@@ -584,11 +586,11 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
 
        switch (params->rx_cq_moderation.cq_period_mode) {
        case MLX5_CQ_PERIOD_MODE_START_FROM_CQE:
-               rq->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE;
+               rq->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_CQE;
                break;
        case MLX5_CQ_PERIOD_MODE_START_FROM_EQE:
        default:
-               rq->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+               rq->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
        }
 
        rq->page_cache.head = 0;
@@ -611,8 +613,6 @@ err_rq_wq_destroy:
        if (rq->xdp_prog)
                bpf_prog_put(rq->xdp_prog);
        xdp_rxq_info_unreg(&rq->xdp_rxq);
-       if (rq->page_pool)
-               page_pool_destroy(rq->page_pool);
        mlx5_wq_destroy(&rq->wq_ctrl);
 
        return err;
@@ -625,10 +625,6 @@ static void mlx5e_free_rq(struct mlx5e_rq *rq)
        if (rq->xdp_prog)
                bpf_prog_put(rq->xdp_prog);
 
-       xdp_rxq_info_unreg(&rq->xdp_rxq);
-       if (rq->page_pool)
-               page_pool_destroy(rq->page_pool);
-
        switch (rq->wq_type) {
        case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
                kvfree(rq->mpwqe.info);
@@ -645,6 +641,8 @@ static void mlx5e_free_rq(struct mlx5e_rq *rq)
 
                mlx5e_page_release(rq, dma_info, false);
        }
+
+       xdp_rxq_info_unreg(&rq->xdp_rxq);
        mlx5_wq_destroy(&rq->wq_ctrl);
 }
 
@@ -1082,6 +1080,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
        sq->clock     = &mdev->clock;
        sq->mkey_be   = c->mkey_be;
        sq->channel   = c;
+       sq->ch_ix     = c->ix;
        sq->txq_ix    = txq_ix;
        sq->uar_map   = mdev->mlx5e_res.bfreg.map;
        sq->min_inline_mode = params->tx_min_inline_mode;
@@ -1517,6 +1516,7 @@ static void mlx5e_free_cq(struct mlx5e_cq *cq)
 
 static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
 {
+       u32 out[MLX5_ST_SZ_DW(create_cq_out)];
        struct mlx5_core_dev *mdev = cq->mdev;
        struct mlx5_core_cq *mcq = &cq->mcq;
 
@@ -1551,7 +1551,7 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
                                            MLX5_ADAPTER_PAGE_SHIFT);
        MLX5_SET64(cqc, cqc, dbr_addr,      cq->wq_ctrl.db.dma);
 
-       err = mlx5_core_create_cq(mdev, mcq, in, inlen);
+       err = mlx5_core_create_cq(mdev, mcq, in, inlen, out, sizeof(out));
 
        kvfree(in);
 
@@ -1569,7 +1569,7 @@ static void mlx5e_destroy_cq(struct mlx5e_cq *cq)
 }
 
 static int mlx5e_open_cq(struct mlx5e_channel *c,
-                        struct net_dim_cq_moder moder,
+                        struct dim_cq_moder moder,
                         struct mlx5e_cq_param *param,
                         struct mlx5e_cq *cq)
 {
@@ -1774,7 +1774,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
                              struct mlx5e_channel **cp)
 {
        int cpu = cpumask_first(mlx5_comp_irq_get_affinity_mask(priv->mdev, ix));
-       struct net_dim_cq_moder icocq_moder = {0, 0};
+       struct dim_cq_moder icocq_moder = {0, 0};
        struct net_device *netdev = priv->netdev;
        struct mlx5e_channel *c;
        unsigned int irq;
@@ -2151,7 +2151,7 @@ static void mlx5e_build_ico_cq_param(struct mlx5e_priv *priv,
 
        mlx5e_build_common_cq_param(priv, param);
 
-       param->cq_period_mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+       param->cq_period_mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
 }
 
 static void mlx5e_build_icosq_param(struct mlx5e_priv *priv,
@@ -2846,7 +2846,7 @@ static void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
        if (hw_modify)
                hw_modify(priv);
 
-       mlx5e_refresh_tirs(priv, false);
+       priv->profile->update_rx(priv);
        mlx5e_activate_priv_channels(priv);
 
        /* return carrier back if needed */
@@ -2893,7 +2893,7 @@ int mlx5e_open_locked(struct net_device *netdev)
        if (err)
                goto err_clear_state_opened_flag;
 
-       mlx5e_refresh_tirs(priv, false);
+       priv->profile->update_rx(priv);
        mlx5e_activate_priv_channels(priv);
        if (priv->profile->update_carrier)
                priv->profile->update_carrier(priv);
@@ -3635,8 +3635,7 @@ static int mlx5e_handle_feature(struct net_device *netdev,
        return 0;
 }
 
-static int mlx5e_set_features(struct net_device *netdev,
-                             netdev_features_t features)
+int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
 {
        netdev_features_t oper_features = netdev->features;
        int err = 0;
@@ -3687,6 +3686,12 @@ static netdev_features_t mlx5e_fix_features(struct net_device *netdev,
                        netdev_warn(netdev, "Disabling LRO, not supported in legacy RQ\n");
        }
 
+       if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)) {
+               features &= ~NETIF_F_RXHASH;
+               if (netdev->features & NETIF_F_RXHASH)
+                       netdev_warn(netdev, "Disabling rxhash, not supported when CQE compress is active\n");
+       }
+
        mutex_unlock(&priv->state_lock);
 
        return features;
@@ -3812,6 +3817,9 @@ int mlx5e_hwstamp_set(struct mlx5e_priv *priv, struct ifreq *ifr)
        memcpy(&priv->tstamp, &config, sizeof(config));
        mutex_unlock(&priv->state_lock);
 
+       /* might need to fix some features */
+       netdev_update_features(priv->netdev);
+
        return copy_to_user(ifr->ifr_data, &config,
                            sizeof(config)) ? -EFAULT : 0;
 }
@@ -4411,9 +4419,9 @@ static bool slow_pci_heuristic(struct mlx5_core_dev *mdev)
                link_speed > MLX5E_SLOW_PCI_RATIO * pci_bw;
 }
 
-static struct net_dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode)
+static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode)
 {
-       struct net_dim_cq_moder moder;
+       struct dim_cq_moder moder;
 
        moder.cq_period_mode = cq_period_mode;
        moder.pkts = MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS;
@@ -4424,9 +4432,9 @@ static struct net_dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode)
        return moder;
 }
 
-static struct net_dim_cq_moder mlx5e_get_def_rx_moderation(u8 cq_period_mode)
+static struct dim_cq_moder mlx5e_get_def_rx_moderation(u8 cq_period_mode)
 {
-       struct net_dim_cq_moder moder;
+       struct dim_cq_moder moder;
 
        moder.cq_period_mode = cq_period_mode;
        moder.pkts = MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS;
@@ -4440,8 +4448,8 @@ static struct net_dim_cq_moder mlx5e_get_def_rx_moderation(u8 cq_period_mode)
 static u8 mlx5_to_net_dim_cq_period_mode(u8 cq_period_mode)
 {
        return cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE ?
-               NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE :
-               NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+               DIM_CQ_PERIOD_MODE_START_FROM_CQE :
+               DIM_CQ_PERIOD_MODE_START_FROM_EQE;
 }
 
 void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
@@ -4581,7 +4589,7 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
 
-       mlx5_query_nic_vport_mac_address(priv->mdev, 0, netdev->dev_addr);
+       mlx5_query_mac_address(priv->mdev, netdev->dev_addr);
        if (is_zero_ether_addr(netdev->dev_addr) &&
            !MLX5_CAP_GEN(priv->mdev, vport_group_manager)) {
                eth_hw_addr_random(netdev);
@@ -4610,14 +4618,18 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
        netdev->ethtool_ops       = &mlx5e_ethtool_ops;
 
        netdev->vlan_features    |= NETIF_F_SG;
-       netdev->vlan_features    |= NETIF_F_IP_CSUM;
-       netdev->vlan_features    |= NETIF_F_IPV6_CSUM;
+       netdev->vlan_features    |= NETIF_F_HW_CSUM;
        netdev->vlan_features    |= NETIF_F_GRO;
        netdev->vlan_features    |= NETIF_F_TSO;
        netdev->vlan_features    |= NETIF_F_TSO6;
        netdev->vlan_features    |= NETIF_F_RXCSUM;
        netdev->vlan_features    |= NETIF_F_RXHASH;
 
+       netdev->mpls_features    |= NETIF_F_SG;
+       netdev->mpls_features    |= NETIF_F_HW_CSUM;
+       netdev->mpls_features    |= NETIF_F_TSO;
+       netdev->mpls_features    |= NETIF_F_TSO6;
+
        netdev->hw_enc_features  |= NETIF_F_HW_VLAN_CTAG_TX;
        netdev->hw_enc_features  |= NETIF_F_HW_VLAN_CTAG_RX;
 
@@ -4633,8 +4645,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 
        if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev) ||
            MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
-               netdev->hw_enc_features |= NETIF_F_IP_CSUM;
-               netdev->hw_enc_features |= NETIF_F_IPV6_CSUM;
+               netdev->hw_enc_features |= NETIF_F_HW_CSUM;
                netdev->hw_enc_features |= NETIF_F_TSO;
                netdev->hw_enc_features |= NETIF_F_TSO6;
                netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
@@ -4680,6 +4691,10 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
        if (!priv->channels.params.scatter_fcs_en)
                netdev->features  &= ~NETIF_F_RXFCS;
 
+       /* prefere CQE compression over rxhash */
+       if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS))
+               netdev->features &= ~NETIF_F_RXHASH;
+
 #define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f)
        if (FT_CAP(flow_modify_en) &&
            FT_CAP(modify_root) &&
@@ -4914,6 +4929,11 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
        mlx5_lag_remove(mdev);
 }
 
+int mlx5e_update_nic_rx(struct mlx5e_priv *priv)
+{
+       return mlx5e_refresh_tirs(priv, false);
+}
+
 static const struct mlx5e_profile mlx5e_nic_profile = {
        .init              = mlx5e_nic_init,
        .cleanup           = mlx5e_nic_cleanup,
@@ -4923,6 +4943,7 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
        .cleanup_tx        = mlx5e_cleanup_nic_tx,
        .enable            = mlx5e_nic_enable,
        .disable           = mlx5e_nic_disable,
+       .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,
@@ -5095,6 +5116,11 @@ static void mlx5e_detach(struct mlx5_core_dev *mdev, void *vpriv)
        struct mlx5e_priv *priv = vpriv;
        struct net_device *netdev = priv->netdev;
 
+#ifdef CONFIG_MLX5_ESWITCH
+       if (MLX5_ESWITCH_MANAGER(mdev) && vpriv == mdev)
+               return;
+#endif
+
        if (!netif_device_present(netdev))
                return;
 
@@ -5115,7 +5141,7 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
 
 #ifdef CONFIG_MLX5_ESWITCH
        if (MLX5_ESWITCH_MANAGER(mdev) &&
-           mlx5_eswitch_mode(mdev->priv.eswitch) == SRIOV_OFFLOADS) {
+           mlx5_eswitch_mode(mdev->priv.eswitch) == MLX5_ESWITCH_OFFLOADS) {
                mlx5e_rep_register_vport_reps(mdev);
                return mdev;
        }