Commit cc628c96 authored by David S. Miller's avatar David S. Miller

Merge tag 'mlx5e-failsafe' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5e-failsafe 27-03-2017

This series provides a fail-safe mechanism to allow safely re-configuring
mlx5e netdevice and provides a resiliency against sporadic
configuration failures.

To enable this we do some refactoring and code reorganizing to allow
breaking the drivers open/close flows to stages:
      open -> activate -> deactivate -> close.

In addition we need to allow creating fresh HW ring resources
(mlx5e_channels) with their own "new" set of parameters, while keeping
the current ones running and active until the new channels are
successfully created with the new configuration, and only then we can
safly replace (switch) old channels with new ones.

For that we introduce mlx5e_channels object and an API to manage it:
 - channels = open_channels(new_params):
   open fresh TX/RX channels
 - activate_channels(channels):
   redirect traffic to them and attach them to the netdev
 - deactivate_channes(channels)
   stop traffic and detach from netdev
 - close(channels)
   Free the TX/RX HW resources of those channels

With the above strategy it is straightforward to achieve the desired
behavior of fail-safe configuration.  In pseudo code:

make_new_config(new_params)
{
	old_channels = current_active_channels;
	new_channels = create_channels(new_params);
	if (!new_channels)
		return "Failed, but current channels are still active :)"

	deactivate_channels(old_channels); /* Can't fail */
	set_hw_new_state();                /* If needed  */
	activate_channels(new_channels);   /* Can't fail */
	close_channels(old_channels);
	current_active_channels = new_channels;

        return "SUCCESS";
}

At the top of this series, we change the following flows to be fail-safe:
ethtool:
   - ring parameters
   - coalesce parameters
   - tx copy break parameters
   - cqe compressing/moderation mode setting (priv flags)
