Skip to content

Commit 22c4640

Browse files
armratnerSaeed Mahameed
authored andcommitted
net/mlx5: Implement management PF Ethernet profile
Add management PF modules, which introduce support for the structures needed to create the resources for the MGMT PF to work. Also, add the necessary calls and functions to establish this functionality. Signed-off-by: Armen Ratner <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]> Reviewed-by: Daniel Jurgens <[email protected]>
1 parent c88c49a commit 22c4640

File tree

9 files changed

+323
-8
lines changed

9 files changed

+323
-8
lines changed

drivers/net/ethernet/mellanox/mlx5/core/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN) += en/rqt.o en/tir.o en/rss.o en/rx_res.o \
2929
en/reporter_tx.o en/reporter_rx.o en/params.o en/xsk/pool.o \
3030
en/xsk/setup.o en/xsk/rx.o en/xsk/tx.o en/devlink.o en/ptp.o \
3131
en/qos.o en/htb.o en/trap.o en/fs_tt_redirect.o en/selq.o \
32-
lib/crypto.o lib/sd.o
32+
en/mgmt_pf.o lib/crypto.o lib/sd.o
3333

3434
#
3535
# Netdev extra

drivers/net/ethernet/mellanox/mlx5/core/dev.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ bool mlx5_rdma_supported(struct mlx5_core_dev *dev)
190190
if (is_mp_supported(dev))
191191
return false;
192192

193+
if (mlx5_core_is_mgmt_pf(dev))
194+
return false;
195+
193196
return true;
194197
}
195198

drivers/net/ethernet/mellanox/mlx5/core/ecpf.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ int mlx5_ec_init(struct mlx5_core_dev *dev)
7575
if (!mlx5_core_is_ecpf(dev))
7676
return 0;
7777

78+
if (mlx5_core_is_mgmt_pf(dev))
79+
return 0;
80+
7881
return mlx5_host_pf_init(dev);
7982
}
8083

@@ -85,6 +88,9 @@ void mlx5_ec_cleanup(struct mlx5_core_dev *dev)
8588
if (!mlx5_core_is_ecpf(dev))
8689
return;
8790

91+
if (mlx5_core_is_mgmt_pf(dev))
92+
return;
93+
8894
mlx5_host_pf_cleanup(dev);
8995

9096
err = mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_HOST_PF]);

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include "lib/sd.h"
6464

6565
extern const struct net_device_ops mlx5e_netdev_ops;
66+
extern const struct net_device_ops mlx5e_mgmt_netdev_ops;
6667
struct page_pool;
6768

6869
#define MLX5E_METADATA_ETHER_TYPE (0x8CE4)
@@ -1125,6 +1126,7 @@ static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev)
11251126
}
11261127

11271128
extern const struct ethtool_ops mlx5e_ethtool_ops;
1129+
extern const struct mlx5e_profile mlx5e_mgmt_pf_nic_profile;
11281130

