Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'mlx5e-next'



Achiad Shochat says:

====================
Driver updates 16-Aug-2015

This patchset contains bug fixes, new RSS and pause parameters ethtool
options, and support for RX CHECKSUM_COMPLETE.

Patchset was applied and tested over commit adc6310c ("Merge branch
'mv88e6xxx-switchdev-fdb'").
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0aa65cc0 bbceefce
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -42,22 +42,24 @@

#define MLX5E_MAX_NUM_TC	8

#define MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE                0x7
#define MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE                0x6
#define MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE                0xa
#define MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE                0xd

#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE                0x7
#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE                0x1
#define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE                0xa
#define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE                0xd

#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ                 (16 * 1024)
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ                 (64 * 1024)
#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC      0x10
#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS      0x20
#define MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC      0x10
#define MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS      0x20
#define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES                0x80
#define MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ         0x7

#define MLX5E_LOG_INDIR_RQT_SIZE       0x7
#define MLX5E_INDIR_RQT_SIZE           BIT(MLX5E_LOG_INDIR_RQT_SIZE)
#define MLX5E_MAX_NUM_CHANNELS         (MLX5E_INDIR_RQT_SIZE >> 1)
#define MLX5E_TX_CQ_POLL_BUDGET        128
#define MLX5E_UPDATE_STATS_INTERVAL    200 /* msecs */
#define MLX5E_SQ_BF_BUDGET             16
@@ -92,6 +94,7 @@ static const char vport_strings[][ETH_GSTRING_LEN] = {
	"lro_bytes",
	"rx_csum_good",
	"rx_csum_none",
	"rx_csum_sw",
	"tx_csum_offload",
	"tx_queue_stopped",
	"tx_queue_wake",
@@ -129,13 +132,14 @@ struct mlx5e_vport_stats {
	u64 lro_bytes;
	u64 rx_csum_good;
	u64 rx_csum_none;
	u64 rx_csum_sw;
	u64 tx_csum_offload;
	u64 tx_queue_stopped;
	u64 tx_queue_wake;
	u64 tx_queue_dropped;
	u64 rx_wqe_err;

#define NUM_VPORT_COUNTERS     31
#define NUM_VPORT_COUNTERS     32
};

static const char pport_strings[][ETH_GSTRING_LEN] = {
@@ -215,6 +219,7 @@ struct mlx5e_pport_stats {
static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
	"packets",
	"csum_none",
	"csum_sw",
	"lro_packets",
	"lro_bytes",
	"wqe_err"
@@ -223,10 +228,11 @@ static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
struct mlx5e_rq_stats {
	u64 packets;
	u64 csum_none;
	u64 csum_sw;
	u64 lro_packets;
	u64 lro_bytes;
	u64 wqe_err;
#define NUM_RQ_STATS 5
#define NUM_RQ_STATS 6
};

static const char sq_stats_strings[][ETH_GSTRING_LEN] = {
@@ -268,11 +274,12 @@ struct mlx5e_params {
	u16 tx_cq_moderation_usec;
	u16 tx_cq_moderation_pkts;
	u16 min_rx_wqes;
	u16 rx_hash_log_tbl_sz;
	bool lro_en;
	u32 lro_wqe_sz;
	u8  rss_hfunc;
	u16 tx_max_inline;
	u8  rss_hfunc;
	u8  toeplitz_hash_key[40];
	u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE];
};

enum {
@@ -569,6 +576,8 @@ 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_disable_vlan_filter(struct mlx5e_priv *priv);

int mlx5e_redirect_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix);

int mlx5e_open_locked(struct net_device *netdev);
int mlx5e_close_locked(struct net_device *netdev);

+108 −26
Original line number Diff line number Diff line
@@ -628,7 +628,7 @@ static int mlx5e_set_settings(struct net_device *netdev,
	u32 link_modes;
	u32 speed;
	u32 eth_proto_cap, eth_proto_admin;
	u8 port_status;
	enum mlx5_port_status ps;
	int err;

	speed = ethtool_cmd_speed(cmd);
@@ -662,26 +662,27 @@ static int mlx5e_set_settings(struct net_device *netdev,
	if (link_modes == eth_proto_admin)
		goto out;

	err = mlx5_set_port_proto(mdev, link_modes, MLX5_PTYS_EN);
	if (err) {
		netdev_err(netdev, "%s: set port eth proto admin failed: %d\n",
			   __func__, err);
		goto out;
	mlx5_query_port_admin_status(mdev, &ps);
	if (ps == MLX5_PORT_UP)
		mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);
	mlx5_set_port_proto(mdev, link_modes, MLX5_PTYS_EN);
	if (ps == MLX5_PORT_UP)
		mlx5_set_port_admin_status(mdev, MLX5_PORT_UP);

out:
	return err;
}

	err = mlx5_query_port_status(mdev, &port_status);
	if (err)
		goto out;
static u32 mlx5e_get_rxfh_key_size(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	if (port_status == MLX5_PORT_DOWN)
		return 0;
	return sizeof(priv->params.toeplitz_hash_key);
}

	err = mlx5_set_port_status(mdev, MLX5_PORT_DOWN);
	if (err)
		goto out;
	err = mlx5_set_port_status(mdev, MLX5_PORT_UP);
out:
	return err;
static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
{
	return MLX5E_INDIR_RQT_SIZE;
}

static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
@@ -689,6 +690,14 @@ static int mlx5e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	if (indir)
		memcpy(indir, priv->params.indirection_rqt,
		       sizeof(priv->params.indirection_rqt));

	if (key)
		memcpy(key, priv->params.toeplitz_hash_key,
		       sizeof(priv->params.toeplitz_hash_key));

	if (hfunc)
		*hfunc = priv->params.rss_hfunc;

@@ -699,28 +708,60 @@ static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
			  const u8 *key, const u8 hfunc)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	bool close_open;
	int err = 0;

	if (hfunc == ETH_RSS_HASH_NO_CHANGE)
		return 0;

	if ((hfunc != ETH_RSS_HASH_XOR) &&
	if ((hfunc != ETH_RSS_HASH_NO_CHANGE) &&
	    (hfunc != ETH_RSS_HASH_XOR) &&
	    (hfunc != ETH_RSS_HASH_TOP))
		return -EINVAL;

	mutex_lock(&priv->state_lock);

	priv->params.rss_hfunc = hfunc;
	if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
		mlx5e_close_locked(dev);
		err = mlx5e_open_locked(dev);
	if (indir) {
		memcpy(priv->params.indirection_rqt, indir,
		       sizeof(priv->params.indirection_rqt));
		mlx5e_redirect_rqt(priv, MLX5E_INDIRECTION_RQT);
	}

	close_open = (key || (hfunc != ETH_RSS_HASH_NO_CHANGE)) &&
		     test_bit(MLX5E_STATE_OPENED, &priv->state);
	if (close_open)
		mlx5e_close_locked(dev);

	if (key)
		memcpy(priv->params.toeplitz_hash_key, key,
		       sizeof(priv->params.toeplitz_hash_key));

	if (hfunc != ETH_RSS_HASH_NO_CHANGE)
		priv->params.rss_hfunc = hfunc;

	if (close_open)
		err = mlx5e_open_locked(priv->netdev);

	mutex_unlock(&priv->state_lock);

	return err;
}

static int mlx5e_get_rxnfc(struct net_device *netdev,
			   struct ethtool_rxnfc *info, u32 *rule_locs)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err = 0;

	switch (info->cmd) {
	case ETHTOOL_GRXRINGS:
		info->data = priv->params.num_channels;
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

static int mlx5e_get_tunable(struct net_device *dev,
			     const struct ethtool_tunable *tuna,
			     void *data)
@@ -779,6 +820,42 @@ static int mlx5e_set_tunable(struct net_device *dev,
	return err;
}

static void mlx5e_get_pauseparam(struct net_device *netdev,
				 struct ethtool_pauseparam *pauseparam)
{
	struct mlx5e_priv *priv    = netdev_priv(netdev);
	struct mlx5_core_dev *mdev = priv->mdev;
	int err;

	err = mlx5_query_port_pause(mdev, &pauseparam->rx_pause,
				    &pauseparam->tx_pause);
	if (err) {
		netdev_err(netdev, "%s: mlx5_query_port_pause failed:0x%x\n",
			   __func__, err);
	}
}

static int mlx5e_set_pauseparam(struct net_device *netdev,
				struct ethtool_pauseparam *pauseparam)
{
	struct mlx5e_priv *priv    = netdev_priv(netdev);
	struct mlx5_core_dev *mdev = priv->mdev;
	int err;

	if (pauseparam->autoneg)
		return -EINVAL;

	err = mlx5_set_port_pause(mdev,
				  pauseparam->rx_pause ? 1 : 0,
				  pauseparam->tx_pause ? 1 : 0);
	if (err) {
		netdev_err(netdev, "%s: mlx5_set_port_pause failed:0x%x\n",
			   __func__, err);
	}

	return err;
}

const struct ethtool_ops mlx5e_ethtool_ops = {
	.get_drvinfo       = mlx5e_get_drvinfo,
	.get_link          = ethtool_op_get_link,
@@ -793,8 +870,13 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
	.set_coalesce      = mlx5e_set_coalesce,
	.get_settings      = mlx5e_get_settings,
	.set_settings      = mlx5e_set_settings,
	.get_rxfh_key_size   = mlx5e_get_rxfh_key_size,
	.get_rxfh_indir_size = mlx5e_get_rxfh_indir_size,
	.get_rxfh          = mlx5e_get_rxfh,
	.set_rxfh          = mlx5e_set_rxfh,
	.get_rxnfc         = mlx5e_get_rxnfc,
	.get_tunable       = mlx5e_get_tunable,
	.set_tunable       = mlx5e_set_tunable,
	.get_pauseparam    = mlx5e_get_pauseparam,
	.set_pauseparam    = mlx5e_set_pauseparam,
};
+42 −38
Original line number Diff line number Diff line
@@ -149,6 +149,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
	s->lro_packets		= 0;
	s->lro_bytes		= 0;
	s->rx_csum_none		= 0;
	s->rx_csum_sw		= 0;
	s->rx_wqe_err		= 0;
	for (i = 0; i < priv->params.num_channels; i++) {
		rq_stats = &priv->channel[i]->rq.stats;
@@ -156,6 +157,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
		s->lro_packets	+= rq_stats->lro_packets;
		s->lro_bytes	+= rq_stats->lro_bytes;
		s->rx_csum_none	+= rq_stats->csum_none;
		s->rx_csum_sw	+= rq_stats->csum_sw;
		s->rx_wqe_err   += rq_stats->wqe_err;

		for (j = 0; j < priv->params.num_tc; j++) {
@@ -241,7 +243,8 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)

	/* Update calculated offload counters */
	s->tx_csum_offload = s->tx_packets - tx_offload_none;
	s->rx_csum_good    = s->rx_packets - s->rx_csum_none;
	s->rx_csum_good    = s->rx_packets - s->rx_csum_none -
			       s->rx_csum_sw;

	mlx5e_update_pport_counters(priv);
free_out:
@@ -1174,27 +1177,32 @@ static int mlx5e_bits_invert(unsigned long a, int size)
	return inv;
}

static void mlx5e_fill_rqt_rqns(struct mlx5e_priv *priv, void *rqtc,
				enum mlx5e_rqt_ix rqt_ix)
static void mlx5e_fill_indir_rqt_rqns(struct mlx5e_priv *priv, void *rqtc)
{
	int i;
	int log_sz;

	switch (rqt_ix) {
	case MLX5E_INDIRECTION_RQT:
		log_sz = priv->params.rx_hash_log_tbl_sz;
		for (i = 0; i < (1 << log_sz); i++) {
	for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++) {
		int ix = i;

		if (priv->params.rss_hfunc == ETH_RSS_HASH_XOR)
				ix = mlx5e_bits_invert(i, log_sz);
			ix = mlx5e_bits_invert(i, MLX5E_LOG_INDIR_RQT_SIZE);

		ix = priv->params.indirection_rqt[ix];
		ix = ix % priv->params.num_channels;
		MLX5_SET(rqtc, rqtc, rq_num[i],
			 test_bit(MLX5E_STATE_OPENED, &priv->state) ?
			 priv->channel[ix]->rq.rqn :
			 priv->drop_rq.rqn);
	}
}

static void mlx5e_fill_rqt_rqns(struct mlx5e_priv *priv, void *rqtc,
				enum mlx5e_rqt_ix rqt_ix)
{

	switch (rqt_ix) {
	case MLX5E_INDIRECTION_RQT:
		mlx5e_fill_indir_rqt_rqns(priv, rqtc);

		break;

@@ -1214,13 +1222,10 @@ static int mlx5e_create_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix)
	u32 *in;
	void *rqtc;
	int inlen;
	int log_sz;
	int sz;
	int err;

	log_sz = (rqt_ix == MLX5E_SINGLE_RQ_RQT) ? 0 :
		  priv->params.rx_hash_log_tbl_sz;
	sz = 1 << log_sz;
	sz = (rqt_ix == MLX5E_SINGLE_RQ_RQT) ? 1 : MLX5E_INDIR_RQT_SIZE;

	inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * sz;
	in = mlx5_vzalloc(inlen);
@@ -1241,19 +1246,16 @@ static int mlx5e_create_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix)
	return err;
}

static int mlx5e_redirect_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix)
int mlx5e_redirect_rqt(struct mlx5e_priv *priv, enum mlx5e_rqt_ix rqt_ix)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	u32 *in;
	void *rqtc;
	int inlen;
	int log_sz;
	int sz;
	int err;

	log_sz = (rqt_ix == MLX5E_SINGLE_RQ_RQT) ? 0 :
		  priv->params.rx_hash_log_tbl_sz;
	sz = 1 << log_sz;
	sz = (rqt_ix == MLX5E_SINGLE_RQ_RQT) ? 1 : MLX5E_INDIR_RQT_SIZE;

	inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + sizeof(u32) * sz;
	in = mlx5_vzalloc(inlen);
@@ -1301,7 +1303,7 @@ static void mlx5e_build_tir_ctx_lro(void *tirc, struct mlx5e_priv *priv)
		  ROUGH_MAX_L2_L3_HDR_SZ) >> 8);
	MLX5_SET(tirc, tirc, lro_timeout_period_usecs,
		 MLX5_CAP_ETH(priv->mdev,
			      lro_timer_supported_periods[3]));
			      lro_timer_supported_periods[2]));
}

