net/mlx5e: Refactor RSS related objects and code
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / ipoib / ipoib.c
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_init                = mlx5i_dev_init,
49         .ndo_uninit              = mlx5i_dev_cleanup,
50         .ndo_change_mtu          = mlx5i_change_mtu,
51         .ndo_do_ioctl            = mlx5i_ioctl,
52 };
53
54 /* IPoIB mlx5 netdev profile */
55 static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
56                                    struct mlx5e_params *params)
57 {
58         /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */
59         mlx5e_init_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST);
60
61         /* RQ size in ipoib by default is 512 */
62         params->log_rq_size = is_kdump_kernel() ?
63                 MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE :
64                 MLX5I_PARAMS_DEFAULT_LOG_RQ_SIZE;
65
66         params->lro_en = false;
67 }
68
69 /* Called directly after IPoIB netdevice was created to initialize SW structs */
70 void mlx5i_init(struct mlx5_core_dev *mdev,
71                 struct net_device *netdev,
72                 const struct mlx5e_profile *profile,
73                 void *ppriv)
74 {
75         struct mlx5e_priv *priv  = mlx5i_epriv(netdev);
76
77         /* priv init */
78         priv->mdev        = mdev;
79         priv->netdev      = netdev;
80         priv->profile     = profile;
81         priv->ppriv       = ppriv;
82         priv->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
83         mutex_init(&priv->state_lock);
84
85         mlx5e_build_nic_params(mdev, &priv->channels.params, profile->max_nch(mdev));
86         mlx5i_build_nic_params(mdev, &priv->channels.params);
87
88         mlx5e_timestamp_init(priv);
89
90         /* netdev init */
91         netdev->hw_features    |= NETIF_F_SG;
92         netdev->hw_features    |= NETIF_F_IP_CSUM;
93         netdev->hw_features    |= NETIF_F_IPV6_CSUM;
94         netdev->hw_features    |= NETIF_F_GRO;
95         netdev->hw_features    |= NETIF_F_TSO;
96         netdev->hw_features    |= NETIF_F_TSO6;
97         netdev->hw_features    |= NETIF_F_RXCSUM;
98         netdev->hw_features    |= NETIF_F_RXHASH;
99
100         netdev->netdev_ops = &mlx5i_netdev_ops;
101         netdev->ethtool_ops = &mlx5i_ethtool_ops;
102 }
103
104 /* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */
105 static void mlx5i_cleanup(struct mlx5e_priv *priv)
106 {
107         /* Do nothing .. */
108 }
109
110 int mlx5i_init_underlay_qp(struct mlx5e_priv *priv)
111 {
112         struct mlx5_core_dev *mdev = priv->mdev;
113         struct mlx5i_priv *ipriv = priv->ppriv;
114         struct mlx5_core_qp *qp = &ipriv->qp;
115         struct mlx5_qp_context *context;
116         int ret;
117
118         /* QP states */
119         context = kzalloc(sizeof(*context), GFP_KERNEL);
120         if (!context)
121                 return -ENOMEM;
122
123         context->flags = cpu_to_be32(MLX5_QP_PM_MIGRATED << 11);
124         context->pri_path.port = 1;
125         context->pri_path.pkey_index = cpu_to_be16(ipriv->pkey_index);
126         context->qkey = cpu_to_be32(IB_DEFAULT_Q_KEY);
127
128         ret = mlx5_core_qp_modify(mdev, MLX5_CMD_OP_RST2INIT_QP, 0, context, qp);
129         if (ret) {
130                 mlx5_core_err(mdev, "Failed to modify qp RST2INIT, err: %d\n", ret);
131                 goto err_qp_modify_to_err;
132         }
133         memset(context, 0, sizeof(*context));
134
135         ret = mlx5_core_qp_modify(mdev, MLX5_CMD_OP_INIT2RTR_QP, 0, context, qp);
136         if (ret) {
137                 mlx5_core_err(mdev, "Failed to modify qp INIT2RTR, err: %d\n", ret);
138                 goto err_qp_modify_to_err;
139         }
140
141         ret = mlx5_core_qp_modify(mdev, MLX5_CMD_OP_RTR2RTS_QP, 0, context, qp);
142         if (ret) {
143                 mlx5_core_err(mdev, "Failed to modify qp RTR2RTS, err: %d\n", ret);
144                 goto err_qp_modify_to_err;
145         }
146
147         kfree(context);
148         return 0;
149
150 err_qp_modify_to_err:
151         mlx5_core_qp_modify(mdev, MLX5_CMD_OP_2ERR_QP, 0, &context, qp);
152         kfree(context);
153         return ret;
154 }
155
156 void mlx5i_uninit_underlay_qp(struct mlx5e_priv *priv)
157 {
158         struct mlx5i_priv *ipriv = priv->ppriv;
159         struct mlx5_core_dev *mdev = priv->mdev;
160         struct mlx5_qp_context context;
161         int err;
162
163         err = mlx5_core_qp_modify(mdev, MLX5_CMD_OP_2RST_QP, 0, &context,
164                                   &ipriv->qp);
165         if (err)
166                 mlx5_core_err(mdev, "Failed to modify qp 2RST, err: %d\n", err);
167 }
168
169 #define MLX5_QP_ENHANCED_ULP_STATELESS_MODE 2
170
171 int mlx5i_create_underlay_qp(struct mlx5_core_dev *mdev, struct mlx5_core_qp *qp)
172 {
173         u32 *in = NULL;
174         void *addr_path;
175         int ret = 0;
176         int inlen;
177         void *qpc;
178
179         inlen = MLX5_ST_SZ_BYTES(create_qp_in);
180         in = kvzalloc(inlen, GFP_KERNEL);
181         if (!in)
182                 return -ENOMEM;
183
184         qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
185         MLX5_SET(qpc, qpc, st, MLX5_QP_ST_UD);
186         MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
187         MLX5_SET(qpc, qpc, ulp_stateless_offload_mode,
188                  MLX5_QP_ENHANCED_ULP_STATELESS_MODE);
189
190         addr_path = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
191         MLX5_SET(ads, addr_path, port, 1);
192         MLX5_SET(ads, addr_path, grh, 1);
193
194         ret = mlx5_core_create_qp(mdev, qp, in, inlen);
195         if (ret) {
196                 mlx5_core_err(mdev, "Failed creating IPoIB QP err : %d\n", ret);
197                 goto out;
198         }
199
200 out:
201         kvfree(in);
202         return ret;
203 }
204
205 void mlx5i_destroy_underlay_qp(struct mlx5_core_dev *mdev, struct mlx5_core_qp *qp)
206 {
207         mlx5_core_destroy_qp(mdev, qp);
208 }
209
210 static int mlx5i_init_tx(struct mlx5e_priv *priv)
211 {
212         struct mlx5i_priv *ipriv = priv->ppriv;
213         int err;
214
215         err = mlx5i_create_underlay_qp(priv->mdev, &ipriv->qp);
216         if (err) {
217                 mlx5_core_warn(priv->mdev, "create underlay QP failed, %d\n", err);
218                 return err;
219         }
220
221         err = mlx5e_create_tis(priv->mdev, 0 /* tc */, ipriv->qp.qpn, &priv->tisn[0]);
222         if (err) {
223                 mlx5_core_warn(priv->mdev, "create tis failed, %d\n", err);
224                 goto err_destroy_underlay_qp;
225         }
226
227         return 0;
228
229 err_destroy_underlay_qp:
230         mlx5i_destroy_underlay_qp(priv->mdev, &ipriv->qp);
231         return err;
232 }
233
234 static void mlx5i_cleanup_tx(struct mlx5e_priv *priv)
235 {
236         struct mlx5i_priv *ipriv = priv->ppriv;
237
238         mlx5e_destroy_tis(priv->mdev, priv->tisn[0]);
239         mlx5i_destroy_underlay_qp(priv->mdev, &ipriv->qp);
240 }
241
242 static int mlx5i_create_flow_steering(struct mlx5e_priv *priv)
243 {
244         struct ttc_params ttc_params = {};
245         int tt, err;
246
247         priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
248                                                MLX5_FLOW_NAMESPACE_KERNEL);
249
250         if (!priv->fs.ns)
251                 return -EINVAL;
252
253         err = mlx5e_arfs_create_tables(priv);
254         if (err) {
255                 netdev_err(priv->netdev, "Failed to create arfs tables, err=%d\n",
256                            err);
257                 priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
258         }
259
260         mlx5e_set_ttc_basic_params(priv, &ttc_params);
261         mlx5e_set_inner_ttc_ft_params(&ttc_params);
262         for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
263                 ttc_params.indir_tirn[tt] = priv->inner_indir_tir[tt].tirn;
264
265         err = mlx5e_create_inner_ttc_table(priv, &ttc_params, &priv->fs.inner_ttc);
266         if (err) {
267                 netdev_err(priv->netdev, "Failed to create inner ttc table, err=%d\n",
268                            err);
269                 goto err_destroy_arfs_tables;
270         }
271
272         mlx5e_set_ttc_ft_params(&ttc_params);
273         for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
274                 ttc_params.indir_tirn[tt] = priv->inner_indir_tir[tt].tirn;
275
276         err = mlx5e_create_ttc_table(priv, &ttc_params, &priv->fs.ttc);
277         if (err) {
278                 netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
279                            err);
280                 goto err_destroy_inner_ttc_table;
281         }
282
283         return 0;
284
285 err_destroy_inner_ttc_table:
286         mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc);
287 err_destroy_arfs_tables:
288         mlx5e_arfs_destroy_tables(priv);
289
290         return err;
291 }
292
293 static void mlx5i_destroy_flow_steering(struct mlx5e_priv *priv)
294 {
295         mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
296         mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc);
297         mlx5e_arfs_destroy_tables(priv);
298 }
299
300 static int mlx5i_init_rx(struct mlx5e_priv *priv)
301 {
302         int err;
303
304         err = mlx5e_create_indirect_rqt(priv);
305         if (err)
306                 return err;
307
308         err = mlx5e_create_direct_rqts(priv);
309         if (err)
310                 goto err_destroy_indirect_rqts;
311
312         err = mlx5e_create_indirect_tirs(priv);
313         if (err)
314                 goto err_destroy_direct_rqts;
315
316         err = mlx5e_create_direct_tirs(priv);
317         if (err)
318                 goto err_destroy_indirect_tirs;
319
320         err = mlx5i_create_flow_steering(priv);
321         if (err)
322                 goto err_destroy_direct_tirs;
323
324         return 0;
325
326 err_destroy_direct_tirs:
327         mlx5e_destroy_direct_tirs(priv);
328 err_destroy_indirect_tirs:
329         mlx5e_destroy_indirect_tirs(priv);
330 err_destroy_direct_rqts:
331         mlx5e_destroy_direct_rqts(priv);
332 err_destroy_indirect_rqts:
333         mlx5e_destroy_rqt(priv, &priv->indir_rqt);
334         return err;
335 }
336
337 static void mlx5i_cleanup_rx(struct mlx5e_priv *priv)
338 {
339         mlx5i_destroy_flow_steering(priv);
340         mlx5e_destroy_direct_tirs(priv);
341         mlx5e_destroy_indirect_tirs(priv);
342         mlx5e_destroy_direct_rqts(priv);
343         mlx5e_destroy_rqt(priv, &priv->indir_rqt);
344 }
345
346 static const struct mlx5e_profile mlx5i_nic_profile = {
347         .init              = mlx5i_init,
348         .cleanup           = mlx5i_cleanup,
349         .init_tx           = mlx5i_init_tx,
350         .cleanup_tx        = mlx5i_cleanup_tx,
351         .init_rx           = mlx5i_init_rx,
352         .cleanup_rx        = mlx5i_cleanup_rx,
353         .enable            = NULL, /* mlx5i_enable */
354         .disable           = NULL, /* mlx5i_disable */
355         .update_stats      = NULL, /* mlx5i_update_stats */
356         .max_nch           = mlx5e_get_max_num_channels,
357         .update_carrier    = NULL, /* no HW update in IB link */
358         .rx_handlers.handle_rx_cqe       = mlx5i_handle_rx_cqe,
359         .rx_handlers.handle_rx_cqe_mpwqe = NULL, /* Not supported */
360         .max_tc            = MLX5I_MAX_NUM_TC,
361 };
362
363 /* mlx5i netdev NDos */
364
365 static int mlx5i_change_mtu(struct net_device *netdev, int new_mtu)
366 {
367         struct mlx5e_priv *priv = mlx5i_epriv(netdev);
368         struct mlx5e_channels new_channels = {};
369         int curr_mtu;
370         int err = 0;
371
372         mutex_lock(&priv->state_lock);
373
374         curr_mtu    = netdev->mtu;
375         netdev->mtu = new_mtu;
376
377         if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
378                 goto out;
379
380         new_channels.params = priv->channels.params;
381         err = mlx5e_open_channels(priv, &new_channels);
382         if (err) {
383                 netdev->mtu = curr_mtu;
384                 goto out;
385         }
386
387         mlx5e_switch_priv_channels(priv, &new_channels, NULL);
388
389 out:
390         mutex_unlock(&priv->state_lock);
391         return err;
392 }
393
394 int mlx5i_dev_init(struct net_device *dev)
395 {
396         struct mlx5e_priv    *priv   = mlx5i_epriv(dev);
397         struct mlx5i_priv    *ipriv  = priv->ppriv;
398
399         /* Set dev address using underlay QP */
400         dev->dev_addr[1] = (ipriv->qp.qpn >> 16) & 0xff;
401         dev->dev_addr[2] = (ipriv->qp.qpn >>  8) & 0xff;
402         dev->dev_addr[3] = (ipriv->qp.qpn) & 0xff;
403
404         /* Add QPN to net-device mapping to HT */
405         mlx5i_pkey_add_qpn(dev ,ipriv->qp.qpn);
406
407         return 0;
408 }
409
410 int mlx5i_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
411 {
412         struct mlx5e_priv *priv = mlx5i_epriv(dev);
413
414         switch (cmd) {
415         case SIOCSHWTSTAMP:
416                 return mlx5e_hwstamp_set(priv, ifr);
417         case SIOCGHWTSTAMP:
418                 return mlx5e_hwstamp_get(priv, ifr);
419         default:
420                 return -EOPNOTSUPP;
421         }
422 }
423
424 void mlx5i_dev_cleanup(struct net_device *dev)
425 {
426         struct mlx5e_priv    *priv   = mlx5i_epriv(dev);
427         struct mlx5i_priv    *ipriv = priv->ppriv;
428
429         mlx5i_uninit_underlay_qp(priv);
430
431         /* Delete QPN to net-device mapping from HT */
432         mlx5i_pkey_del_qpn(dev, ipriv->qp.qpn);
433 }
434
435 static int mlx5i_open(struct net_device *netdev)
436 {
437         struct mlx5e_priv *epriv = mlx5i_epriv(netdev);
438         struct mlx5i_priv *ipriv = epriv->ppriv;
439         struct mlx5_core_dev *mdev = epriv->mdev;
440         int err;
441
442         mutex_lock(&epriv->state_lock);
443
444         set_bit(MLX5E_STATE_OPENED, &epriv->state);
445
446         err = mlx5i_init_underlay_qp(epriv);
447         if (err) {
448                 mlx5_core_warn(mdev, "prepare underlay qp state failed, %d\n", err);
449                 goto err_clear_state_opened_flag;
450         }
451
452         err = mlx5_fs_add_rx_underlay_qpn(mdev, ipriv->qp.qpn);
453         if (err) {
454                 mlx5_core_warn(mdev, "attach underlay qp to ft failed, %d\n", err);
455                 goto err_reset_qp;
456         }
457
458         err = mlx5e_open_channels(epriv, &epriv->channels);
459         if (err)
460                 goto err_remove_fs_underlay_qp;
461
462         mlx5e_refresh_tirs(epriv, false);
463         mlx5e_activate_priv_channels(epriv);
464
465         mutex_unlock(&epriv->state_lock);
466         return 0;
467
468 err_remove_fs_underlay_qp:
469         mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn);
470 err_reset_qp:
471         mlx5i_uninit_underlay_qp(epriv);
472 err_clear_state_opened_flag:
473         clear_bit(MLX5E_STATE_OPENED, &epriv->state);
474         mutex_unlock(&epriv->state_lock);
475         return err;
476 }
477
478 static int mlx5i_close(struct net_device *netdev)
479 {
480         struct mlx5e_priv *epriv = mlx5i_epriv(netdev);
481         struct mlx5i_priv *ipriv = epriv->ppriv;
482         struct mlx5_core_dev *mdev = epriv->mdev;
483
484         /* May already be CLOSED in case a previous configuration operation
485          * (e.g RX/TX queue size change) that involves close&open failed.
486          */
487         mutex_lock(&epriv->state_lock);
488
489         if (!test_bit(MLX5E_STATE_OPENED, &epriv->state))
490                 goto unlock;
491
492         clear_bit(MLX5E_STATE_OPENED, &epriv->state);
493
494         netif_carrier_off(epriv->netdev);
495         mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn);
496         mlx5i_uninit_underlay_qp(epriv);
497         mlx5e_deactivate_priv_channels(epriv);
498         mlx5e_close_channels(&epriv->channels);
499 unlock:
500         mutex_unlock(&epriv->state_lock);
501         return 0;
502 }
503
504 /* IPoIB RDMA netdev callbacks */
505 static int mlx5i_attach_mcast(struct net_device *netdev, struct ib_device *hca,
506                               union ib_gid *gid, u16 lid, int set_qkey,
507                               u32 qkey)
508 {
509         struct mlx5e_priv    *epriv = mlx5i_epriv(netdev);
510         struct mlx5_core_dev *mdev  = epriv->mdev;
511         struct mlx5i_priv    *ipriv = epriv->ppriv;
512         int err;
513
514         mlx5_core_dbg(mdev, "attaching QPN 0x%x, MGID %pI6\n", ipriv->qp.qpn, gid->raw);
515         err = mlx5_core_attach_mcg(mdev, gid, ipriv->qp.qpn);
516         if (err)
517                 mlx5_core_warn(mdev, "failed attaching QPN 0x%x, MGID %pI6\n",
518                                ipriv->qp.qpn, gid->raw);
519
520         if (set_qkey) {
521                 mlx5_core_dbg(mdev, "%s setting qkey 0x%x\n",
522                               netdev->name, qkey);
523                 ipriv->qkey = qkey;
524         }
525
526         return err;
527 }
528
529 static int mlx5i_detach_mcast(struct net_device *netdev, struct ib_device *hca,
530                               union ib_gid *gid, u16 lid)
531 {
532         struct mlx5e_priv    *epriv = mlx5i_epriv(netdev);
533         struct mlx5_core_dev *mdev  = epriv->mdev;
534         struct mlx5i_priv    *ipriv = epriv->ppriv;
535         int err;
536
537         mlx5_core_dbg(mdev, "detaching QPN 0x%x, MGID %pI6\n", ipriv->qp.qpn, gid->raw);
538
539         err = mlx5_core_detach_mcg(mdev, gid, ipriv->qp.qpn);
540         if (err)
541                 mlx5_core_dbg(mdev, "failed dettaching QPN 0x%x, MGID %pI6\n",
542                               ipriv->qp.qpn, gid->raw);
543
544         return err;
545 }
546
547 static int mlx5i_xmit(struct net_device *dev, struct sk_buff *skb,
548                       struct ib_ah *address, u32 dqpn)
549 {
550         struct mlx5e_priv *epriv = mlx5i_epriv(dev);
551         struct mlx5e_txqsq *sq   = epriv->txq2sq[skb_get_queue_mapping(skb)];
552         struct mlx5_ib_ah *mah   = to_mah(address);
553         struct mlx5i_priv *ipriv = epriv->ppriv;
554
555         return mlx5i_sq_xmit(sq, skb, &mah->av, dqpn, ipriv->qkey);
556 }
557
558 static void mlx5i_set_pkey_index(struct net_device *netdev, int id)
559 {
560         struct mlx5i_priv *ipriv = netdev_priv(netdev);
561
562         ipriv->pkey_index = (u16)id;
563 }
564
565 static int mlx5i_check_required_hca_cap(struct mlx5_core_dev *mdev)
566 {
567         if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_IB)
568                 return -EOPNOTSUPP;
569
570         if (!MLX5_CAP_GEN(mdev, ipoib_enhanced_offloads)) {
571                 mlx5_core_warn(mdev, "IPoIB enhanced offloads are not supported\n");
572                 return -EOPNOTSUPP;
573         }
574
575         return 0;
576 }
577
578 struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
579                                           struct ib_device *ibdev,
580                                           const char *name,
581                                           void (*setup)(struct net_device *))
582 {
583         const struct mlx5e_profile *profile;
584         struct net_device *netdev;
585         struct mlx5i_priv *ipriv;
586         struct mlx5e_priv *epriv;
587         struct rdma_netdev *rn;
588         bool sub_interface;
589         int nch;
590         int err;
591
592         if (mlx5i_check_required_hca_cap(mdev)) {
593                 mlx5_core_warn(mdev, "Accelerated mode is not supported\n");
594                 return ERR_PTR(-EOPNOTSUPP);
595         }
596
597         /* TODO: Need to find a better way to check if child device*/
598         sub_interface = (mdev->mlx5e_res.pdn != 0);
599
600         if (sub_interface)
601                 profile = mlx5i_pkey_get_profile();
602         else
603                 profile = &mlx5i_nic_profile;
604
605         nch = profile->max_nch(mdev);
606
607         netdev = alloc_netdev_mqs(sizeof(struct mlx5i_priv) + sizeof(struct mlx5e_priv),
608                                   name, NET_NAME_UNKNOWN,
609                                   setup,
610                                   nch * MLX5E_MAX_NUM_TC,
611                                   nch);
612         if (!netdev) {
613                 mlx5_core_warn(mdev, "alloc_netdev_mqs failed\n");
614                 return NULL;
615         }
616
617         ipriv = netdev_priv(netdev);
618         epriv = mlx5i_epriv(netdev);
619
620         epriv->wq = create_singlethread_workqueue("mlx5i");
621         if (!epriv->wq)
622                 goto err_free_netdev;
623
624         ipriv->sub_interface = sub_interface;
625         if (!ipriv->sub_interface) {
626                 err = mlx5i_pkey_qpn_ht_init(netdev);
627                 if (err) {
628                         mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n");
629                         goto destroy_wq;
630                 }
631
632                 /* This should only be called once per mdev */
633                 err = mlx5e_create_mdev_resources(mdev);
634                 if (err)
635                         goto destroy_ht;
636         }
637
638         profile->init(mdev, netdev, profile, ipriv);
639
640         mlx5e_attach_netdev(epriv);
641         netif_carrier_off(netdev);
642
643         /* set rdma_netdev func pointers */
644         rn = &ipriv->rn;
645         rn->hca  = ibdev;
646         rn->send = mlx5i_xmit;
647         rn->attach_mcast = mlx5i_attach_mcast;
648         rn->detach_mcast = mlx5i_detach_mcast;
649         rn->set_id = mlx5i_set_pkey_index;
650
651         return netdev;
652
653 destroy_ht:
654         mlx5i_pkey_qpn_ht_cleanup(netdev);
655 destroy_wq:
656         destroy_workqueue(epriv->wq);
657 err_free_netdev:
658         free_netdev(netdev);
659
660         return NULL;
661 }
662 EXPORT_SYMBOL(mlx5_rdma_netdev_alloc);
663
664 void mlx5_rdma_netdev_free(struct net_device *netdev)
665 {
666         struct mlx5e_priv *priv = mlx5i_epriv(netdev);
667         struct mlx5i_priv *ipriv = priv->ppriv;
668         const struct mlx5e_profile *profile = priv->profile;
669
670         mlx5e_detach_netdev(priv);
671         profile->cleanup(priv);
672         destroy_workqueue(priv->wq);
673
674         if (!ipriv->sub_interface) {
675                 mlx5i_pkey_qpn_ht_cleanup(netdev);
676                 mlx5e_destroy_mdev_resources(priv->mdev);
677         }
678         free_netdev(netdev);
679 }
680 EXPORT_SYMBOL(mlx5_rdma_netdev_free);