root/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mlx5i_build_nic_params
  2. mlx5i_init
  3. mlx5i_cleanup
  4. mlx5i_grp_sw_update_stats
  5. mlx5i_get_stats
  6. mlx5i_init_underlay_qp
  7. mlx5i_uninit_underlay_qp
  8. mlx5i_create_underlay_qp
  9. mlx5i_destroy_underlay_qp
  10. mlx5i_create_tis
  11. mlx5i_init_tx
  12. mlx5i_cleanup_tx
  13. mlx5i_create_flow_steering
  14. mlx5i_destroy_flow_steering
  15. mlx5i_init_rx
  16. mlx5i_cleanup_rx
  17. mlx5i_change_mtu
  18. mlx5i_dev_init
  19. mlx5i_ioctl
  20. mlx5i_dev_cleanup
  21. mlx5i_open
  22. mlx5i_close
  23. mlx5i_attach_mcast
  24. mlx5i_detach_mcast
  25. mlx5i_xmit
  26. mlx5i_set_pkey_index
  27. mlx5i_check_required_hca_cap
  28. mlx5_rdma_netdev_free
  29. mlx5_is_sub_interface
  30. mlx5_get_profile
  31. mlx5_rdma_setup_rn
  32. mlx5_rdma_rn_get_params

   1 /*
   2  * Copyright (c) 2017, Mellanox Technologies. All rights reserved.
   3  *
   4  * This software is available to you under a choice of one of two
   5  * licenses.  You may choose to be licensed under the terms of the GNU
   6  * General Public License (GPL) Version 2, available from the file
   7  * COPYING in the main directory of this source tree, or the
   8  * OpenIB.org BSD license below:
   9  *
  10  *     Redistribution and use in source and binary forms, with or
  11  *     without modification, are permitted provided that the following
  12  *     conditions are met:
  13  *
  14  *      - Redistributions of source code must retain the above
  15  *        copyright notice, this list of conditions and the following
  16  *        disclaimer.
  17  *
  18  *      - Redistributions in binary form must reproduce the above
  19  *        copyright notice, this list of conditions and the following
  20  *        disclaimer in the documentation and/or other materials
  21  *        provided with the distribution.
  22  *
  23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30  * SOFTWARE.
  31  */
  32 
  33 #include <rdma/ib_verbs.h>
  34 #include <linux/mlx5/fs.h>
  35 #include "en.h"
  36 #include "ipoib.h"
  37 
  38 #define IB_DEFAULT_Q_KEY   0xb1b
  39 #define MLX5I_PARAMS_DEFAULT_LOG_RQ_SIZE 9
  40 
  41 static int mlx5i_open(struct net_device *netdev);
  42 static int mlx5i_close(struct net_device *netdev);
  43 static int mlx5i_change_mtu(struct net_device *netdev, int new_mtu);
  44 
  45 static const struct net_device_ops mlx5i_netdev_ops = {
  46         .ndo_open                = mlx5i_open,
  47         .ndo_stop                = mlx5i_close,
  48         .ndo_get_stats64         = mlx5i_get_stats,
  49         .ndo_init                = mlx5i_dev_init,
  50         .ndo_uninit              = mlx5i_dev_cleanup,
  51         .ndo_change_mtu          = mlx5i_change_mtu,
  52         .ndo_do_ioctl            = mlx5i_ioctl,
  53 };
  54 
  55 /* IPoIB mlx5 netdev profile */
  56 static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
  57                                    struct mlx5e_params *params)
  58 {
  59         /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */
  60         MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ, false);
  61         mlx5e_set_rq_type(mdev, params);
  62         mlx5e_init_rq_type_params(mdev, params);
  63 
  64         /* RQ size in ipoib by default is 512 */
  65         params->log_rq_mtu_frames = is_kdump_kernel() ?
  66                 MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE :
  67                 MLX5I_PARAMS_DEFAULT_LOG_RQ_SIZE;
  68 
  69         params->lro_en = false;
  70         params->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
  71         params->tunneled_offload_en = false;
  72 }
  73 
  74 /* Called directly after IPoIB netdevice was created to initialize SW structs */
  75 int mlx5i_init(struct mlx5_core_dev *mdev,
  76                struct net_device *netdev,
  77                const struct mlx5e_profile *profile,
  78                void *ppriv)
  79 {
  80         struct mlx5e_priv *priv  = mlx5i_epriv(netdev);
  81         int err;
  82 
  83         err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
  84         if (err)
  85                 return err;
  86 
  87         mlx5e_set_netdev_mtu_boundaries(priv);
  88         netdev->mtu = netdev->max_mtu;
  89 
  90         mlx5e_build_nic_params(mdev, NULL, &priv->rss_params, &priv->channels.params,
  91                                priv->max_nch, netdev->mtu);
  92         mlx5i_build_nic_params(mdev, &priv->channels.params);
  93 
  94         mlx5e_timestamp_init(priv);
  95 
  96         /* netdev init */
  97         netdev->hw_features    |= NETIF_F_SG;
  98         netdev->hw_features    |= NETIF_F_IP_CSUM;
  99         netdev->hw_features    |= NETIF_F_IPV6_CSUM;
 100         netdev->hw_features    |= NETIF_F_GRO;
 101         netdev->hw_features    |= NETIF_F_TSO;
 102         netdev->hw_features    |= NETIF_F_TSO6;
 103         netdev->hw_features    |= NETIF_F_RXCSUM;
 104         netdev->hw_features    |= NETIF_F_RXHASH;
 105 
 106         netdev->netdev_ops = &mlx5i_netdev_ops;
 107         netdev->ethtool_ops = &mlx5i_ethtool_ops;
 108 
 109         return 0;
 110 }
 111 
 112 /* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */
 113 void mlx5i_cleanup(struct mlx5e_priv *priv)
 114 {
 115         mlx5e_netdev_cleanup(priv->netdev, priv);
 116 }
 117 
 118 static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv)
 119 {
 120         struct mlx5e_sw_stats s = { 0 };
 121         int i, j;
 122 
 123         for (i = 0; i < priv->max_nch; i++) {
 124                 struct mlx5e_channel_stats *channel_stats;
 125                 struct mlx5e_rq_stats *rq_stats;
 126 
 127                 channel_stats = &priv->channel_stats[i];
 128                 rq_stats = &channel_stats->rq;
 129 
 130                 s.rx_packets += rq_stats->packets;
 131                 s.rx_bytes   += rq_stats->bytes;
 132 
 133                 for (j = 0; j < priv->max_opened_tc; j++) {
 134                         struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j];
 135 
 136                         s.tx_packets           += sq_stats->packets;
 137                         s.tx_bytes             += sq_stats->bytes;
 138                         s.tx_queue_dropped     += sq_stats->dropped;
 139                 }
 140         }
 141 
 142         memcpy(&priv->stats.sw, &s, sizeof(s));
 143 }
 144 
 145 void mlx5i_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
 146 {
 147         struct mlx5e_priv     *priv   = mlx5i_epriv(dev);
 148         struct mlx5e_sw_stats *sstats = &priv->stats.sw;
 149 
 150         mlx5i_grp_sw_update_stats(priv);
 151 
 152         stats->rx_packets = sstats->rx_packets;
 153         stats->rx_bytes   = sstats->rx_bytes;
 154         stats->tx_packets = sstats->tx_packets;
 155         stats->tx_bytes   = sstats->tx_bytes;
 156         stats->tx_dropped = sstats->tx_queue_dropped;
 157 }
 158 
 159 int mlx5i_init_underlay_qp(struct mlx5e_priv *priv)
 160 {
 161         struct mlx5_core_dev *mdev = priv->mdev;
 162         struct mlx5i_priv *ipriv = priv->ppriv;
 163         struct mlx5_core_qp *qp = &ipriv->qp;
 164         struct mlx5_qp_context *context;
 165         int ret;
 166 
 167         /* QP states */
 168         context = kzalloc(sizeof(*context), GFP_KERNEL);
 169         if (!context)
 170                 return -ENOMEM;
 171 
 172         context->flags = cpu_to_be32(MLX5_QP_PM_MIGRATED << 11);
 173         context->pri_path.port = 1;
 174         context->pri_path.pkey_index = cpu_to_be16(ipriv->pkey_index);
 175         context->qkey = cpu_to_be32(IB_DEFAULT_Q_KEY);
 176 
 177         ret = mlx5_core_qp_modify(mdev, MLX5_CMD_OP_RST2INIT_QP, 0, context, qp);
 178         if (ret) {
 179                 mlx5_core_err(mdev, "Failed to modify qp RST2INIT, err: %d\n", ret);
 180                 goto err_qp_modify_to_err;
 181         }
 182         memset(context, 0, sizeof(*context));
 183 
 184         ret = mlx5_core_qp_modify(mdev, MLX5_CMD_OP_INIT2RTR_QP, 0, context, qp);
 185         if (ret) {
 186                 mlx5_core_err(mdev, "Failed to modify qp INIT2RTR, err: %d\n", ret);
 187                 goto err_qp_modify_to_err;
 188         }
 189 
 190         ret = mlx5_core_qp_modify(mdev, MLX5_CMD_OP_RTR2RTS_QP, 0, context, qp);
 191         if (ret) {
 192                 mlx5_core_err(mdev, "Failed to modify qp RTR2RTS, err: %d\n", ret);
 193                 goto err_qp_modify_to_err;
 194         }
 195 
 196         kfree(context);
 197         return 0;
 198 
 199 err_qp_modify_to_err:
 200         mlx5_core_qp_modify(mdev, MLX5_CMD_OP_2ERR_QP, 0, &context, qp);
 201         kfree(context);
 202         return ret;
 203 }
 204 
 205 void mlx5i_uninit_underlay_qp(struct mlx5e_priv *priv)
 206 {
 207         struct mlx5i_priv *ipriv = priv->ppriv;
 208         struct mlx5_core_dev *mdev = priv->mdev;
 209         struct mlx5_qp_context context;
 210         int err;
 211 
 212         err = mlx5_core_qp_modify(mdev, MLX5_CMD_OP_2RST_QP, 0, &context,
 213                                   &ipriv->qp);
 214         if (err)
 215                 mlx5_core_err(mdev, "Failed to modify qp 2RST, err: %d\n", err);
 216 }
 217 
 218 #define MLX5_QP_ENHANCED_ULP_STATELESS_MODE 2
 219 
 220 int mlx5i_create_underlay_qp(struct mlx5_core_dev *mdev, struct mlx5_core_qp *qp)
 221 {
 222         u32 *in = NULL;
 223         void *addr_path;
 224         int ret = 0;
 225         int inlen;
 226         void *qpc;
 227 
 228         inlen = MLX5_ST_SZ_BYTES(create_qp_in);
 229         in = kvzalloc(inlen, GFP_KERNEL);
 230         if (!in)
 231                 return -ENOMEM;
 232 
 233         qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
 234         MLX5_SET(qpc, qpc, st, MLX5_QP_ST_UD);
 235         MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
 236         MLX5_SET(qpc, qpc, ulp_stateless_offload_mode,
 237                  MLX5_QP_ENHANCED_ULP_STATELESS_MODE);
 238 
 239         addr_path = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
 240         MLX5_SET(ads, addr_path, vhca_port_num, 1);
 241         MLX5_SET(ads, addr_path, grh, 1);
 242 
 243         ret = mlx5_core_create_qp(mdev, qp, in, inlen);
 244         if (ret) {
 245                 mlx5_core_err(mdev, "Failed creating IPoIB QP err : %d\n", ret);
 246                 goto out;
 247         }
 248 
 249 out:
 250         kvfree(in);
 251         return ret;
 252 }
 253 
 254 void mlx5i_destroy_underlay_qp(struct mlx5_core_dev *mdev, struct mlx5_core_qp *qp)
 255 {
 256         mlx5_core_destroy_qp(mdev, qp);
 257 }
 258 
 259 int mlx5i_create_tis(struct mlx5_core_dev *mdev, u32 underlay_qpn, u32 *tisn)
 260 {
 261         u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
 262         void *tisc;
 263 
 264         tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
 265 
 266         MLX5_SET(tisc, tisc, underlay_qpn, underlay_qpn);
 267 
 268         return mlx5e_create_tis(mdev, in, tisn);
 269 }
 270 
 271 static int mlx5i_init_tx(struct mlx5e_priv *priv)
 272 {
 273         struct mlx5i_priv *ipriv = priv->ppriv;
 274         int err;
 275 
 276         err = mlx5i_create_underlay_qp(priv->mdev, &ipriv->qp);
 277         if (err) {
 278                 mlx5_core_warn(priv->mdev, "create underlay QP failed, %d\n", err);
 279                 return err;
 280         }
 281 
 282         err = mlx5i_create_tis(priv->mdev, ipriv->qp.qpn, &priv->tisn[0][0]);
 283         if (err) {
 284                 mlx5_core_warn(priv->mdev, "create tis failed, %d\n", err);
 285                 goto err_destroy_underlay_qp;
 286         }
 287 
 288         return 0;
 289 
 290 err_destroy_underlay_qp:
 291         mlx5i_destroy_underlay_qp(priv->mdev, &ipriv->qp);
 292         return err;
 293 }
 294 
 295 static void mlx5i_cleanup_tx(struct mlx5e_priv *priv)
 296 {
 297         struct mlx5i_priv *ipriv = priv->ppriv;
 298 
 299         mlx5e_destroy_tis(priv->mdev, priv->tisn[0][0]);
 300         mlx5i_destroy_underlay_qp(priv->mdev, &ipriv->qp);
 301 }
 302 
 303 static int mlx5i_create_flow_steering(struct mlx5e_priv *priv)
 304 {
 305         struct ttc_params ttc_params = {};
 306         int tt, err;
 307 
 308         priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
 309                                                MLX5_FLOW_NAMESPACE_KERNEL);
 310 
 311         if (!priv->fs.ns)
 312                 return -EINVAL;
 313 
 314         err = mlx5e_arfs_create_tables(priv);
 315         if (err) {
 316                 netdev_err(priv->netdev, "Failed to create arfs tables, err=%d\n",
 317                            err);
 318                 priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
 319         }
 320 
 321         mlx5e_set_ttc_basic_params(priv, &ttc_params);
 322         mlx5e_set_inner_ttc_ft_params(&ttc_params);
 323         for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
 324                 ttc_params.indir_tirn[tt] = priv->inner_indir_tir[tt].tirn;
 325 
 326         err = mlx5e_create_inner_ttc_table(priv, &ttc_params, &priv->fs.inner_ttc);
 327         if (err) {
 328                 netdev_err(priv->netdev, "Failed to create inner ttc table, err=%d\n",
 329                            err);
 330                 goto err_destroy_arfs_tables;
 331         }
 332 
 333         mlx5e_set_ttc_ft_params(&ttc_params);
 334         for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
 335                 ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn;
 336 
 337         err = mlx5e_create_ttc_table(priv, &ttc_params, &priv->fs.ttc);
 338         if (err) {
 339                 netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
 340                            err);
 341                 goto err_destroy_inner_ttc_table;
 342         }
 343 
 344         return 0;
 345 
 346 err_destroy_inner_ttc_table:
 347         mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc);
 348 err_destroy_arfs_tables:
 349         mlx5e_arfs_destroy_tables(priv);
 350 
 351         return err;
 352 }
 353 
 354 static void mlx5i_destroy_flow_steering(struct mlx5e_priv *priv)
 355 {
 356         mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
 357         mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc);
 358         mlx5e_arfs_destroy_tables(priv);
 359 }
 360 
 361 static int mlx5i_init_rx(struct mlx5e_priv *priv)
 362 {
 363         struct mlx5_core_dev *mdev = priv->mdev;
 364         int err;
 365 
 366         mlx5e_create_q_counters(priv);
 367 
 368         err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
 369         if (err) {
 370                 mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
 371                 goto err_destroy_q_counters;
 372         }
 373 
 374         err = mlx5e_create_indirect_rqt(priv);
 375         if (err)
 376                 goto err_close_drop_rq;
 377 
 378         err = mlx5e_create_direct_rqts(priv, priv->direct_tir);
 379         if (err)
 380                 goto err_destroy_indirect_rqts;
 381 
 382         err = mlx5e_create_indirect_tirs(priv, true);
 383         if (err)
 384                 goto err_destroy_direct_rqts;
 385 
 386         err = mlx5e_create_direct_tirs(priv, priv->direct_tir);
 387         if (err)
 388                 goto err_destroy_indirect_tirs;
 389 
 390         err = mlx5i_create_flow_steering(priv);
 391         if (err)
 392                 goto err_destroy_direct_tirs;
 393 
 394         return 0;
 395 
 396 err_destroy_direct_tirs:
 397         mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
 398 err_destroy_indirect_tirs:
 399         mlx5e_destroy_indirect_tirs(priv);
 400 err_destroy_direct_rqts:
 401         mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
 402 err_destroy_indirect_rqts:
 403         mlx5e_destroy_rqt(priv, &priv->indir_rqt);
 404 err_close_drop_rq:
 405         mlx5e_close_drop_rq(&priv->drop_rq);
 406 err_destroy_q_counters:
 407         mlx5e_destroy_q_counters(priv);
 408         return err;
 409 }
 410 
 411 static void mlx5i_cleanup_rx(struct mlx5e_priv *priv)
 412 {
 413         mlx5i_destroy_flow_steering(priv);
 414         mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
 415         mlx5e_destroy_indirect_tirs(priv);
 416         mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
 417         mlx5e_destroy_rqt(priv, &priv->indir_rqt);
 418         mlx5e_close_drop_rq(&priv->drop_rq);
 419         mlx5e_destroy_q_counters(priv);
 420 }
 421 
 422 static const struct mlx5e_profile mlx5i_nic_profile = {
 423         .init              = mlx5i_init,
 424         .cleanup           = mlx5i_cleanup,
 425         .init_tx           = mlx5i_init_tx,
 426         .cleanup_tx        = mlx5i_cleanup_tx,
 427         .init_rx           = mlx5i_init_rx,
 428         .cleanup_rx        = mlx5i_cleanup_rx,
 429         .enable            = NULL, /* mlx5i_enable */
 430         .disable           = NULL, /* mlx5i_disable */
 431         .update_rx         = mlx5e_update_nic_rx,
 432         .update_stats      = NULL, /* mlx5i_update_stats */
 433         .update_carrier    = NULL, /* no HW update in IB link */
 434         .rx_handlers.handle_rx_cqe       = mlx5i_handle_rx_cqe,
 435         .rx_handlers.handle_rx_cqe_mpwqe = NULL, /* Not supported */
 436         .max_tc            = MLX5I_MAX_NUM_TC,
 437         .rq_groups         = MLX5E_NUM_RQ_GROUPS(REGULAR),
 438 };
 439 
 440 /* mlx5i netdev NDos */
 441 
 442 static int mlx5i_change_mtu(struct net_device *netdev, int new_mtu)
 443 {
 444         struct mlx5e_priv *priv = mlx5i_epriv(netdev);
 445         struct mlx5e_channels new_channels = {};
 446         struct mlx5e_params *params;
 447         int err = 0;
 448 
 449         mutex_lock(&priv->state_lock);
 450 
 451         params = &priv->channels.params;
 452 
 453         if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
 454                 params->sw_mtu = new_mtu;
 455                 netdev->mtu = params->sw_mtu;
 456                 goto out;
 457         }
 458 
 459         new_channels.params = *params;
 460         new_channels.params.sw_mtu = new_mtu;
 461 
 462         err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
 463         if (err)
 464                 goto out;
 465 
 466         netdev->mtu = new_channels.params.sw_mtu;
 467 
 468 out:
 469         mutex_unlock(&priv->state_lock);
 470         return err;
 471 }
 472 
 473 int mlx5i_dev_init(struct net_device *dev)
 474 {
 475         struct mlx5e_priv    *priv   = mlx5i_epriv(dev);
 476         struct mlx5i_priv    *ipriv  = priv->ppriv;
 477 
 478         /* Set dev address using underlay QP */
 479         dev->dev_addr[1] = (ipriv->qp.qpn >> 16) & 0xff;
 480         dev->dev_addr[2] = (ipriv->qp.qpn >>  8) & 0xff;
 481         dev->dev_addr[3] = (ipriv->qp.qpn) & 0xff;
 482 
 483         /* Add QPN to net-device mapping to HT */
 484         mlx5i_pkey_add_qpn(dev ,ipriv->qp.qpn);
 485 
 486         return 0;
 487 }
 488 
 489 int mlx5i_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 490 {
 491         struct mlx5e_priv *priv = mlx5i_epriv(dev);
 492 
 493         switch (cmd) {
 494         case SIOCSHWTSTAMP:
 495                 return mlx5e_hwstamp_set(priv, ifr);
 496         case SIOCGHWTSTAMP:
 497                 return mlx5e_hwstamp_get(priv, ifr);
 498         default:
 499                 return -EOPNOTSUPP;
 500         }
 501 }
 502 
 503 void mlx5i_dev_cleanup(struct net_device *dev)
 504 {
 505         struct mlx5e_priv    *priv   = mlx5i_epriv(dev);
 506         struct mlx5i_priv    *ipriv = priv->ppriv;
 507 
 508         mlx5i_uninit_underlay_qp(priv);
 509 
 510         /* Delete QPN to net-device mapping from HT */
 511         mlx5i_pkey_del_qpn(dev, ipriv->qp.qpn);
 512 }
 513 
 514 static int mlx5i_open(struct net_device *netdev)
 515 {
 516         struct mlx5e_priv *epriv = mlx5i_epriv(netdev);
 517         struct mlx5i_priv *ipriv = epriv->ppriv;
 518         struct mlx5_core_dev *mdev = epriv->mdev;
 519         int err;
 520 
 521         mutex_lock(&epriv->state_lock);
 522 
 523         set_bit(MLX5E_STATE_OPENED, &epriv->state);
 524 
 525         err = mlx5i_init_underlay_qp(epriv);
 526         if (err) {
 527                 mlx5_core_warn(mdev, "prepare underlay qp state failed, %d\n", err);
 528                 goto err_clear_state_opened_flag;
 529         }
 530 
 531         err = mlx5_fs_add_rx_underlay_qpn(mdev, ipriv->qp.qpn);
 532         if (err) {
 533                 mlx5_core_warn(mdev, "attach underlay qp to ft failed, %d\n", err);
 534                 goto err_reset_qp;
 535         }
 536 
 537         err = mlx5e_open_channels(epriv, &epriv->channels);
 538         if (err)
 539                 goto err_remove_fs_underlay_qp;
 540 
 541         epriv->profile->update_rx(epriv);
 542         mlx5e_activate_priv_channels(epriv);
 543 
 544         mutex_unlock(&epriv->state_lock);
 545         return 0;
 546 
 547 err_remove_fs_underlay_qp:
 548         mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn);
 549 err_reset_qp:
 550         mlx5i_uninit_underlay_qp(epriv);
 551 err_clear_state_opened_flag:
 552         clear_bit(MLX5E_STATE_OPENED, &epriv->state);
 553         mutex_unlock(&epriv->state_lock);
 554         return err;
 555 }
 556 
 557 static int mlx5i_close(struct net_device *netdev)
 558 {
 559         struct mlx5e_priv *epriv = mlx5i_epriv(netdev);
 560         struct mlx5i_priv *ipriv = epriv->ppriv;
 561         struct mlx5_core_dev *mdev = epriv->mdev;
 562 
 563         /* May already be CLOSED in case a previous configuration operation
 564          * (e.g RX/TX queue size change) that involves close&open failed.
 565          */
 566         mutex_lock(&epriv->state_lock);
 567 
 568         if (!test_bit(MLX5E_STATE_OPENED, &epriv->state))
 569                 goto unlock;
 570 
 571         clear_bit(MLX5E_STATE_OPENED, &epriv->state);
 572 
 573         netif_carrier_off(epriv->netdev);
 574         mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn);
 575         mlx5e_deactivate_priv_channels(epriv);
 576         mlx5e_close_channels(&epriv->channels);
 577         mlx5i_uninit_underlay_qp(epriv);
 578 unlock:
 579         mutex_unlock(&epriv->state_lock);
 580         return 0;
 581 }
 582 
 583 /* IPoIB RDMA netdev callbacks */
 584 static int mlx5i_attach_mcast(struct net_device *netdev, struct ib_device *hca,
 585                               union ib_gid *gid, u16 lid, int set_qkey,
 586                               u32 qkey)
 587 {
 588         struct mlx5e_priv    *epriv = mlx5i_epriv(netdev);
 589         struct mlx5_core_dev *mdev  = epriv->mdev;
 590         struct mlx5i_priv    *ipriv = epriv->ppriv;
 591         int err;
 592 
 593         mlx5_core_dbg(mdev, "attaching QPN 0x%x, MGID %pI6\n", ipriv->qp.qpn, gid->raw);
 594         err = mlx5_core_attach_mcg(mdev, gid, ipriv->qp.qpn);
 595         if (err)
 596                 mlx5_core_warn(mdev, "failed attaching QPN 0x%x, MGID %pI6\n",
 597                                ipriv->qp.qpn, gid->raw);
 598 
 599         if (set_qkey) {
 600                 mlx5_core_dbg(mdev, "%s setting qkey 0x%x\n",
 601                               netdev->name, qkey);
 602                 ipriv->qkey = qkey;
 603         }
 604 
 605         return err;
 606 }
 607 
 608 static int mlx5i_detach_mcast(struct net_device *netdev, struct ib_device *hca,
 609                               union ib_gid *gid, u16 lid)
 610 {
 611         struct mlx5e_priv    *epriv = mlx5i_epriv(netdev);
 612         struct mlx5_core_dev *mdev  = epriv->mdev;
 613         struct mlx5i_priv    *ipriv = epriv->ppriv;
 614         int err;
 615 
 616         mlx5_core_dbg(mdev, "detaching QPN 0x%x, MGID %pI6\n", ipriv->qp.qpn, gid->raw);
 617 
 618         err = mlx5_core_detach_mcg(mdev, gid, ipriv->qp.qpn);
 619         if (err)
 620                 mlx5_core_dbg(mdev, "failed detaching QPN 0x%x, MGID %pI6\n",
 621                               ipriv->qp.qpn, gid->raw);
 622 
 623         return err;
 624 }
 625 
 626 static int mlx5i_xmit(struct net_device *dev, struct sk_buff *skb,
 627                       struct ib_ah *address, u32 dqpn)
 628 {
 629         struct mlx5e_priv *epriv = mlx5i_epriv(dev);
 630         struct mlx5e_txqsq *sq   = epriv->txq2sq[skb_get_queue_mapping(skb)];
 631         struct mlx5_ib_ah *mah   = to_mah(address);
 632         struct mlx5i_priv *ipriv = epriv->ppriv;
 633 
 634         return mlx5i_sq_xmit(sq, skb, &mah->av, dqpn, ipriv->qkey, netdev_xmit_more());
 635 }
 636 
 637 static void mlx5i_set_pkey_index(struct net_device *netdev, int id)
 638 {
 639         struct mlx5i_priv *ipriv = netdev_priv(netdev);
 640 
 641         ipriv->pkey_index = (u16)id;
 642 }
 643 
 644 static int mlx5i_check_required_hca_cap(struct mlx5_core_dev *mdev)
 645 {
 646         if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_IB)
 647                 return -EOPNOTSUPP;
 648 
 649         if (!MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads)) {
 650                 mlx5_core_warn(mdev, "IPoIB enhanced offloads are not supported\n");
 651                 return -EOPNOTSUPP;
 652         }
 653 
 654         return 0;
 655 }
 656 
 657 static void mlx5_rdma_netdev_free(struct net_device *netdev)
 658 {
 659         struct mlx5e_priv *priv = mlx5i_epriv(netdev);
 660         struct mlx5i_priv *ipriv = priv->ppriv;
 661         const struct mlx5e_profile *profile = priv->profile;
 662 
 663         mlx5e_detach_netdev(priv);
 664         profile->cleanup(priv);
 665 
 666         if (!ipriv->sub_interface) {
 667                 mlx5i_pkey_qpn_ht_cleanup(netdev);
 668                 mlx5e_destroy_mdev_resources(priv->mdev);
 669         }
 670 }
 671 
 672 static bool mlx5_is_sub_interface(struct mlx5_core_dev *mdev)
 673 {
 674         return mdev->mlx5e_res.pdn != 0;
 675 }
 676 
 677 static const struct mlx5e_profile *mlx5_get_profile(struct mlx5_core_dev *mdev)
 678 {
 679         if (mlx5_is_sub_interface(mdev))
 680                 return mlx5i_pkey_get_profile();
 681         return &mlx5i_nic_profile;
 682 }
 683 
 684 static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num,
 685                               struct net_device *netdev, void *param)
 686 {
 687         struct mlx5_core_dev *mdev = (struct mlx5_core_dev *)param;
 688         const struct mlx5e_profile *prof = mlx5_get_profile(mdev);
 689         struct mlx5i_priv *ipriv;
 690         struct mlx5e_priv *epriv;
 691         struct rdma_netdev *rn;
 692         int err;
 693 
 694         ipriv = netdev_priv(netdev);
 695         epriv = mlx5i_epriv(netdev);
 696 
 697         ipriv->sub_interface = mlx5_is_sub_interface(mdev);
 698         if (!ipriv->sub_interface) {
 699                 err = mlx5i_pkey_qpn_ht_init(netdev);
 700                 if (err) {
 701                         mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n");
 702                         return err;
 703                 }
 704 
 705                 /* This should only be called once per mdev */
 706                 err = mlx5e_create_mdev_resources(mdev);
 707                 if (err)
 708                         goto destroy_ht;
 709         }
 710 
 711         prof->init(mdev, netdev, prof, ipriv);
 712 
 713         err = mlx5e_attach_netdev(epriv);
 714         if (err)
 715                 goto detach;
 716         netif_carrier_off(netdev);
 717 
 718         /* set rdma_netdev func pointers */
 719         rn = &ipriv->rn;
 720         rn->hca  = ibdev;
 721         rn->send = mlx5i_xmit;
 722         rn->attach_mcast = mlx5i_attach_mcast;
 723         rn->detach_mcast = mlx5i_detach_mcast;
 724         rn->set_id = mlx5i_set_pkey_index;
 725 
 726         netdev->priv_destructor = mlx5_rdma_netdev_free;
 727         netdev->needs_free_netdev = 1;
 728 
 729         return 0;
 730 
 731 detach:
 732         prof->cleanup(epriv);
 733         if (ipriv->sub_interface)
 734                 return err;
 735         mlx5e_destroy_mdev_resources(mdev);
 736 destroy_ht:
 737         mlx5i_pkey_qpn_ht_cleanup(netdev);
 738         return err;
 739 }
 740 
 741 int mlx5_rdma_rn_get_params(struct mlx5_core_dev *mdev,
 742                             struct ib_device *device,
 743                             struct rdma_netdev_alloc_params *params)
 744 {
 745         int nch;
 746         int rc;
 747 
 748         rc = mlx5i_check_required_hca_cap(mdev);
 749         if (rc)
 750                 return rc;
 751 
 752         nch = mlx5e_get_max_num_channels(mdev);
 753 
 754         *params = (struct rdma_netdev_alloc_params){
 755                 .sizeof_priv = sizeof(struct mlx5i_priv) +
 756                                sizeof(struct mlx5e_priv),
 757                 .txqs = nch * MLX5E_MAX_NUM_TC,
 758                 .rxqs = nch,
 759                 .param = mdev,
 760                 .initialize_rdma_netdev = mlx5_rdma_setup_rn,
 761         };
 762 
 763         return 0;
 764 }
 765 EXPORT_SYMBOL(mlx5_rdma_rn_get_params);

/* [<][>][^][v][top][bottom][index][help] */