static int mlx5e_modify_tir_lro(struct mlx5e_priv *priv, int tt)
@@ -1611,7 +1613,7 @@ static void mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 *tirc, int tt)
						       rx_hash_toeplitz_key);

			MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
			netdev_rss_key_fill(rss_key, len);
			memcpy(rss_key, priv->params.toeplitz_hash_key, len);
		}
		break;
	}
@@ -1911,9 +1913,10 @@ u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev)

static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
				    struct net_device *netdev,
				    int num_comp_vectors)
				    int num_channels)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int i;

	priv->params.log_sq_size           =
		MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
@@ -1930,22 +1933,22 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
	priv->params.tx_max_inline         = mlx5e_get_max_inline_cap(mdev);
	priv->params.min_rx_wqes           =
		MLX5E_PARAMS_DEFAULT_MIN_RX_WQES;
	priv->params.rx_hash_log_tbl_sz    =
		(order_base_2(num_comp_vectors) >
		 MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ) ?
		order_base_2(num_comp_vectors)           :
		MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ;
	priv->params.num_tc                = 1;
	priv->params.default_vlan_prio     = 0;
	priv->params.rss_hfunc             = ETH_RSS_HASH_XOR;

	priv->params.lro_en = false && !!MLX5_CAP_ETH(priv->mdev, lro_cap);
	netdev_rss_key_fill(priv->params.toeplitz_hash_key,
			    sizeof(priv->params.toeplitz_hash_key));

	for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++)
		priv->params.indirection_rqt[i] = i % num_channels;

	priv->params.lro_wqe_sz            =
		MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;

	priv->mdev                         = mdev;
	priv->netdev                       = netdev;
	priv->params.num_channels          = num_comp_vectors;
	priv->params.num_channels          = num_channels;
	priv->default_vlan_prio            = priv->params.default_vlan_prio;

	spin_lock_init(&priv->async_events_spinlock);
