Commit a8d5dd19 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mlx5-updates-2020-12-01' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



mlx5-updates-2020-12-01

mlx5e port TX timestamping support and MISC updates

1) Add support for port TX timestamping, for better PTP accuracy.

Currently in mlx5 HW TX timestamping is done on CQE (TX completion)
generation, which much earlier than when the packet actually goes out to
the wire, in this series Eran implements the option to do timestamping on
the port using a special SQ (Send Queue), such Send Queue will generate 2
CQEs (TX completions), the original one and a new one when the packet
leaves the port, due to the nature of this special handling, such mechanism
is an opt-in only and it is off by default to avoid any performance
degradation on normal traffic flows.

This patchset improves TX Hardware timestamping offset to be less than
40ns at a 100Gbps line rate, compared to 600ns before.

With that, making our HW compliant with G.8273.2 class C, and allow Linux
systems to be deployed in the 5G telco edge, where this standard is a must.

2) Misc updates and trivial improvements.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c22c0d55 2f6b379c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
		en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o \
		en_selftest.o en/port.o en/monitor_stats.o en/health.o \
		en/reporter_tx.o en/reporter_rx.o en/params.o en/xsk/pool.o \
		en/xsk/setup.o en/xsk/rx.o en/xsk/tx.o en/devlink.o
		en/xsk/setup.o en/xsk/rx.o en/xsk/tx.o en/devlink.o en/ptp.o

#
# Netdev extra
+55 −8
Original line number Diff line number Diff line
@@ -227,6 +227,7 @@ enum mlx5e_priv_flag {
	MLX5E_PFLAG_RX_NO_CSUM_COMPLETE,
	MLX5E_PFLAG_XDP_TX_MPWQE,
	MLX5E_PFLAG_SKB_TX_MPWQE,
	MLX5E_PFLAG_TX_PORT_TS,
	MLX5E_NUM_PFLAGS, /* Keep last */
};

@@ -282,10 +283,12 @@ struct mlx5e_cq {
	u16                        event_ctr;
	struct napi_struct        *napi;
	struct mlx5_core_cq        mcq;
	struct mlx5e_channel      *channel;
	struct mlx5e_ch_stats     *ch_stats;

	/* control */
	struct net_device         *netdev;
	struct mlx5_core_dev      *mdev;
	struct mlx5e_priv         *priv;
	struct mlx5_wq_ctrl        wq_ctrl;
} ____cacheline_aligned_in_smp;

@@ -329,6 +332,15 @@ struct mlx5e_tx_mpwqe {
	u8 inline_on;
};

struct mlx5e_skb_fifo {
	struct sk_buff **fifo;
	u16 *pc;
	u16 *cc;
	u16 mask;
};

struct mlx5e_ptpsq;