11291131
int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, u32 *mkey);
11301132
int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises);
@@ -1230,6 +1232,8 @@ netdev_features_t mlx5e_features_check(struct sk_buff *skb,
12301232
struct net_device *netdev,
12311233
netdev_features_t features);
12321234
int mlx5e_set_features(struct net_device *netdev, netdev_features_t features);
1235+
void mlx5e_nic_set_rx_mode(struct mlx5e_priv *priv);
1236+
12331237
#ifdef CONFIG_MLX5_ESWITCH
12341238
int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac);
12351239
int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, int max_tx_rate);
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2+
// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
4+
#include <linux/kernel.h>
5+
#include "en/params.h"
6+
#include "en/health.h"
7+
#include "lib/eq.h"
8+
#include "en/dcbnl.h"
9+
#include "en_accel/ipsec.h"
10+
#include "en_accel/en_accel.h"
11+
#include "en/trap.h"
12+
#include "en/monitor_stats.h"
13+
#include "en/hv_vhca_stats.h"
14+
#include "en_rep.h"
15+
#include "en.h"
16+
17+
static int mgmt_pf_async_event(struct notifier_block *nb, unsigned long event, void *data)
18+
{
19+
struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
20+
struct mlx5_eqe *eqe = data;
21+
22+
if (event != MLX5_EVENT_TYPE_PORT_CHANGE)
23+
return NOTIFY_DONE;
24+
25+
switch (eqe->sub_type) {
26+
case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
27+
case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
28+
queue_work(priv->wq, &priv->update_carrier_work);
29+
break;
30+
default:
31+
return NOTIFY_DONE;
32+
}
33+
34+
return NOTIFY_OK;
35+
}
36+
37+
static void mlx5e_mgmt_pf_enable_async_events(struct mlx5e_priv *priv)
38+
{
39+
priv->events_nb.notifier_call = mgmt_pf_async_event;
40+
mlx5_notifier_register(priv->mdev, &priv->events_nb);
41+
}
42+
43+
static void mlx5e_disable_mgmt_pf_async_events(struct mlx5e_priv *priv)
44+
{
45+
mlx5_notifier_unregister(priv->mdev, &priv->events_nb);
46+
}
47+
48+
static void mlx5e_modify_mgmt_pf_admin_state(struct mlx5_core_dev *mdev,
49+
enum mlx5_port_status state)
50+
{
51+
struct mlx5_eswitch *esw = mdev->priv.eswitch;
52+
int vport_admin_state;
53+
54+
mlx5_set_port_admin_status(mdev, state);
55+
56+
if (state == MLX5_PORT_UP)
57+
vport_admin_state = MLX5_VPORT_ADMIN_STATE_AUTO;
58+
else
59+
vport_admin_state = MLX5_VPORT_ADMIN_STATE_DOWN;
60+
61+
mlx5_eswitch_set_vport_state(esw, MLX5_VPORT_UPLINK, vport_admin_state);
62+
}
63+
64+
static void mlx5e_build_mgmt_pf_nic_params(struct mlx5e_priv *priv, u16 mtu)
65+
{
66+
struct mlx5e_params *params = &priv->channels.params;
67+
struct mlx5_core_dev *mdev = priv->mdev;
68+
u8 rx_cq_period_mode;
69+
70+
params->sw_mtu = mtu;
71+
params->hard_mtu = MLX5E_ETH_HARD_MTU;
72+
params->num_channels = 1;
73+
74+
/* SQ */
75+
params->log_sq_size = is_kdump_kernel() ?
76+
MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE :
77+
MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
78+
MLX5E_SET_PFLAG(params, MLX5E_PFLAG_SKB_TX_MPWQE, mlx5e_tx_mpwqe_supported(mdev));
79+
80+
MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE, false);
81+
82+
/* RQ */
83+
mlx5e_build_rq_params(mdev, params);
84+
85+
/* CQ moderation params */
86+
rx_cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
87+
MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
88+
MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
89+
params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
90+
params->tx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
91+
mlx5e_set_rx_cq_mode_params(params, rx_cq_period_mode);
92+
mlx5e_set_tx_cq_mode_params(params, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
93+
94+
/* TX inline */
95+
mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
96+
}
97+
98+
static int mlx5e_mgmt_pf_init(struct mlx5_core_dev *mdev,
99+
struct net_device *netdev)
100+
{
101+
struct mlx5e_priv *priv = netdev_priv(netdev);
102+
struct mlx5e_flow_steering *fs;
103+
int err;
104+
105+
mlx5e_build_mgmt_pf_nic_params(priv, netdev->mtu);
106+
107+
mlx5e_timestamp_init(priv);
108+
109+
fs = mlx5e_fs_init(priv->profile, mdev,
110+
!test_bit(MLX5E_STATE_DESTROYING, &priv->state),
111+
priv->dfs_root);
112+
if (!fs) {
113+
err = -ENOMEM;
114+
mlx5_core_err(mdev, "FS initialization failed, %d\n", err);
115+
return err;
116+
}
117+
priv->fs = fs;
118+
119+
mlx5e_health_create_reporters(priv);
120+
121+
return 0;
122+
}
123+
124+
static void mlx5e_mgmt_pf_cleanup(struct mlx5e_priv *priv)
125+
{
126+
mlx5e_health_destroy_reporters(priv);
127+
mlx5e_fs_cleanup(priv->fs);
128+
priv->fs = NULL;
129+
}
130+
131+
static int mlx5e_mgmt_pf_init_rx(struct mlx5e_priv *priv)
132+
{
133+
struct mlx5_core_dev *mdev = priv->mdev;
134+
int err;
135+
136+
priv->rx_res = mlx5e_rx_res_create(mdev, 0, priv->max_nch, priv->drop_rq.rqn,
137+
&priv->channels.params.packet_merge,
138+
priv->channels.params.num_channels);
139+
if (!priv->rx_res)
140+
return -ENOMEM;
141+
142+
mlx5e_create_q_counters(priv);
143+
144+
err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
145+
if (err) {
146+
mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
147+
goto err_destroy_q_counters;
148+
}
149+
150+
err = mlx5e_create_flow_steering(priv->fs, priv->rx_res, priv->profile,
151+
priv->netdev);
152+
if (err) {
153+
mlx5_core_warn(mdev, "create flow steering failed, %d\n", err);
154+
goto err_destroy_rx_res;
155+
}
156+
157+
return 0;
158+
159+
err_destroy_rx_res:
160+
mlx5e_rx_res_destroy(priv->rx_res);
161+
priv->rx_res = NULL;
162+
mlx5e_close_drop_rq(&priv->drop_rq);
163+
err_destroy_q_counters:
164+
mlx5e_destroy_q_counters(priv);
165+
return err;
166+
}
167+
168+
static void mlx5e_mgmt_pf_cleanup_rx(struct mlx5e_priv *priv)
169+
{
170+
mlx5e_destroy_flow_steering(priv->fs, !!(priv->netdev->hw_features & NETIF_F_NTUPLE),
171+
priv->profile);
172+
mlx5e_rx_res_destroy(priv->rx_res);
173+
priv->rx_res = NULL;
174+
mlx5e_close_drop_rq(&priv->drop_rq);
175+
mlx5e_destroy_q_counters(priv);
176+
}
177+
178+
static int mlx5e_mgmt_pf_init_tx(struct mlx5e_priv *priv)
179+
{
180+
return 0;
181+
}
182+
183+
static void mlx5e_mgmt_pf_cleanup_tx(struct mlx5e_priv *priv)
184+
{
185+
}
186+
187+
static void mlx5e_mgmt_pf_enable(struct mlx5e_priv *priv)
188+
{
189+
struct net_device *netdev = priv->netdev;
190+
struct mlx5_core_dev *mdev = priv->mdev;
191+
192+
mlx5e_fs_init_l2_addr(priv->fs, netdev);
193+
194+
/* Marking the link as currently not needed by the Driver */
195+
if (!netif_running(netdev))
196+
mlx5e_modify_mgmt_pf_admin_state(mdev, MLX5_PORT_DOWN);
197+
198+
mlx5e_set_netdev_mtu_boundaries(priv);
199+
mlx5e_set_dev_port_mtu(priv);
200+
201+
mlx5e_mgmt_pf_enable_async_events(priv);
202+
if (mlx5e_monitor_counter_supported(priv))
203+
mlx5e_monitor_counter_init(priv);
204+
205+
mlx5e_hv_vhca_stats_create(priv);
206+
if (netdev->reg_state != NETREG_REGISTERED)
207+
return;
208+
mlx5e_dcbnl_init_app(priv);
209+
210+
mlx5e_nic_set_rx_mode(priv);
211+
212+
rtnl_lock();
213+
if (netif_running(netdev))
214+
mlx5e_open(netdev);
215+
udp_tunnel_nic_reset_ntf(priv->netdev);
216+
netif_device_attach(netdev);
217+
rtnl_unlock();
218+
}
219+
220+
static void mlx5e_mgmt_pf_disable(struct mlx5e_priv *priv)
221+
{
222+
if (priv->netdev->reg_state == NETREG_REGISTERED)
223+
mlx5e_dcbnl_delete_app(priv);
224+
225+
rtnl_lock();
226+
if (netif_running(priv->netdev))
227+
mlx5e_close(priv->netdev);
228+
netif_device_detach(priv->netdev);
229+
rtnl_unlock();
230+
231+
mlx5e_nic_set_rx_mode(priv);
232+
233+
mlx5e_hv_vhca_stats_destroy(priv);
234+
if (mlx5e_monitor_counter_supported(priv))
235+
mlx5e_monitor_counter_cleanup(priv);
236+
237+
mlx5e_disable_mgmt_pf_async_events(priv);
238+
mlx5e_ipsec_cleanup(priv);
239+
}
240+
241+
static int mlx5e_mgmt_pf_update_rx(struct mlx5e_priv *priv)
242+
{
243+
return mlx5e_refresh_tirs(priv, false, false);
244+
}
245+
246+
static int mlx5e_mgmt_pf_max_nch_limit(struct mlx5_core_dev *mdev)
247+
{
248+
return 1;
249+
}
250+
251+
const struct mlx5e_profile mlx5e_mgmt_pf_nic_profile = {
252+
.init = mlx5e_mgmt_pf_init,
253+
.cleanup = mlx5e_mgmt_pf_cleanup,
254+
.init_rx = mlx5e_mgmt_pf_init_rx,
255+
.cleanup_rx = mlx5e_mgmt_pf_cleanup_rx,
256+
.init_tx = mlx5e_mgmt_pf_init_tx,
257+
.cleanup_tx = mlx5e_mgmt_pf_cleanup_tx,
258+
.enable = mlx5e_mgmt_pf_enable,
259+
.disable = mlx5e_mgmt_pf_disable,
260+
.update_rx = mlx5e_mgmt_pf_update_rx,
261+
.update_stats = mlx5e_stats_update_ndo_stats,
262+
.update_carrier = mlx5e_update_carrier,
263+
.rx_handlers = &mlx5e_rx_handlers_nic,
264+
.max_tc = 1,
265+
.max_nch_limit = mlx5e_mgmt_pf_max_nch_limit,
266+
.stats_grps = mlx5e_nic_stats_grps,
267+
.stats_grps_num = mlx5e_nic_stats_grps_num
268+
};

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3799,7 +3799,7 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
37993799
stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors;
38003800
}
38013801

