Skip to content

Commit

Permalink
net/mlx5e: Introduce SRIOV VF representors
Browse files Browse the repository at this point in the history
Implement the relevant profile functions to create mlx5e driver instance
serving as VF representor. When SRIOV offloads mode is enabled, each VF
will have a representor netdevice instance on the host.

To do that, we also export set of shared service functions from en_main.c,
such that they can be used by both NIC and repsresentors netdevs.

The newly created representor netdevice has a basic set of net_device_ops
which are the same ndo functions as the NIC netdevice and an ndo of it's
own for phys port name.

The profiling infrastructure allow sharing code between the NIC and the
vport representor even though the representor has only a subset of the
NIC functionality.

The VF reps and the PF which is used in that mode to represent the uplink,
expose switchdev ops. Currently the only op supposed is attr get for the
port parent ID which here serves to identify net-devices belonging to the
same HW E-Switch. Other than that, no offloading is implemented and hence
switching functionality is achieved if one sets SW switching rules, e.g
using tc, bridge or ovs.

Port phys name (ndo_get_phys_port_name) is implemented to allow exporting
to user-space the VF vport number and along with the switchdev port parent
id (phys_switch_id) enable a udev base consistent naming scheme:

SUBSYSTEM=="net", ACTION=="add", ATTR{phys_switch_id}=="<phys_switch_id>", \
        ATTR{phys_port_name}!="", NAME="$PF_NIC$attr{phys_port_name}"

where phys_switch_id is exposed by the PF (and VF reps) and $PF_NIC is
the name of the PF netdevice.

Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
hadarhenzion authored and davem330 committed Jul 2, 2016
1 parent 127ea38 commit cb67b83
Show file tree
Hide file tree
Showing 6 changed files with 574 additions and 19 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o eswitch.o eswitch_offloads.o \
en_main.o en_common.o en_fs.o en_ethtool.o en_tx.o \
en_rx.o en_rx_am.o en_txrx.o en_clock.o vxlan.o \
en_tc.o en_arfs.o
en_tc.o en_arfs.o en_rep.o

mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o
28 changes: 28 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <linux/mlx5/vport.h>
#include <linux/mlx5/transobj.h>
#include <linux/rhashtable.h>
#include <net/switchdev.h>
#include "wq.h"
#include "mlx5_core.h"
#include "en_stats.h"
Expand Down Expand Up @@ -816,4 +817,31 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev);
void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev);
int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5_core_dev *mdev);

struct mlx5_eswitch_rep;
int mlx5e_vport_rep_load(struct mlx5_eswitch *esw,
struct mlx5_eswitch_rep *rep);
void mlx5e_vport_rep_unload(struct mlx5_eswitch *esw,
struct mlx5_eswitch_rep *rep);
int mlx5e_nic_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep);
void mlx5e_nic_rep_unload(struct mlx5_eswitch *esw,
struct mlx5_eswitch_rep *rep);
int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv);
void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv);
int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr);

int mlx5e_create_direct_rqts(struct mlx5e_priv *priv);
void mlx5e_destroy_rqt(struct mlx5e_priv *priv, struct mlx5e_rqt *rqt);
int mlx5e_create_direct_tirs(struct mlx5e_priv *priv);
void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv);
int mlx5e_create_tises(struct mlx5e_priv *priv);
void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv);
int mlx5e_close(struct net_device *netdev);
int mlx5e_open(struct net_device *netdev);
void mlx5e_update_stats_work(struct work_struct *work);
void *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
const struct mlx5e_profile *profile, void *ppriv);
void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv);
struct rtnl_link_stats64 *
mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats);

#endif /* __MLX5_EN_H__ */
53 changes: 38 additions & 15 deletions drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
mlx5e_update_sw_counters(priv);
}