struct mlx5e_txqsq {
	/* data path */

@@ -349,11 +361,10 @@ struct mlx5e_txqsq {
	/* read only */
	struct mlx5_wq_cyc         wq;
	u32                        dma_fifo_mask;
	u16                        skb_fifo_mask;
	struct mlx5e_sq_stats     *stats;
	struct {
		struct mlx5e_sq_dma       *dma_fifo;
		struct sk_buff           **skb_fifo;
		struct mlx5e_skb_fifo      skb_fifo;
		struct mlx5e_tx_wqe_info  *wqe_info;
	} db;
	void __iomem              *uar_map;
@@ -367,14 +378,17 @@ struct mlx5e_txqsq {
	unsigned int               hw_mtu;
	struct hwtstamp_config    *tstamp;
	struct mlx5_clock         *clock;
	struct net_device         *netdev;
	struct mlx5_core_dev      *mdev;
	struct mlx5e_priv         *priv;

	/* control path */
	struct mlx5_wq_ctrl        wq_ctrl;
	struct mlx5e_channel      *channel;
	int                        ch_ix;
	int                        txq_ix;
	u32                        rate_limit;
	struct work_struct         recover_work;
	struct mlx5e_ptpsq        *ptpsq;
} ____cacheline_aligned_in_smp;

struct mlx5e_dma_info {
@@ -593,7 +607,6 @@ struct mlx5e_rq {
		u8             map_dir;   /* dma map direction */
	} buff;

	struct mlx5e_channel  *channel;
	struct device         *pdev;
	struct net_device     *netdev;
	struct mlx5e_rq_stats *stats;
@@ -602,6 +615,8 @@ struct mlx5e_rq {
	struct mlx5e_page_cache page_cache;
	struct hwtstamp_config *tstamp;
	struct mlx5_clock      *clock;
	struct mlx5e_icosq    *icosq;
	struct mlx5e_priv     *priv;

	mlx5e_fp_handle_rx_cqe handle_rx_cqe;
	mlx5e_fp_post_rx_wqes  post_wqes;
@@ -681,8 +696,11 @@ struct mlx5e_channel {
	int                        cpu;
};

struct mlx5e_port_ptp;

struct mlx5e_channels {
	struct mlx5e_channel **c;
	struct mlx5e_port_ptp  *port_ptp;
	unsigned int           num;
	struct mlx5e_params    params;
};
@@ -697,6 +715,12 @@ struct mlx5e_channel_stats {
	struct mlx5e_xdpsq_stats xsksq;
} ____cacheline_aligned_in_smp;

struct mlx5e_port_ptp_stats {
	struct mlx5e_ch_stats ch;
	struct mlx5e_sq_stats sq[MLX5E_MAX_NUM_TC];
	struct mlx5e_ptp_cq_stats cq[MLX5E_MAX_NUM_TC];
} ____cacheline_aligned_in_smp;

enum {
	MLX5E_STATE_OPENED,
	MLX5E_STATE_DESTROYING,
@@ -766,8 +790,10 @@ struct mlx5e_scratchpad {

struct mlx5e_priv {
	/* priv data path fields - start */
	struct mlx5e_txqsq *txq2sq[MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC];
	/* +1 for port ptp ts */
	struct mlx5e_txqsq *txq2sq[(MLX5E_MAX_NUM_CHANNELS + 1) * MLX5E_MAX_NUM_TC];
	int channel_tc2realtxq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
	int port_ptp_tc2realtxq[MLX5E_MAX_NUM_TC];
#ifdef CONFIG_MLX5_CORE_EN_DCB
	struct mlx5e_dcbx_dp       dcbx_dp;
#endif
@@ -802,12 +828,15 @@ struct mlx5e_priv {
	struct net_device         *netdev;
	struct mlx5e_stats         stats;
	struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS];
	struct mlx5e_port_ptp_stats port_ptp_stats;
	u16                        max_nch;
	u8                         max_opened_tc;
	bool                       port_ptp_opened;
	struct hwtstamp_config     tstamp;
	u16                        q_counter;
	u16                        drop_rq_q_counter;
	struct notifier_block      events_nb;
	int                        num_tc_x_num_ch;

	struct udp_tunnel_nic_info nic_info;
#ifdef CONFIG_MLX5_CORE_EN_DCB
@@ -923,9 +952,17 @@ int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,
		     struct mlx5e_xdpsq *sq, bool is_redirect);
void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq);

struct mlx5e_create_cq_param {
	struct napi_struct *napi;
	struct mlx5e_ch_stats *ch_stats;
	int node;
	int ix;
};

struct mlx5e_cq_param;
int mlx5e_open_cq(struct mlx5e_channel *c, struct dim_cq_moder moder,
		  struct mlx5e_cq_param *param, struct mlx5e_cq *cq);
int mlx5e_open_cq(struct mlx5e_priv *priv, struct dim_cq_moder moder,
		  struct mlx5e_cq_param *param, struct mlx5e_create_cq_param *ccp,
		  struct mlx5e_cq *cq);
void mlx5e_close_cq(struct mlx5e_cq *cq);

int mlx5e_open_locked(struct net_device *netdev);
@@ -974,7 +1011,17 @@ void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq);
int mlx5e_modify_sq(struct mlx5_core_dev *mdev, u32 sqn,
		    struct mlx5e_modify_sq_param *p);
void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq);
void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq);
void mlx5e_free_txqsq(struct mlx5e_txqsq *sq);
void mlx5e_tx_disable_queue(struct netdev_queue *txq);
int mlx5e_alloc_txqsq_db(struct mlx5e_txqsq *sq, int numa);
void mlx5e_free_txqsq_db(struct mlx5e_txqsq *sq);
struct mlx5e_create_sq_param;
int mlx5e_create_sq_rdy(struct mlx5_core_dev *mdev,
			struct mlx5e_sq_param *param,
			struct mlx5e_create_sq_param *csp,
			u32 *sqn);
void mlx5e_tx_err_cqe_work(struct work_struct *recover_work);

static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev)
{
+1 −2
Original line number Diff line number Diff line
@@ -287,8 +287,7 @@ void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv);
int mlx5e_create_flow_steering(struct mlx5e_priv *priv);
void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv);

bool mlx5e_tunnel_proto_supported(struct mlx5_core_dev *mdev, u8 proto_type);
bool mlx5e_any_tunnel_proto_supported(struct mlx5_core_dev *mdev);
u8 mlx5e_get_proto_by_tunnel_type(enum mlx5e_tunnel_types tt);

#endif /* __MLX5E_FLOW_STEER_H__ */
+7 −9
Original line number Diff line number Diff line
@@ -37,13 +37,12 @@ int mlx5e_health_fmsg_named_obj_nest_end(struct devlink_fmsg *fmsg)

int mlx5e_health_cq_diag_fmsg(struct mlx5e_cq *cq, struct devlink_fmsg *fmsg)
{
	struct mlx5e_priv *priv = cq->channel->priv;
	u32 out[MLX5_ST_SZ_DW(query_cq_out)] = {};
	u8 hw_status;
	void *cqc;
	int err;

	err = mlx5_core_query_cq(priv->mdev, &cq->mcq, out);
	err = mlx5_core_query_cq(cq->mdev, &cq->mcq, out);
	if (err)
		return err;

@@ -158,10 +157,8 @@ void mlx5e_health_channels_update(struct mlx5e_priv *priv)
						     DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
}

int mlx5e_health_sq_to_ready(struct mlx5e_channel *channel, u32 sqn)
int mlx5e_health_sq_to_ready(struct mlx5_core_dev *mdev, struct net_device *dev, u32 sqn)
{
	struct mlx5_core_dev *mdev = channel->mdev;
	struct net_device *dev = channel->netdev;
	struct mlx5e_modify_sq_param msp = {};
	int err;

@@ -206,21 +203,22 @@ int mlx5e_health_recover_channels(struct mlx5e_priv *priv)
	return err;
}

int mlx5e_health_channel_eq_recover(struct mlx5_eq_comp *eq, struct mlx5e_channel *channel)
int mlx5e_health_channel_eq_recover(struct net_device *dev, struct mlx5_eq_comp *eq,
				    struct mlx5e_ch_stats *stats)
{
	u32 eqe_count;

	netdev_err(channel->netdev, "EQ 0x%x: Cons = 0x%x, irqn = 0x%x\n",
	netdev_err(dev, "EQ 0x%x: Cons = 0x%x, irqn = 0x%x\n",
		   eq->core.eqn, eq->core.cons_index, eq->core.irqn);

	eqe_count = mlx5_eq_poll_irq_disabled(eq);
	if (!eqe_count)
		return -EIO;

	netdev_err(channel->netdev, "Recovered %d eqes on EQ 0x%x\n",
	netdev_err(dev, "Recovered %d eqes on EQ 0x%x\n",
		   eqe_count, eq->core.eqn);

	channel->stats->eq_rearm++;
	stats->eq_rearm++;
	return 0;
}

+3 −4
Original line number Diff line number Diff line
@@ -7,8 +7,6 @@
#include "en.h"
#include "diag/rsc_dump.h"

#define MLX5E_RX_ERR_CQE(cqe) (get_cqe_opcode(cqe) != MLX5_CQE_RESP_SEND)

static inline bool cqe_syndrome_needs_recover(u8 syndrome)
{
	return syndrome == MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR ||
@@ -42,8 +40,9 @@ struct mlx5e_err_ctx {
	void *ctx;
};

int mlx5e_health_sq_to_ready(struct mlx5e_channel *channel, u32 sqn);
int mlx5e_health_channel_eq_recover(struct mlx5_eq_comp *eq, struct mlx5e_channel *channel);
int mlx5e_health_sq_to_ready(struct mlx5_core_dev *mdev, struct net_device *dev, u32 sqn);
int mlx5e_health_channel_eq_recover(struct net_device *dev, struct mlx5_eq_comp *eq,
				    struct mlx5e_ch_stats *stats);
int mlx5e_health_recover_channels(struct mlx5e_priv *priv);
int mlx5e_health_report(struct mlx5e_priv *priv,
			struct devlink_health_reporter *reporter, char *err_str,
Loading