3802-
static void mlx5e_nic_set_rx_mode(struct mlx5e_priv *priv)
3802+
void mlx5e_nic_set_rx_mode(struct mlx5e_priv *priv)
38033803
{
38043804
if (mlx5e_is_uplink_rep(priv))
38053805
return; /* no rx mode for uplink rep */
@@ -5004,6 +5004,15 @@ const struct net_device_ops mlx5e_netdev_ops = {
50045004
#endif
50055005
};
50065006

5007+
const struct net_device_ops mlx5e_mgmt_netdev_ops = {
5008+
.ndo_open = mlx5e_open,
5009+
.ndo_stop = mlx5e_close,
5010+
.ndo_start_xmit = mlx5e_xmit,
5011+
.ndo_get_stats64 = mlx5e_get_stats,
5012+
.ndo_change_mtu = mlx5e_change_nic_mtu,
5013+
.ndo_set_rx_mode = mlx5e_set_rx_mode,
5014+
};
5015+
50075016
static u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout)
50085017
{
50095018
int i;
@@ -5143,7 +5152,11 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
51435152

51445153
SET_NETDEV_DEV(netdev, mdev->device);
51455154

5146-
netdev->netdev_ops = &mlx5e_netdev_ops;
5155+
if (mlx5_core_is_mgmt_pf(mdev))
5156+
netdev->netdev_ops = &mlx5e_mgmt_netdev_ops;
5157+
else
5158+
netdev->netdev_ops = &mlx5e_netdev_ops;
5159+
51475160
netdev->xdp_metadata_ops = &mlx5e_xdp_metadata_ops;
51485161
netdev->xsk_tx_metadata_ops = &mlx5e_xsk_tx_metadata_ops;
51495162

@@ -6094,13 +6107,18 @@ static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
60946107
static int _mlx5e_probe(struct auxiliary_device *adev)
60956108
{
60966109
struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
6097-
const struct mlx5e_profile *profile = &mlx5e_nic_profile;
60986110
struct mlx5_core_dev *mdev = edev->mdev;
6111+
const struct mlx5e_profile *profile;
60996112
struct mlx5e_dev *mlx5e_dev;
61006113
struct net_device *netdev;
61016114
struct mlx5e_priv *priv;
61026115
int err;
61036116

6117+
if (mlx5_core_is_mgmt_pf(mdev))
6118+
profile = &mlx5e_mgmt_pf_nic_profile;
6119+
else
6120+
profile = &mlx5e_nic_profile;
6121+
61046122
mlx5e_dev = mlx5e_create_devlink(&adev->dev, mdev);
61056123
if (IS_ERR(mlx5e_dev))
61066124
return PTR_ERR(mlx5e_dev);

drivers/net/ethernet/mellanox/mlx5/core/eswitch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,7 @@ int mlx5_esw_sf_max_hpf_functions(struct mlx5_core_dev *dev, u16 *max_sfs, u16 *
16651665
void *hca_caps;
16661666
int err;
16671667

1668-
if (!mlx5_core_is_ecpf(dev)) {
1668+
if (!mlx5_core_is_ecpf(dev) || mlx5_core_is_mgmt_pf(dev)) {
16691669
*max_sfs = 0;
16701670
return 0;
16711671
}

0 commit comments

Comments
 (0)