@@ -2034,19 +2037,20 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
{
	struct net_device *netdev;
	struct mlx5e_priv *priv;
	int ncv = mdev->priv.eq_table.num_comp_vectors;
	int nch = min_t(int, mdev->priv.eq_table.num_comp_vectors,
			MLX5E_MAX_NUM_CHANNELS);
	int err;

	if (mlx5e_check_required_hca_cap(mdev))
		return NULL;

	netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv), ncv, ncv);
	netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv), nch, nch);
	if (!netdev) {
		mlx5_core_err(mdev, "alloc_etherdev_mqs() failed\n");
		return NULL;
	}

	mlx5e_build_netdev_priv(mdev, netdev, ncv);
	mlx5e_build_netdev_priv(mdev, netdev, nch);
	mlx5e_build_netdev(netdev);

	netif_carrier_off(netdev);
+36 −10
Original line number Diff line number Diff line
@@ -111,10 +111,12 @@ static void mlx5e_lro_update_hdr(struct sk_buff *skb, struct mlx5_cqe64 *cqe)
		tcp = (struct tcphdr *)(skb->data + ETH_HLEN +
					sizeof(struct iphdr));
		ipv6 = NULL;
		skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
	} else {
		tcp = (struct tcphdr *)(skb->data + ETH_HLEN +
					sizeof(struct ipv6hdr));
		ipv4 = NULL;
		skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
	}

	if (get_cqe_lro_tcppsh(cqe))