ndos:
   - tc setup
   - set features: LRO
   - change mtu
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 95ed0edd 2e20a151
...@@ -182,15 +182,15 @@ enum mlx5e_priv_flag { ...@@ -182,15 +182,15 @@ enum mlx5e_priv_flag {
MLX5E_PFLAG_RX_CQE_COMPRESS = (1 << 1), MLX5E_PFLAG_RX_CQE_COMPRESS = (1 << 1),
}; };
#define MLX5E_SET_PFLAG(priv, pflag, enable) \ #define MLX5E_SET_PFLAG(params, pflag, enable) \
do { \ do { \
if (enable) \ if (enable) \
(priv)->params.pflags |= (pflag); \ (params)->pflags |= (pflag); \
else \ else \
(priv)->params.pflags &= ~(pflag); \ (params)->pflags &= ~(pflag); \
} while (0) } while (0)
#define MLX5E_GET_PFLAG(priv, pflag) (!!((priv)->params.pflags & (pflag))) #define MLX5E_GET_PFLAG(params, pflag) (!!((params)->pflags & (pflag)))
#ifdef CONFIG_MLX5_CORE_EN_DCB #ifdef CONFIG_MLX5_CORE_EN_DCB
#define MLX5E_MAX_BW_ALLOC 100 /* Max percentage of BW allocation */ #define MLX5E_MAX_BW_ALLOC 100 /* Max percentage of BW allocation */
...@@ -213,7 +213,6 @@ struct mlx5e_params { ...@@ -213,7 +213,6 @@ struct mlx5e_params {
bool rx_cqe_compress_def; bool rx_cqe_compress_def;
struct mlx5e_cq_moder rx_cq_moderation; struct mlx5e_cq_moder rx_cq_moderation;
struct mlx5e_cq_moder tx_cq_moderation; struct mlx5e_cq_moder tx_cq_moderation;
u16 min_rx_wqes;
bool lro_en; bool lro_en;
u32 lro_wqe_sz; u32 lro_wqe_sz;
u16 tx_max_inline; u16 tx_max_inline;
...@@ -225,6 +224,7 @@ struct mlx5e_params { ...@@ -225,6 +224,7 @@ struct mlx5e_params {
bool rx_am_enabled; bool rx_am_enabled;
u32 lro_timeout; u32 lro_timeout;
u32 pflags; u32 pflags;
struct bpf_prog *xdp_prog;
}; };
#ifdef CONFIG_MLX5_CORE_EN_DCB #ifdef CONFIG_MLX5_CORE_EN_DCB
...@@ -280,7 +280,6 @@ struct mlx5e_cq { ...@@ -280,7 +280,6 @@ struct mlx5e_cq {
struct napi_struct *napi; struct napi_struct *napi;
struct mlx5_core_cq mcq; struct mlx5_core_cq mcq;
struct mlx5e_channel *channel; struct mlx5e_channel *channel;
struct mlx5e_priv *priv;
/* cqe decompression */ /* cqe decompression */
struct mlx5_cqe64 title; struct mlx5_cqe64 title;
...@@ -290,6 +289,7 @@ struct mlx5e_cq { ...@@ -290,6 +289,7 @@ struct mlx5e_cq {
u16 decmprs_wqe_counter; u16 decmprs_wqe_counter;
/* control */ /* control */
struct mlx5_core_dev *mdev;
struct mlx5_frag_wq_ctrl wq_ctrl; struct mlx5_frag_wq_ctrl wq_ctrl;
} ____cacheline_aligned_in_smp; } ____cacheline_aligned_in_smp;
...@@ -357,7 +357,7 @@ struct mlx5e_txqsq { ...@@ -357,7 +357,7 @@ struct mlx5e_txqsq {
/* control path */ /* control path */
struct mlx5_wq_ctrl wq_ctrl; struct mlx5_wq_ctrl wq_ctrl;
struct mlx5e_channel *channel; struct mlx5e_channel *channel;
int tc; int txq_ix;
u32 rate_limit; u32 rate_limit;
} ____cacheline_aligned_in_smp; } ____cacheline_aligned_in_smp;
...@@ -533,7 +533,7 @@ struct mlx5e_rq { ...@@ -533,7 +533,7 @@ struct mlx5e_rq {
u32 mpwqe_num_strides; u32 mpwqe_num_strides;
u32 rqn; u32 rqn;
struct mlx5e_channel *channel; struct mlx5e_channel *channel;
struct mlx5e_priv *priv; struct mlx5_core_dev *mdev;
struct mlx5_core_mkey umr_mkey; struct mlx5_core_mkey umr_mkey;
} ____cacheline_aligned_in_smp; } ____cacheline_aligned_in_smp;
...@@ -556,10 +556,18 @@ struct mlx5e_channel { ...@@ -556,10 +556,18 @@ struct mlx5e_channel {
/* control */ /* control */
struct mlx5e_priv *priv; struct mlx5e_priv *priv;
struct mlx5_core_dev *mdev;
struct mlx5e_tstamp *tstamp;
int ix; int ix;
int cpu; int cpu;
}; };
struct mlx5e_channels {
struct mlx5e_channel **c;
unsigned int num;
struct mlx5e_params params;
};
enum mlx5e_traffic_types { enum mlx5e_traffic_types {
MLX5E_TT_IPV4_TCP, MLX5E_TT_IPV4_TCP,
MLX5E_TT_IPV6_TCP, MLX5E_TT_IPV6_TCP,
...@@ -709,34 +717,17 @@ enum { ...@@ -709,34 +717,17 @@ enum {
MLX5E_NIC_PRIO MLX5E_NIC_PRIO
}; };
struct mlx5e_profile {
void (*init)(struct mlx5_core_dev *mdev,
struct net_device *netdev,
const struct mlx5e_profile *profile, void *ppriv);
void (*cleanup)(struct mlx5e_priv *priv);
int (*init_rx)(struct mlx5e_priv *priv);
void (*cleanup_rx)(struct mlx5e_priv *priv);
int (*init_tx)(struct mlx5e_priv *priv);
void (*cleanup_tx)(struct mlx5e_priv *priv);
void (*enable)(struct mlx5e_priv *priv);
void (*disable)(struct mlx5e_priv *priv);
void (*update_stats)(struct mlx5e_priv *priv);
int (*max_nch)(struct mlx5_core_dev *mdev);
int max_tc;
};
struct mlx5e_priv { struct mlx5e_priv {
/* priv data path fields - start */ /* priv data path fields - start */
struct mlx5e_txqsq **txq_to_sq_map; struct mlx5e_txqsq *txq2sq[MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC];
int channeltc_to_txq_map[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC]; int channel_tc2txq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
struct bpf_prog *xdp_prog;
/* priv data path fields - end */ /* priv data path fields - end */
unsigned long state; unsigned long state;
struct mutex state_lock; /* Protects Interface state */ struct mutex state_lock; /* Protects Interface state */
struct mlx5e_rq drop_rq; struct mlx5e_rq drop_rq;
struct mlx5e_channel **channel; struct mlx5e_channels channels;
u32 tisn[MLX5E_MAX_NUM_TC]; u32 tisn[MLX5E_MAX_NUM_TC];
struct mlx5e_rqt indir_rqt; struct mlx5e_rqt indir_rqt;
struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS]; struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS];
...@@ -746,7 +737,6 @@ struct mlx5e_priv { ...@@ -746,7 +737,6 @@ struct mlx5e_priv {
struct mlx5e_flow_steering fs; struct mlx5e_flow_steering fs;
struct mlx5e_vxlan_db vxlan; struct mlx5e_vxlan_db vxlan;
struct mlx5e_params params;
struct workqueue_struct *wq; struct workqueue_struct *wq;
struct work_struct update_carrier_work; struct work_struct update_carrier_work;
struct work_struct set_rx_mode_work; struct work_struct set_rx_mode_work;
...@@ -766,6 +756,22 @@ struct mlx5e_priv { ...@@ -766,6 +756,22 @@ struct mlx5e_priv {
void *ppriv; void *ppriv;
}; };
struct mlx5e_profile {
void (*init)(struct mlx5_core_dev *mdev,
struct net_device *netdev,
const struct mlx5e_profile *profile, void *ppriv);
void (*cleanup)(struct mlx5e_priv *priv);
int (*init_rx)(struct mlx5e_priv *priv);
void (*cleanup_rx)(struct mlx5e_priv *priv);
int (*init_tx)(struct mlx5e_priv *priv);
void (*cleanup_tx)(struct mlx5e_priv *priv);
void (*enable)(struct mlx5e_priv *priv);
void (*disable)(struct mlx5e_priv *priv);
void (*update_stats)(struct mlx5e_priv *priv);
int (*max_nch)(struct mlx5_core_dev *mdev);
int max_tc;
};
void mlx5e_build_ptys2ethtool_map(void); void mlx5e_build_ptys2ethtool_map(void);
u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb, u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
...@@ -827,7 +833,7 @@ void mlx5e_pps_event_handler(struct mlx5e_priv *priv, ...@@ -827,7 +833,7 @@ void mlx5e_pps_event_handler(struct mlx5e_priv *priv,
struct ptp_clock_event *event); struct ptp_clock_event *event);
int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr); int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr);
int mlx5e_hwstamp_get(struct net_device *dev, struct ifreq *ifr); int mlx5e_hwstamp_get(struct net_device *dev, struct ifreq *ifr);
void mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool val); int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool val);
int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto, int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto,
u16 vid); u16 vid);
...@@ -836,14 +842,40 @@ int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto, ...@@ -836,14 +842,40 @@ int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto,
void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv); void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv);
void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv); void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv);
int mlx5e_modify_rqs_vsd(struct mlx5e_priv *priv, bool vsd); int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd);
struct mlx5e_redirect_rqt_param {
bool is_rss;
union {
u32 rqn; /* Direct RQN (Non-RSS) */
struct {
u8 hfunc;
struct mlx5e_channels *channels;
} rss; /* RSS data */
};
};
int mlx5e_redirect_rqt(struct mlx5e_priv *priv, u32 rqtn, int sz, int ix); int mlx5e_redirect_rqt(struct mlx5e_priv *priv, u32 rqtn, int sz,
void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_priv *priv, void *tirc, struct mlx5e_redirect_rqt_param rrp);
enum mlx5e_traffic_types tt); void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_params *params,
enum mlx5e_traffic_types tt,
void *tirc);
int mlx5e_open_locked(struct net_device *netdev); int mlx5e_open_locked(struct net_device *netdev);
int mlx5e_close_locked(struct net_device *netdev); int mlx5e_close_locked(struct net_device *netdev);
int mlx5e_open_channels(struct mlx5e_priv *priv,
struct mlx5e_channels *chs);
void mlx5e_close_channels(struct mlx5e_channels *chs);
/* Function pointer to be used to modify WH settings while
* switching channels
*/
typedef int (*mlx5e_fp_hw_modify)(struct mlx5e_priv *priv);
void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
struct mlx5e_channels *new_chs,
mlx5e_fp_hw_modify hw_modify);
void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev, void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
u32 *indirection_rqt, int len, u32 *indirection_rqt, int len,
int num_channels); int num_channels);
...@@ -851,7 +883,8 @@ int mlx5e_get_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); ...@@ -851,7 +883,8 @@ int mlx5e_get_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params,
u8 cq_period_mode); u8 cq_period_mode);
void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type); void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev,
struct mlx5e_params *params, u8 rq_type);
static inline static inline
struct mlx5e_tx_wqe *mlx5e_post_nop(struct mlx5_wq_cyc *wq, u32 sqn, u16 *pc) struct mlx5e_tx_wqe *mlx5e_post_nop(struct mlx5_wq_cyc *wq, u32 sqn, u16 *pc)
...@@ -942,8 +975,7 @@ void mlx5e_destroy_tir(struct mlx5_core_dev *mdev, ...@@ -942,8 +975,7 @@ void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
struct mlx5e_tir *tir); struct mlx5e_tir *tir);
int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev); int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev);
void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev); void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev);
int mlx5e_refresh_tirs_self_loopback(struct mlx5_core_dev *mdev, int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb);
bool enable_uc_lb);
struct mlx5_eswitch_rep; struct mlx5_eswitch_rep;
int mlx5e_vport_rep_load(struct mlx5_eswitch *esw, int mlx5e_vport_rep_load(struct mlx5_eswitch *esw,
......
...@@ -90,6 +90,7 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr) ...@@ -90,6 +90,7 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr)
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
struct hwtstamp_config config; struct hwtstamp_config config;
int err;
if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz)) if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -111,7 +112,7 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr) ...@@ -111,7 +112,7 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr)
switch (config.rx_filter) { switch (config.rx_filter) {
case HWTSTAMP_FILTER_NONE: case HWTSTAMP_FILTER_NONE:
/* Reset CQE compression to Admin default */ /* Reset CQE compression to Admin default */
mlx5e_modify_rx_cqe_compression_locked(priv, priv->params.rx_cqe_compress_def); mlx5e_modify_rx_cqe_compression_locked(priv, priv->channels.params.rx_cqe_compress_def);
break; break;
case HWTSTAMP_FILTER_ALL: case HWTSTAMP_FILTER_ALL:
case HWTSTAMP_FILTER_SOME: case HWTSTAMP_FILTER_SOME:
...@@ -129,7 +130,12 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr) ...@@ -129,7 +130,12 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr)
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
/* Disable CQE compression */ /* Disable CQE compression */
netdev_warn(dev, "Disabling cqe compression"); netdev_warn(dev, "Disabling cqe compression");
mlx5e_modify_rx_cqe_compression_locked(priv, false); err = mlx5e_modify_rx_cqe_compression_locked(priv, false);
if (err) {
netdev_err(dev, "Failed disabling cqe compression err=%d\n", err);
mutex_unlock(&priv->state_lock);
return err;
}
config.rx_filter = HWTSTAMP_FILTER_ALL; config.rx_filter = HWTSTAMP_FILTER_ALL;
break; break;
default: default:
......
...@@ -136,18 +136,20 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev) ...@@ -136,18 +136,20 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev)
mlx5_core_dealloc_pd(mdev, res->pdn); mlx5_core_dealloc_pd(mdev, res->pdn);
} }
int mlx5e_refresh_tirs_self_loopback(struct mlx5_core_dev *mdev, int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
bool enable_uc_lb)
{ {
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5e_tir *tir; struct mlx5e_tir *tir;
void *in; int err = -ENOMEM;
u32 tirn = 0;
int inlen; int inlen;
int err = 0; void *in;
inlen = MLX5_ST_SZ_BYTES(modify_tir_in); inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
in = mlx5_vzalloc(inlen); in = mlx5_vzalloc(inlen);
if (!in) if (!in)
return -ENOMEM; goto out;
if (enable_uc_lb) if (enable_uc_lb)
MLX5_SET(modify_tir_in, in, ctx.self_lb_block, MLX5_SET(modify_tir_in, in, ctx.self_lb_block,
...@@ -156,13 +158,16 @@ int mlx5e_refresh_tirs_self_loopback(struct mlx5_core_dev *mdev, ...@@ -156,13 +158,16 @@ int mlx5e_refresh_tirs_self_loopback(struct mlx5_core_dev *mdev,
MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1); MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1);
list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) { list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) {
err = mlx5_core_modify_tir(mdev, tir->tirn, in, inlen); tirn = tir->tirn;
err = mlx5_core_modify_tir(mdev, tirn, in, inlen);
if (err) if (err)
goto out; goto out;
} }
out: out:
kvfree(in); kvfree(in);
if (err)
netdev_err(priv->netdev, "refresh tir(0x%x) failed, %d\n", tirn, err);
return err; return err;
} }
...@@ -390,7 +390,7 @@ static int validate_flow(struct mlx5e_priv *priv, ...@@ -390,7 +390,7 @@ static int validate_flow(struct mlx5e_priv *priv,
if (fs->location >= MAX_NUM_OF_ETHTOOL_RULES) if (fs->location >= MAX_NUM_OF_ETHTOOL_RULES)
return -EINVAL; return -EINVAL;
if (fs->ring_cookie >= priv->params.num_channels && if (fs->ring_cookie >= priv->channels.params.num_channels &&
fs->ring_cookie != RX_CLS_FLOW_DISC) fs->ring_cookie != RX_CLS_FLOW_DISC)
return -EINVAL; return -EINVAL;
......
...@@ -102,14 +102,16 @@ static void mlx5e_rep_update_sw_counters(struct mlx5e_priv *priv) ...@@ -102,14 +102,16 @@ static void mlx5e_rep_update_sw_counters(struct mlx5e_priv *priv)
int i, j; int i, j;
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
for (i = 0; i < priv->params.num_channels; i++) { for (i = 0; i < priv->channels.num; i++) {
rq_stats = &priv->channel[i]->rq.stats; struct mlx5e_channel *c = priv->channels.c[i];
rq_stats = &c->rq.stats;
s->rx_packets += rq_stats->packets; s->rx_packets += rq_stats->packets;
s->rx_bytes += rq_stats->bytes; s->rx_bytes += rq_stats->bytes;
for (j = 0; j < priv->params.num_tc; j++) { for (j = 0; j < priv->channels.params.num_tc; j++) {
sq_stats = &priv->channel[i]->sq[j].stats; sq_stats = &c->sq[j].stats;
s->tx_packets += sq_stats->packets; s->tx_packets += sq_stats->packets;
s->tx_bytes += sq_stats->bytes; s->tx_bytes += sq_stats->bytes;
...@@ -187,22 +189,26 @@ int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv) ...@@ -187,22 +189,26 @@ int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
struct mlx5_eswitch_rep *rep = priv->ppriv; struct mlx5_eswitch_rep *rep = priv->ppriv;
struct mlx5e_channel *c; struct mlx5e_channel *c;
int n, tc, err, num_sqs = 0; int n, tc, num_sqs = 0;
int err = -ENOMEM;
u16 *sqs; u16 *sqs;
sqs = kcalloc(priv->params.num_channels * priv->params.num_tc, sizeof(u16), GFP_KERNEL); sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(u16), GFP_KERNEL);
if (!sqs) if (!sqs)
return -ENOMEM; goto out;
for (n = 0; n < priv->params.num_channels; n++) { for (n = 0; n < priv->channels.num; n++) {
c = priv->channel[n]; c = priv->channels.c[n];
for (tc = 0; tc < c->num_tc; tc++) for (tc = 0; tc < c->num_tc; tc++)
sqs[num_sqs++] = c->sq[tc].sqn; sqs[num_sqs++] = c->sq[tc].sqn;
} }
err = mlx5_eswitch_sqs2vport_start(esw, rep, sqs, num_sqs); err = mlx5_eswitch_sqs2vport_start(esw, rep, sqs, num_sqs);
kfree(sqs); kfree(sqs);
out:
if (err)
netdev_warn(priv->netdev, "Failed to add SQs FWD rules %d\n", err);
return err; return err;
} }
...@@ -397,42 +403,23 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = { ...@@ -397,42 +403,23 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = {
.ndo_get_offload_stats = mlx5e_get_offload_stats, .ndo_get_offload_stats = mlx5e_get_offload_stats,
}; };
static void mlx5e_build_rep_netdev_priv(struct mlx5_core_dev *mdev, static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct mlx5e_params *params)
const struct mlx5e_profile *profile,
void *ppriv)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev);
u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ? u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
MLX5_CQ_PERIOD_MODE_START_FROM_CQE : MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
MLX5_CQ_PERIOD_MODE_START_FROM_EQE; MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
priv->params.log_sq_size = params->log_sq_size = MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE; params->rq_wq_type = MLX5_WQ_TYPE_LINKED_LIST;
priv->params.rq_wq_type = MLX5_WQ_TYPE_LINKED_LIST; params->log_rq_size = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
priv->params.log_rq_size = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
priv->params.min_rx_wqes = mlx5_min_rx_wqes(priv->params.rq_wq_type,
BIT(priv->params.log_rq_size));
priv->params.rx_am_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
mlx5e_set_rx_cq_mode_params(&priv->params, cq_period_mode);
priv->params.tx_max_inline = mlx5e_get_max_inline_cap(mdev); params->rx_am_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
priv->params.num_tc = 1; mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
priv->params.lro_wqe_sz = params->tx_max_inline = mlx5e_get_max_inline_cap(mdev);
MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ; params->num_tc = 1;
params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
priv->mdev = mdev;
priv->netdev = netdev;
priv->params.num_channels = profile->max_nch(mdev);
priv->profile = profile;
priv->ppriv = ppriv;
mutex_init(&priv->state_lock);
INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
} }
static void mlx5e_build_rep_netdev(struct net_device *netdev) static void mlx5e_build_rep_netdev(struct net_device *netdev)
...@@ -458,7 +445,19 @@ static void mlx5e_init_rep(struct mlx5_core_dev *mdev, ...@@ -458,7 +445,19 @@ static void mlx5e_init_rep(struct mlx5_core_dev *mdev,
const struct mlx5e_profile *profile, const struct mlx5e_profile *profile,
void *ppriv) void *ppriv)
{ {
mlx5e_build_rep_netdev_priv(mdev, netdev, profile, ppriv); struct mlx5e_priv *priv = netdev_priv(netdev);
priv->mdev = mdev;
priv->netdev = netdev;
priv->profile = profile;
priv->ppriv = ppriv;
mutex_init(&priv->state_lock);
INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
priv->channels.params.num_channels = profile->max_nch(mdev);
mlx5e_build_rep_params(mdev, &priv->channels.params);
mlx5e_build_rep_netdev(netdev); mlx5e_build_rep_netdev(netdev);
} }
...@@ -503,7 +502,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv) ...@@ -503,7 +502,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
err_destroy_direct_tirs: err_destroy_direct_tirs:
mlx5e_destroy_direct_tirs(priv); mlx5e_destroy_direct_tirs(priv);
err_destroy_direct_rqts: err_destroy_direct_rqts:
for (i = 0; i < priv->params.num_channels; i++) for (i = 0; i < priv->channels.params.num_channels; i++)
mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt); mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
return err; return err;
} }
...@@ -516,7 +515,7 @@ static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv) ...@@ -516,7 +515,7 @@ static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
mlx5e_tc_cleanup(priv); mlx5e_tc_cleanup(priv);
mlx5_del_flow_rules(rep->vport_rx_rule); mlx5_del_flow_rules(rep->vport_rx_rule);
mlx5e_destroy_direct_tirs(priv); mlx5e_destroy_direct_tirs(priv);
for (i = 0; i < priv->params.num_channels; i++) for (i = 0; i < priv->channels.params.num_channels; i++)
mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt); mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
} }
......
...@@ -156,28 +156,6 @@ static inline u32 mlx5e_decompress_cqes_start(struct mlx5e_rq *rq, ...@@ -156,28 +156,6 @@ static inline u32 mlx5e_decompress_cqes_start(struct mlx5e_rq *rq,
return mlx5e_decompress_cqes_cont(rq, cq, 1, budget_rem) - 1; return mlx5e_decompress_cqes_cont(rq, cq, 1, budget_rem) - 1;
} }
void mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool val)
{
bool was_opened;
if (!MLX5_CAP_GEN(priv->mdev, cqe_compression))
return;
if (MLX5E_GET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS) == val)
return;
was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
if (was_opened)
mlx5e_close_locked(priv->netdev);
MLX5E_SET_PFLAG(priv, MLX5E_PFLAG_RX_CQE_COMPRESS, val);
mlx5e_set_rq_type_params(priv, priv->params.rq_wq_type);
if (was_opened)
mlx5e_open_locked(priv->netdev);
}
#define RQ_PAGE_SIZE(rq) ((1 << rq->buff.page_order) << PAGE_SHIFT) #define RQ_PAGE_SIZE(rq) ((1 << rq->buff.page_order) << PAGE_SHIFT)
static inline bool mlx5e_rx_cache_put(struct mlx5e_rq *rq, static inline bool mlx5e_rx_cache_put(struct mlx5e_rq *rq,
......
...@@ -293,7 +293,7 @@ void mlx5e_rx_am_work(struct work_struct *work) ...@@ -293,7 +293,7 @@ void mlx5e_rx_am_work(struct work_struct *work)
struct mlx5e_rq *rq = container_of(am, struct mlx5e_rq, am); struct mlx5e_rq *rq = container_of(am, struct mlx5e_rq, am);
struct mlx5e_cq_moder cur_profile = profile[am->mode][am->profile_ix]; struct mlx5e_cq_moder cur_profile = profile[am->mode][am->profile_ix];
mlx5_core_modify_cq_moderation(rq->priv->mdev, &rq->cq.mcq, mlx5_core_modify_cq_moderation(rq->mdev, &rq->cq.mcq,
cur_profile.usec, cur_profile.pkts); cur_profile.usec, cur_profile.pkts);
am->state = MLX5E_AM_START_MEASURE; am->state = MLX5E_AM_START_MEASURE;
......
...@@ -236,12 +236,9 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv, ...@@ -236,12 +236,9 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv,
{ {
int err = 0; int err = 0;
err = mlx5e_refresh_tirs_self_loopback(priv->mdev, true); err = mlx5e_refresh_tirs(priv, true);
if (err) { if (err)
netdev_err(priv->netdev,
"\tFailed to enable UC loopback err(%d)\n", err);
return err; return err;
}
lbtp->loopback_ok = false; lbtp->loopback_ok = false;
init_completion(&lbtp->comp); init_completion(&lbtp->comp);
...@@ -258,7 +255,7 @@ static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv, ...@@ -258,7 +255,7 @@ static void mlx5e_test_loopback_cleanup(struct mlx5e_priv *priv,
struct mlx5e_lbt_priv *lbtp) struct mlx5e_lbt_priv *lbtp)
{ {
dev_remove_pack(&lbtp->pt); dev_remove_pack(&lbtp->pt);
mlx5e_refresh_tirs_self_loopback(priv->mdev, false); mlx5e_refresh_tirs(priv, false);
} }
#define MLX5E_LB_VERIFY_TIMEOUT (msecs_to_jiffies(200)) #define MLX5E_LB_VERIFY_TIMEOUT (msecs_to_jiffies(200))
......
...@@ -88,6 +88,7 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb, ...@@ -88,6 +88,7 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
int channel_ix = fallback(dev, skb); int channel_ix = fallback(dev, skb);
u16 num_channels;
int up = 0; int up = 0;
if (!netdev_get_num_tc(dev)) if (!netdev_get_num_tc(dev))
...@@ -99,11 +100,11 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb, ...@@ -99,11 +100,11 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
/* channel_ix can be larger than num_channels since /* channel_ix can be larger than num_channels since
* dev->num_real_tx_queues = num_channels * num_tc * dev->num_real_tx_queues = num_channels * num_tc
*/ */
if (channel_ix >= priv->params.num_channels) num_channels = priv->channels.params.num_channels;
channel_ix = reciprocal_scale(channel_ix, if (channel_ix >= num_channels)
priv->params.num_channels); channel_ix = reciprocal_scale(channel_ix, num_channels);
return priv->channeltc_to_txq_map[channel_ix][up]; return priv->channel_tc2txq[channel_ix][up];
} }
static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb) static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
...@@ -339,7 +340,7 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb) ...@@ -339,7 +340,7 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb)
netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev) netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5e_priv *priv = netdev_priv(dev);
struct mlx5e_txqsq *sq = priv->txq_to_sq_map[skb_get_queue_mapping(skb)]; struct mlx5e_txqsq *sq = priv->txq2sq[skb_get_queue_mapping(skb)];
return mlx5e_sq_xmit(sq, skb); return mlx5e_sq_xmit(sq, skb);
} }
......
...@@ -164,8 +164,7 @@ void mlx5e_cq_error_event(struct mlx5_core_cq *mcq, enum mlx5_event event) ...@@ -164,8 +164,7 @@ void mlx5e_cq_error_event(struct mlx5_core_cq *mcq, enum mlx5_event event)
{ {
struct mlx5e_cq *cq = container_of(mcq, struct mlx5e_cq, mcq); struct mlx5e_cq *cq = container_of(mcq, struct mlx5e_cq, mcq);
struct mlx5e_channel *c = cq->channel; struct mlx5e_channel *c = cq->channel;
struct mlx5e_priv *priv = c->priv; struct net_device *netdev = c->netdev;
struct net_device *netdev = priv->netdev;
netdev_err(netdev, "%s: cqn=0x%.6x event=0x%.2x\n", netdev_err(netdev, "%s: cqn=0x%.6x event=0x%.2x\n",
__func__, mcq->cqn, event); __func__, mcq->cqn, event);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment