net: wangxun: add ethtool_ops for ring parameters
Support to query RX/TX depth with ethtool -g, and change RX/TX depth with ethtool -G. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2fe2ca09da
commit
883b5984a5
@ -229,3 +229,21 @@ int wx_set_pauseparam(struct net_device *netdev,
|
||||
return phylink_ethtool_set_pauseparam(wx->phylink, pause);
|
||||
}
|
||||
EXPORT_SYMBOL(wx_set_pauseparam);
|
||||
|
||||
void wx_get_ringparam(struct net_device *netdev,
|
||||
struct ethtool_ringparam *ring,
|
||||
struct kernel_ethtool_ringparam *kernel_ring,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
|
||||
ring->rx_max_pending = WX_MAX_RXD;
|
||||
ring->tx_max_pending = WX_MAX_TXD;
|
||||
ring->rx_mini_max_pending = 0;
|
||||
ring->rx_jumbo_max_pending = 0;
|
||||
ring->rx_pending = wx->rx_ring_count;
|
||||
ring->tx_pending = wx->tx_ring_count;
|
||||
ring->rx_mini_pending = 0;
|
||||
ring->rx_jumbo_pending = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(wx_get_ringparam);
|
||||
|
@ -22,4 +22,8 @@ void wx_get_pauseparam(struct net_device *netdev,
|
||||
struct ethtool_pauseparam *pause);
|
||||
int wx_set_pauseparam(struct net_device *netdev,
|
||||
struct ethtool_pauseparam *pause);
|
||||
void wx_get_ringparam(struct net_device *netdev,
|
||||
struct ethtool_ringparam *ring,
|
||||
struct kernel_ethtool_ringparam *kernel_ring,
|
||||
struct netlink_ext_ack *extack);
|
||||
#endif /* _WX_ETHTOOL_H_ */
|
||||
|
@ -2671,4 +2671,70 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
|
||||
}
|
||||
EXPORT_SYMBOL(wx_set_features);
|
||||
|
||||
void wx_set_ring(struct wx *wx, u32 new_tx_count,
|
||||
u32 new_rx_count, struct wx_ring *temp_ring)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
||||
/* Setup new Tx resources and free the old Tx resources in that order.
|
||||
* We can then assign the new resources to the rings via a memcpy.
|
||||
* The advantage to this approach is that we are guaranteed to still
|
||||
* have resources even in the case of an allocation failure.
|
||||
*/
|
||||
if (new_tx_count != wx->tx_ring_count) {
|
||||
for (i = 0; i < wx->num_tx_queues; i++) {
|
||||
memcpy(&temp_ring[i], wx->tx_ring[i],
|
||||
sizeof(struct wx_ring));
|
||||
|
||||
temp_ring[i].count = new_tx_count;
|
||||
err = wx_setup_tx_resources(&temp_ring[i]);
|
||||
if (err) {
|
||||
wx_err(wx, "setup new tx resources failed, keep using the old config\n");
|
||||
while (i) {
|
||||
i--;
|
||||
wx_free_tx_resources(&temp_ring[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < wx->num_tx_queues; i++) {
|
||||
wx_free_tx_resources(wx->tx_ring[i]);
|
||||
|
||||
memcpy(wx->tx_ring[i], &temp_ring[i],
|
||||
sizeof(struct wx_ring));
|
||||
}
|
||||
|
||||
wx->tx_ring_count = new_tx_count;
|
||||
}
|
||||
|
||||
/* Repeat the process for the Rx rings if needed */
|
||||
if (new_rx_count != wx->rx_ring_count) {
|
||||
for (i = 0; i < wx->num_rx_queues; i++) {
|
||||
memcpy(&temp_ring[i], wx->rx_ring[i],
|
||||
sizeof(struct wx_ring));
|
||||
|
||||
temp_ring[i].count = new_rx_count;
|
||||
err = wx_setup_rx_resources(&temp_ring[i]);
|
||||
if (err) {
|
||||
wx_err(wx, "setup new rx resources failed, keep using the old config\n");
|
||||
while (i) {
|
||||
i--;
|
||||
wx_free_rx_resources(&temp_ring[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < wx->num_rx_queues; i++) {
|
||||
wx_free_rx_resources(wx->rx_ring[i]);
|
||||
memcpy(wx->rx_ring[i], &temp_ring[i],
|
||||
sizeof(struct wx_ring));
|
||||
}
|
||||
|
||||
wx->rx_ring_count = new_rx_count;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(wx_set_ring);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -29,5 +29,7 @@ int wx_setup_resources(struct wx *wx);
|
||||
void wx_get_stats64(struct net_device *netdev,
|
||||
struct rtnl_link_stats64 *stats);
|
||||
int wx_set_features(struct net_device *netdev, netdev_features_t features);
|
||||
void wx_set_ring(struct wx *wx, u32 new_tx_count,
|
||||
u32 new_rx_count, struct wx_ring *temp_ring);
|
||||
|
||||
#endif /* _NGBE_LIB_H_ */
|
||||
|
@ -412,6 +412,12 @@ enum WX_MSCA_CMD_value {
|
||||
|
||||
#define WX_MAX_RXD 8192
|
||||
#define WX_MAX_TXD 8192
|
||||
#define WX_MIN_RXD 128
|
||||
#define WX_MIN_TXD 128
|
||||
|
||||
/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
|
||||
#define WX_REQ_RX_DESCRIPTOR_MULTIPLE 8
|
||||
#define WX_REQ_TX_DESCRIPTOR_MULTIPLE 8
|
||||
|
||||
#define WX_MAX_JUMBO_FRAME_SIZE 9432 /* max payload 9414 */
|
||||
#define VMDQ_P(p) p
|
||||
|
@ -7,7 +7,10 @@
|
||||
|
||||
#include "../libwx/wx_ethtool.h"
|
||||
#include "../libwx/wx_type.h"
|
||||
#include "../libwx/wx_lib.h"
|
||||
#include "../libwx/wx_hw.h"
|
||||
#include "ngbe_ethtool.h"
|
||||
#include "ngbe_type.h"
|
||||
|
||||
static void ngbe_get_wol(struct net_device *netdev,
|
||||
struct ethtool_wolinfo *wol)
|
||||
@ -41,6 +44,54 @@ static int ngbe_set_wol(struct net_device *netdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ngbe_set_ringparam(struct net_device *netdev,
|
||||
struct ethtool_ringparam *ring,
|
||||
struct kernel_ethtool_ringparam *kernel_ring,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
u32 new_rx_count, new_tx_count;
|
||||
struct wx_ring *temp_ring;
|
||||
int i;
|
||||
|
||||
new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
|
||||
new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
|
||||
|
||||
new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD);
|
||||
new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE);
|
||||
|
||||
if (new_tx_count == wx->tx_ring_count &&
|
||||
new_rx_count == wx->rx_ring_count)
|
||||
return 0;
|
||||
|
||||
if (!netif_running(wx->netdev)) {
|
||||
for (i = 0; i < wx->num_tx_queues; i++)
|
||||
wx->tx_ring[i]->count = new_tx_count;
|
||||
for (i = 0; i < wx->num_rx_queues; i++)
|
||||
wx->rx_ring[i]->count = new_rx_count;
|
||||
wx->tx_ring_count = new_tx_count;
|
||||
wx->rx_ring_count = new_rx_count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate temporary buffer to store rings in */
|
||||
i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
|
||||
temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
|
||||
if (!temp_ring)
|
||||
return -ENOMEM;
|
||||
|
||||
ngbe_down(wx);
|
||||
|
||||
wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring);
|
||||
kvfree(temp_ring);
|
||||
|
||||
wx_configure(wx);
|
||||
ngbe_up(wx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops ngbe_ethtool_ops = {
|
||||
.get_drvinfo = wx_get_drvinfo,
|
||||
.get_link = ethtool_op_get_link,
|
||||
@ -56,6 +107,8 @@ static const struct ethtool_ops ngbe_ethtool_ops = {
|
||||
.get_pause_stats = wx_get_pause_stats,
|
||||
.get_pauseparam = wx_get_pauseparam,
|
||||
.set_pauseparam = wx_set_pauseparam,
|
||||
.get_ringparam = wx_get_ringparam,
|
||||
.set_ringparam = ngbe_set_ringparam,
|
||||
};
|
||||
|
||||
void ngbe_set_ethtool_ops(struct net_device *netdev)
|
||||
|
@ -334,7 +334,7 @@ static void ngbe_disable_device(struct wx *wx)
|
||||
wx_update_stats(wx);
|
||||
}
|
||||
|
||||
static void ngbe_down(struct wx *wx)
|
||||
void ngbe_down(struct wx *wx)
|
||||
{
|
||||
phylink_stop(wx->phylink);
|
||||
ngbe_disable_device(wx);
|
||||
@ -342,7 +342,7 @@ static void ngbe_down(struct wx *wx)
|
||||
wx_clean_all_rx_rings(wx);
|
||||
}
|
||||
|
||||
static void ngbe_up(struct wx *wx)
|
||||
void ngbe_up(struct wx *wx)
|
||||
{
|
||||
wx_configure_vectors(wx);
|
||||
|
||||
|
@ -130,4 +130,7 @@
|
||||
|
||||
extern char ngbe_driver_name[];
|
||||
|
||||
void ngbe_down(struct wx *wx);
|
||||
void ngbe_up(struct wx *wx);
|
||||
|
||||
#endif /* _NGBE_TYPE_H_ */
|
||||
|
@ -7,9 +7,57 @@
|
||||
|
||||
#include "../libwx/wx_ethtool.h"
|
||||
#include "../libwx/wx_type.h"
|
||||
#include "../libwx/wx_lib.h"
|
||||
#include "txgbe_type.h"
|
||||
#include "txgbe_ethtool.h"
|
||||
|
||||
static int txgbe_set_ringparam(struct net_device *netdev,
|
||||
struct ethtool_ringparam *ring,
|
||||
struct kernel_ethtool_ringparam *kernel_ring,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct wx *wx = netdev_priv(netdev);
|
||||
u32 new_rx_count, new_tx_count;
|
||||
struct wx_ring *temp_ring;
|
||||
int i;
|
||||
|
||||
new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
|
||||
new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
|
||||
|
||||
new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD);
|
||||
new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE);
|
||||
|
||||
if (new_tx_count == wx->tx_ring_count &&
|
||||
new_rx_count == wx->rx_ring_count)
|
||||
return 0;
|
||||
|
||||
if (!netif_running(wx->netdev)) {
|
||||
for (i = 0; i < wx->num_tx_queues; i++)
|
||||
wx->tx_ring[i]->count = new_tx_count;
|
||||
for (i = 0; i < wx->num_rx_queues; i++)
|
||||
wx->rx_ring[i]->count = new_rx_count;
|
||||
wx->tx_ring_count = new_tx_count;
|
||||
wx->rx_ring_count = new_rx_count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate temporary buffer to store rings in */
|
||||
i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
|
||||
temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
|
||||
if (!temp_ring)
|
||||
return -ENOMEM;
|
||||
|
||||
txgbe_down(wx);
|
||||
|
||||
wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring);
|
||||
kvfree(temp_ring);
|
||||
|
||||
txgbe_up(wx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops txgbe_ethtool_ops = {
|
||||
.get_drvinfo = wx_get_drvinfo,
|
||||
.nway_reset = wx_nway_reset,
|
||||
@ -23,6 +71,8 @@ static const struct ethtool_ops txgbe_ethtool_ops = {
|
||||
.get_pause_stats = wx_get_pause_stats,
|
||||
.get_pauseparam = wx_get_pauseparam,
|
||||
.set_pauseparam = wx_set_pauseparam,
|
||||
.get_ringparam = wx_get_ringparam,
|
||||
.set_ringparam = txgbe_set_ringparam,
|
||||
};
|
||||
|
||||
void txgbe_set_ethtool_ops(struct net_device *netdev)
|
||||
|
@ -288,7 +288,7 @@ static void txgbe_disable_device(struct wx *wx)
|
||||
wx_update_stats(wx);
|
||||
}
|
||||
|
||||
static void txgbe_down(struct wx *wx)
|
||||
void txgbe_down(struct wx *wx)
|
||||
{
|
||||
txgbe_disable_device(wx);
|
||||
txgbe_reset(wx);
|
||||
@ -298,6 +298,12 @@ static void txgbe_down(struct wx *wx)
|
||||
wx_clean_all_rx_rings(wx);
|
||||
}
|
||||
|
||||
void txgbe_up(struct wx *wx)
|
||||
{
|
||||
wx_configure(wx);
|
||||
txgbe_up_complete(wx);
|
||||
}
|
||||
|
||||
/**
|
||||
* txgbe_init_type_code - Initialize the shared code
|
||||
* @wx: pointer to hardware structure
|
||||
|
@ -129,6 +129,9 @@
|
||||
|
||||
extern char txgbe_driver_name[];
|
||||
|
||||
void txgbe_down(struct wx *wx);
|
||||
void txgbe_up(struct wx *wx);
|
||||
|
||||
#define NODE_PROP(_NAME, _PROP) \
|
||||
(const struct software_node) { \
|
||||
.name = _NAME, \
|
||||
|
Loading…
Reference in New Issue
Block a user