@@ -149,6 +151,38 @@ static inline void mlx5e_skb_set_hash(struct mlx5_cqe64 *cqe,
	skb_set_hash(skb, be32_to_cpu(cqe->rss_hash_result), ht);
}

static inline bool is_first_ethertype_ip(struct sk_buff *skb)
{
	__be16 ethertype = ((struct ethhdr *)skb->data)->h_proto;

	return (ethertype == htons(ETH_P_IP) || ethertype == htons(ETH_P_IPV6));
}

static inline void mlx5e_handle_csum(struct net_device *netdev,
				     struct mlx5_cqe64 *cqe,
				     struct mlx5e_rq *rq,
				     struct sk_buff *skb)
{
	if (unlikely(!(netdev->features & NETIF_F_RXCSUM)))
		goto csum_none;

	if (likely(cqe->hds_ip_ext & CQE_L4_OK)) {
		skb->ip_summed = CHECKSUM_UNNECESSARY;
	} else if (is_first_ethertype_ip(skb)) {
		skb->ip_summed = CHECKSUM_COMPLETE;
		skb->csum = csum_unfold(cqe->check_sum);
		rq->stats.csum_sw++;
	} else {
		goto csum_none;
	}

	return;

csum_none:
	skb->ip_summed = CHECKSUM_NONE;
	rq->stats.csum_none++;
}

