Commit e95cc634 authored by Jiawen Wu's avatar Jiawen Wu Committed by Duanqiang Wen
Browse files

net: wangxun: add coalesce options support

mainline inclusion
from mainline-v6.8-rc1
commit 4ac2d9dff4b01fb210f951dcb67badcc2a1aa427
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I93QRU
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4ac2d9dff4b01fb210f951dcb67badcc2a1aa427



---------------------------------------------------------

Support to show RX/TX coalesce with ethtool -c and set RX/TX
coalesce with ethtool -C.

Signed-off-by: default avatarJiawen Wu <jiawenwu@trustnetic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarDuanqiang Wen <duanqiangwen@net-swift.com>
parent e6a095af
Loading
Loading
Loading
Loading
+101 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include "wx_type.h"
#include "wx_ethtool.h"
#include "wx_hw.h"
#include "wx_lib.h"

struct wx_stats {
	char stat_string[ETH_GSTRING_LEN];
@@ -247,3 +248,103 @@ void wx_get_ringparam(struct net_device *netdev,
	ring->rx_jumbo_pending = 0;
}
EXPORT_SYMBOL(wx_get_ringparam);

int wx_get_coalesce(struct net_device *netdev,
		    struct ethtool_coalesce *ec,
		    struct kernel_ethtool_coalesce *kernel_coal,
		    struct netlink_ext_ack *extack)
{
	struct wx *wx = netdev_priv(netdev);

	ec->tx_max_coalesced_frames_irq = wx->tx_work_limit;
	/* only valid if in constant ITR mode */
	if (wx->rx_itr_setting <= 1)
		ec->rx_coalesce_usecs = wx->rx_itr_setting;
	else
		ec->rx_coalesce_usecs = wx->rx_itr_setting >> 2;

	/* if in mixed tx/rx queues per vector mode, report only rx settings */
	if (wx->q_vector[0]->tx.count && wx->q_vector[0]->rx.count)
		return 0;

	/* only valid if in constant ITR mode */
	if (wx->tx_itr_setting <= 1)
		ec->tx_coalesce_usecs = wx->tx_itr_setting;
	else
		ec->tx_coalesce_usecs = wx->tx_itr_setting >> 2;

	return 0;
}
EXPORT_SYMBOL(wx_get_coalesce);

int wx_set_coalesce(struct net_device *netdev,
		    struct ethtool_coalesce *ec,
		    struct kernel_ethtool_coalesce *kernel_coal,
		    struct netlink_ext_ack *extack)
{
	struct wx *wx = netdev_priv(netdev);
	u16 tx_itr_param, rx_itr_param;
	struct wx_q_vector *q_vector;
	u16 max_eitr;
	int i;

	if (wx->q_vector[0]->tx.count && wx->q_vector[0]->rx.count) {
		/* reject Tx specific changes in case of mixed RxTx vectors */
		if (ec->tx_coalesce_usecs)
			return -EOPNOTSUPP;
	}

	if (ec->tx_max_coalesced_frames_irq)
		wx->tx_work_limit = ec->tx_max_coalesced_frames_irq;

	if (wx->mac.type == wx_mac_sp)
		max_eitr = WX_SP_MAX_EITR;
	else
		max_eitr = WX_EM_MAX_EITR;

	if ((ec->rx_coalesce_usecs > (max_eitr >> 2)) ||
	    (ec->tx_coalesce_usecs > (max_eitr >> 2)))
		return -EINVAL;

	if (ec->rx_coalesce_usecs > 1)
		wx->rx_itr_setting = ec->rx_coalesce_usecs << 2;
	else
		wx->rx_itr_setting = ec->rx_coalesce_usecs;

	if (wx->rx_itr_setting == 1)
		rx_itr_param = WX_20K_ITR;
	else
		rx_itr_param = wx->rx_itr_setting;

	if (ec->tx_coalesce_usecs > 1)
		wx->tx_itr_setting = ec->tx_coalesce_usecs << 2;
	else
		wx->tx_itr_setting = ec->tx_coalesce_usecs;

	if (wx->tx_itr_setting == 1) {
		if (wx->mac.type == wx_mac_sp)
			tx_itr_param = WX_12K_ITR;
		else
			tx_itr_param = WX_20K_ITR;
	} else {
		tx_itr_param = wx->tx_itr_setting;
	}

	/* mixed Rx/Tx */
	if (wx->q_vector[0]->tx.count && wx->q_vector[0]->rx.count)
		wx->tx_itr_setting = wx->rx_itr_setting;

	for (i = 0; i < wx->num_q_vectors; i++) {
		q_vector = wx->q_vector[i];
		if (q_vector->tx.count && !q_vector->rx.count)
			/* tx only */
			q_vector->itr = tx_itr_param;
		else
			/* rx only or mixed */
			q_vector->itr = rx_itr_param;
		wx_write_eitr(q_vector);
	}

	return 0;
}
EXPORT_SYMBOL(wx_set_coalesce);
+8 −0
Original line number Diff line number Diff line
@@ -26,4 +26,12 @@ void wx_get_ringparam(struct net_device *netdev,
		      struct ethtool_ringparam *ring,
		      struct kernel_ethtool_ringparam *kernel_ring,
		      struct netlink_ext_ack *extack);
int wx_get_coalesce(struct net_device *netdev,
		    struct ethtool_coalesce *ec,
		    struct kernel_ethtool_coalesce *kernel_coal,
		    struct netlink_ext_ack *extack);
int wx_set_coalesce(struct net_device *netdev,
		    struct ethtool_coalesce *ec,
		    struct kernel_ethtool_coalesce *kernel_coal,
		    struct netlink_ext_ack *extack);
#endif /* _WX_ETHTOOL_H_ */
+1 −1
Original line number Diff line number Diff line
@@ -2082,7 +2082,7 @@ static void wx_set_ivar(struct wx *wx, s8 direction,
 * when it needs to update EITR registers at runtime.  Hardware
 * specific quirks/differences are taken care of here.
 */
static void wx_write_eitr(struct wx_q_vector *q_vector)
void wx_write_eitr(struct wx_q_vector *q_vector)
{
	struct wx *wx = q_vector->wx;
	int v_idx = q_vector->v_idx;
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ void wx_free_irq(struct wx *wx);
int wx_setup_isb_resources(struct wx *wx);
void wx_free_isb_resources(struct wx *wx);
u32 wx_misc_isb(struct wx *wx, enum wx_isb_idx idx);
void wx_write_eitr(struct wx_q_vector *q_vector);
void wx_configure_vectors(struct wx *wx);
void wx_clean_all_rx_rings(struct wx *wx);
void wx_clean_all_tx_rings(struct wx *wx);
+1 −0
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ enum WX_MSCA_CMD_value {
#define WX_PX_IVAR_ALLOC_VAL         0x80 /* Interrupt Allocation valid */
#define WX_7K_ITR                    595
#define WX_12K_ITR                   336
#define WX_20K_ITR                   200
#define WX_SP_MAX_EITR               0x00000FF8U
#define WX_EM_MAX_EITR               0x00007FFCU

Loading