static void mlx5e_update_stats_work(struct work_struct *work)
void mlx5e_update_stats_work(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct mlx5e_priv *priv = container_of(dwork, struct mlx5e_priv,
Expand Down Expand Up @@ -1518,7 +1518,7 @@ static int mlx5e_create_rqt(struct mlx5e_priv *priv, int sz,
return err;
}

static void mlx5e_destroy_rqt(struct mlx5e_priv *priv, struct mlx5e_rqt *rqt)
void mlx5e_destroy_rqt(struct mlx5e_priv *priv, struct mlx5e_rqt *rqt)
{
rqt->enabled = false;
mlx5_core_destroy_rqt(priv->mdev, rqt->rqtn);
Expand All @@ -1531,7 +1531,7 @@ static int mlx5e_create_indirect_rqts(struct mlx5e_priv *priv)
return mlx5e_create_rqt(priv, MLX5E_INDIR_RQT_SIZE, 0, rqt);
}

static int mlx5e_create_direct_rqts(struct mlx5e_priv *priv)
int mlx5e_create_direct_rqts(struct mlx5e_priv *priv)
{
struct mlx5e_rqt *rqt;
int err;
Expand Down Expand Up @@ -1743,6 +1743,7 @@ static void mlx5e_netdev_set_tcs(struct net_device *netdev)
int mlx5e_open_locked(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5_core_dev *mdev = priv->mdev;
int num_txqs;
int err;

Expand Down Expand Up @@ -1778,9 +1779,14 @@ int mlx5e_open_locked(struct net_device *netdev)
#ifdef CONFIG_RFS_ACCEL
priv->netdev->rx_cpu_rmap = priv->mdev->rmap;
#endif
if (priv->profile->update_stats)
queue_delayed_work(priv->wq, &priv->update_stats_work, 0);

queue_delayed_work(priv->wq, &priv->update_stats_work, 0);

if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
err = mlx5e_add_sqs_fwd_rules(priv);
if (err)
goto err_close_channels;
}
return 0;

err_close_channels:
Expand All @@ -1790,7 +1796,7 @@ int mlx5e_open_locked(struct net_device *netdev)
return err;
}

static int mlx5e_open(struct net_device *netdev)
int mlx5e_open(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
int err;
Expand All @@ -1805,6 +1811,7 @@ static int mlx5e_open(struct net_device *netdev)
int mlx5e_close_locked(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5_core_dev *mdev = priv->mdev;

/* May already be CLOSED in case a previous configuration operation
* (e.g RX/TX queue size change) that involves close&open failed.
Expand All @@ -1814,6 +1821,9 @@ int mlx5e_close_locked(struct net_device *netdev)

clear_bit(MLX5E_STATE_OPENED, &priv->state);

if (MLX5_CAP_GEN(mdev, vport_group_manager))
mlx5e_remove_sqs_fwd_rules(priv);

mlx5e_timestamp_cleanup(priv);
netif_carrier_off(priv->netdev);
mlx5e_redirect_rqts(priv);
Expand All @@ -1822,7 +1832,7 @@ int mlx5e_close_locked(struct net_device *netdev)
return 0;
}

static int mlx5e_close(struct net_device *netdev)
int mlx5e_close(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
int err;
Expand Down Expand Up @@ -1957,7 +1967,7 @@ static void mlx5e_destroy_tis(struct mlx5e_priv *priv, int tc)
mlx5_core_destroy_tis(priv->mdev, priv->tisn[tc]);
}

static int mlx5e_create_tises(struct mlx5e_priv *priv)
int mlx5e_create_tises(struct mlx5e_priv *priv)
{
int err;
int tc;
Expand All @@ -1977,7 +1987,7 @@ static int mlx5e_create_tises(struct mlx5e_priv *priv)
return err;
}

static void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv)
void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv)
{
int tc;

Expand Down Expand Up @@ -2143,7 +2153,7 @@ static int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv)
return err;
}

static int mlx5e_create_direct_tirs(struct mlx5e_priv *priv)
int mlx5e_create_direct_tirs(struct mlx5e_priv *priv)
{
int nch = priv->profile->max_nch(priv->mdev);
struct mlx5e_tir *tir;
Expand Down Expand Up @@ -2190,7 +2200,7 @@ static void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv)
mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[i]);
}

static void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv)
void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv)
{
int nch = priv->profile->max_nch(priv->mdev);
int i;
Expand Down Expand Up @@ -2270,7 +2280,7 @@ static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
return mlx5e_setup_tc(dev, tc->tc);
}

static struct rtnl_link_stats64 *
struct rtnl_link_stats64 *
mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
struct mlx5e_priv *priv = netdev_priv(dev);
Expand Down Expand Up @@ -2988,6 +2998,10 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
}
}

static const struct switchdev_ops mlx5e_switchdev_ops = {
.switchdev_port_attr_get = mlx5e_attr_get,
};

static void mlx5e_build_nic_netdev(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
Expand Down Expand Up @@ -3069,6 +3083,11 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->priv_flags |= IFF_UNICAST_FLT;

mlx5e_set_netdev_dev_addr(netdev);

#ifdef CONFIG_NET_SWITCHDEV
if (MLX5_CAP_GEN(mdev, vport_group_manager))
netdev->switchdev_ops = &mlx5e_switchdev_ops;
#endif
}

static void mlx5e_create_q_counter(struct mlx5e_priv *priv)
Expand Down Expand Up @@ -3251,6 +3270,8 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
queue_work(priv->wq, &priv->set_rx_mode_work);

if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
rep.load = mlx5e_nic_rep_load;
rep.unload = mlx5e_nic_rep_unload;
rep.vport = 0;
rep.priv_data = priv;
mlx5_eswitch_register_vport_rep(esw, &rep);
Expand All @@ -3277,8 +3298,8 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
.max_tc = MLX5E_MAX_NUM_TC,
};

static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
const struct mlx5e_profile *profile, void *ppriv)
void *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
const struct mlx5e_profile *profile, void *ppriv)
{
struct net_device *netdev;
struct mlx5e_priv *priv;
Expand Down Expand Up @@ -3372,6 +3393,8 @@ static void mlx5e_register_vport_rep(struct mlx5_core_dev *mdev)
for (vport = 1; vport < total_vfs; vport++) {
struct mlx5_eswitch_rep rep;

rep.load = mlx5e_vport_rep_load;
rep.unload = mlx5e_vport_rep_unload;
rep.vport = vport;
mlx5_eswitch_register_vport_rep(esw, &rep);
}
Expand Down Expand Up @@ -3402,7 +3425,7 @@ static void *mlx5e_add(struct mlx5_core_dev *mdev)
return ret;
}

static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv)
void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, struct mlx5e_priv *priv)
{
const struct mlx5e_profile *profile = priv->profile;
struct net_device *netdev = priv->netdev;
Expand Down
Loading

0 comments on commit cb67b83

Please sign in to comment.