static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
				      struct mlx5e_rq *rq,
				      struct sk_buff *skb)
@@ -162,20 +196,12 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
	lro_num_seg = be32_to_cpu(cqe->srqn) >> 24;
	if (lro_num_seg > 1) {
		mlx5e_lro_update_hdr(skb, cqe);
		skb_shinfo(skb)->gso_size = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
		skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt, lro_num_seg);
		rq->stats.lro_packets++;
		rq->stats.lro_bytes += cqe_bcnt;
	}

	if (likely(netdev->features & NETIF_F_RXCSUM) &&
	    (cqe->hds_ip_ext & CQE_L2_OK) &&
	    (cqe->hds_ip_ext & CQE_L3_OK) &&
	    (cqe->hds_ip_ext & CQE_L4_OK)) {
		skb->ip_summed = CHECKSUM_UNNECESSARY;
	} else {
		skb->ip_summed = CHECKSUM_NONE;
		rq->stats.csum_none++;
	}
	mlx5e_handle_csum(netdev, cqe, rq, skb);

	skb->protocol = eth_type_trans(skb, netdev);

+52 −4
Original line number Diff line number Diff line
@@ -216,7 +216,7 @@ int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
}
EXPORT_SYMBOL_GPL(mlx5_set_port_proto);

int mlx5_set_port_status(struct mlx5_core_dev *dev,
int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
			       enum mlx5_port_status status)
{
	u32 in[MLX5_ST_SZ_DW(paos_reg)];
@@ -224,14 +224,17 @@ int mlx5_set_port_status(struct mlx5_core_dev *dev,

	memset(in, 0, sizeof(in));

	MLX5_SET(paos_reg, in, local_port, 1);
	MLX5_SET(paos_reg, in, admin_status, status);
	MLX5_SET(paos_reg, in, ase, 1);

	return mlx5_core_access_reg(dev, in, sizeof(in), out,
				    sizeof(out), MLX5_REG_PAOS, 0, 1);
}
EXPORT_SYMBOL_GPL(mlx5_set_port_admin_status);

int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
				 enum mlx5_port_status *status)
{
	u32 in[MLX5_ST_SZ_DW(paos_reg)];
	u32 out[MLX5_ST_SZ_DW(paos_reg)];
@@ -239,14 +242,17 @@ int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)

	memset(in, 0, sizeof(in));

	MLX5_SET(paos_reg, in, local_port, 1);

	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
				   sizeof(out), MLX5_REG_PAOS, 0, 0);
	if (err)
		return err;

	*status = MLX5_GET(paos_reg, out, oper_status);
	*status = MLX5_GET(paos_reg, out, admin_status);
	return err;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);

