mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-16 23:36:09 -05:00
net: wangxun: add coalesce options support
Support to show RX/TX coalesce with ethtool -c and set RX/TX coalesce with ethtool -C. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
883b5984a5
commit
4ac2d9dff4
@@ -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);
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -93,6 +93,8 @@ static int ngbe_set_ringparam(struct net_device *netdev,
|
||||
}
|
||||
|
||||
static const struct ethtool_ops ngbe_ethtool_ops = {
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ,
|
||||
.get_drvinfo = wx_get_drvinfo,
|
||||
.get_link = ethtool_op_get_link,
|
||||
.get_link_ksettings = wx_get_link_ksettings,
|
||||
@@ -109,6 +111,8 @@ static const struct ethtool_ops ngbe_ethtool_ops = {
|
||||
.set_pauseparam = wx_set_pauseparam,
|
||||
.get_ringparam = wx_get_ringparam,
|
||||
.set_ringparam = ngbe_set_ringparam,
|
||||
.get_coalesce = wx_get_coalesce,
|
||||
.set_coalesce = wx_set_coalesce,
|
||||
};
|
||||
|
||||
void ngbe_set_ethtool_ops(struct net_device *netdev)
|
||||
|
||||
@@ -59,6 +59,8 @@ static int txgbe_set_ringparam(struct net_device *netdev,
|
||||
}
|
||||
|
||||
static const struct ethtool_ops txgbe_ethtool_ops = {
|
||||
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
|
||||
ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ,
|
||||
.get_drvinfo = wx_get_drvinfo,
|
||||
.nway_reset = wx_nway_reset,
|
||||
.get_link = ethtool_op_get_link,
|
||||
@@ -73,6 +75,8 @@ static const struct ethtool_ops txgbe_ethtool_ops = {
|
||||
.set_pauseparam = wx_set_pauseparam,
|
||||
.get_ringparam = wx_get_ringparam,
|
||||
.set_ringparam = txgbe_set_ringparam,
|
||||
.get_coalesce = wx_get_coalesce,
|
||||
.set_coalesce = wx_set_coalesce,
|
||||
};
|
||||
|
||||
void txgbe_set_ethtool_ops(struct net_device *netdev)
|
||||
|
||||
Reference in New Issue
Block a user