static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu,
				int *max_mtu, int *oper_mtu, u8 port)
@@ -328,3 +334,45 @@ int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev,
	return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_vl_hw_cap);

int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 rx_pause, u32 tx_pause)
{
	u32 in[MLX5_ST_SZ_DW(pfcc_reg)];
	u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
	int err;

	memset(in, 0, sizeof(in));
	MLX5_SET(pfcc_reg, in, local_port, 1);
	MLX5_SET(pfcc_reg, in, pptx, tx_pause);
	MLX5_SET(pfcc_reg, in, pprx, rx_pause);

	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
				   sizeof(out), MLX5_REG_PFCC, 0, 1);
	return err;
}
EXPORT_SYMBOL_GPL(mlx5_set_port_pause);

int mlx5_query_port_pause(struct mlx5_core_dev *dev,
			  u32 *rx_pause, u32 *tx_pause)
{
	u32 in[MLX5_ST_SZ_DW(pfcc_reg)];
	u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
	int err;

	memset(in, 0, sizeof(in));
	MLX5_SET(pfcc_reg, in, local_port, 1);

	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
				   sizeof(out), MLX5_REG_PFCC, 0, 0);
	if (err)
		return err;

	if (rx_pause)
		*rx_pause = MLX5_GET(pfcc_reg, out, pprx);

	if (tx_pause)
		*tx_pause = MLX5_GET(pfcc_reg, out, pptx);

	return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_pause);
Loading