Skip to content

Commit 883b598

Browse files
Jiawen Wudavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2fe2ca0 commit 883b598

File tree

11 files changed

+214
-3
lines changed

11 files changed

+214
-3
lines changed

drivers/net/ethernet/wangxun/libwx/wx_ethtool.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,21 @@ int wx_set_pauseparam(struct net_device *netdev,
229229
return phylink_ethtool_set_pauseparam(wx->phylink, pause);
230230
}
231231
EXPORT_SYMBOL(wx_set_pauseparam);
232+
233+
void wx_get_ringparam(struct net_device *netdev,
234+
struct ethtool_ringparam *ring,
235+
struct kernel_ethtool_ringparam *kernel_ring,
236+
struct netlink_ext_ack *extack)
237+
{
238+
struct wx *wx = netdev_priv(netdev);
239+
240+
ring->rx_max_pending = WX_MAX_RXD;
241+
ring->tx_max_pending = WX_MAX_TXD;
242+
ring->rx_mini_max_pending = 0;
243+
ring->rx_jumbo_max_pending = 0;
244+
ring->rx_pending = wx->rx_ring_count;
245+
ring->tx_pending = wx->tx_ring_count;
246+
ring->rx_mini_pending = 0;
247+
ring->rx_jumbo_pending = 0;
248+
}
249+
EXPORT_SYMBOL(wx_get_ringparam);

drivers/net/ethernet/wangxun/libwx/wx_ethtool.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,8 @@ void wx_get_pauseparam(struct net_device *netdev,
2222
struct ethtool_pauseparam *pause);
2323
int wx_set_pauseparam(struct net_device *netdev,
2424
struct ethtool_pauseparam *pause);
25+
void wx_get_ringparam(struct net_device *netdev,
26+
struct ethtool_ringparam *ring,
27+
struct kernel_ethtool_ringparam *kernel_ring,
28+
struct netlink_ext_ack *extack);
2529
#endif /* _WX_ETHTOOL_H_ */

drivers/net/ethernet/wangxun/libwx/wx_lib.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,4 +2671,70 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
26712671
}
26722672
EXPORT_SYMBOL(wx_set_features);
26732673

2674+
void wx_set_ring(struct wx *wx, u32 new_tx_count,
2675+
u32 new_rx_count, struct wx_ring *temp_ring)
2676+
{
2677+
int i, err = 0;
2678+
2679+
/* Setup new Tx resources and free the old Tx resources in that order.
2680+
* We can then assign the new resources to the rings via a memcpy.
2681+
* The advantage to this approach is that we are guaranteed to still
2682+
* have resources even in the case of an allocation failure.
2683+
*/
2684+
if (new_tx_count != wx->tx_ring_count) {
2685+
for (i = 0; i < wx->num_tx_queues; i++) {
2686+
memcpy(&temp_ring[i], wx->tx_ring[i],
2687+
sizeof(struct wx_ring));
2688+
2689+
temp_ring[i].count = new_tx_count;
2690+
err = wx_setup_tx_resources(&temp_ring[i]);
2691+
if (err) {
2692+
wx_err(wx, "setup new tx resources failed, keep using the old config\n");
2693+
while (i) {
2694+
i--;
2695+
wx_free_tx_resources(&temp_ring[i]);
2696+
}
2697+
return;
2698+
}
2699+
}
2700+
2701+
for (i = 0; i < wx->num_tx_queues; i++) {
2702+
wx_free_tx_resources(wx->tx_ring[i]);
2703+
2704+
memcpy(wx->tx_ring[i], &temp_ring[i],
2705+
sizeof(struct wx_ring));
2706+
}
2707+
2708+
wx->tx_ring_count = new_tx_count;
2709+
}
2710+
2711+
/* Repeat the process for the Rx rings if needed */
2712+
if (new_rx_count != wx->rx_ring_count) {
2713+
for (i = 0; i < wx->num_rx_queues; i++) {
2714+
memcpy(&temp_ring[i], wx->rx_ring[i],
2715+
sizeof(struct wx_ring));
2716+
2717+
temp_ring[i].count = new_rx_count;
2718+
err = wx_setup_rx_resources(&temp_ring[i]);
2719+
if (err) {
2720+
wx_err(wx, "setup new rx resources failed, keep using the old config\n");
2721+
while (i) {
2722+
i--;
2723+
wx_free_rx_resources(&temp_ring[i]);
2724+
}
2725+
return;
2726+
}
2727+
}
2728+
2729+
for (i = 0; i < wx->num_rx_queues; i++) {
2730+
wx_free_rx_resources(wx->rx_ring[i]);
2731+
memcpy(wx->rx_ring[i], &temp_ring[i],
2732+
sizeof(struct wx_ring));
2733+
}
2734+
2735+
wx->rx_ring_count = new_rx_count;
2736+
}
2737+
}
2738+
EXPORT_SYMBOL(wx_set_ring);
2739+
26742740
MODULE_LICENSE("GPL");

drivers/net/ethernet/wangxun/libwx/wx_lib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,7 @@ int wx_setup_resources(struct wx *wx);
2929
void wx_get_stats64(struct net_device *netdev,
3030
struct rtnl_link_stats64 *stats);
3131
int wx_set_features(struct net_device *netdev, netdev_features_t features);
32+
void wx_set_ring(struct wx *wx, u32 new_tx_count,
33+
u32 new_rx_count, struct wx_ring *temp_ring);
3234

3335
#endif /* _NGBE_LIB_H_ */

drivers/net/ethernet/wangxun/libwx/wx_type.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,12 @@ enum WX_MSCA_CMD_value {
412412

413413
#define WX_MAX_RXD 8192
414414
#define WX_MAX_TXD 8192
415+
#define WX_MIN_RXD 128
416+
#define WX_MIN_TXD 128
417+
418+
/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
419+
#define WX_REQ_RX_DESCRIPTOR_MULTIPLE 8
420+
#define WX_REQ_TX_DESCRIPTOR_MULTIPLE 8
415421

416422
#define WX_MAX_JUMBO_FRAME_SIZE 9432 /* max payload 9414 */
417423
#define VMDQ_P(p) p

drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77

88
#include "../libwx/wx_ethtool.h"
99
#include "../libwx/wx_type.h"
10+
#include "../libwx/wx_lib.h"
11+
#include "../libwx/wx_hw.h"
1012
#include "ngbe_ethtool.h"
13+
#include "ngbe_type.h"
1114

1215
static void ngbe_get_wol(struct net_device *netdev,
1316
struct ethtool_wolinfo *wol)
@@ -41,6 +44,54 @@ static int ngbe_set_wol(struct net_device *netdev,
4144
return 0;
4245
}
4346

47+
static int ngbe_set_ringparam(struct net_device *netdev,
48+
struct ethtool_ringparam *ring,
49+
struct kernel_ethtool_ringparam *kernel_ring,
50+
struct netlink_ext_ack *extack)
51+
{
52+
struct wx *wx = netdev_priv(netdev);
53+
u32 new_rx_count, new_tx_count;
54+
struct wx_ring *temp_ring;
55+
int i;
56+
57+
new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
58+
new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
59+
60+
new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD);
61+
new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE);
62+
63+
if (new_tx_count == wx->tx_ring_count &&
64+
new_rx_count == wx->rx_ring_count)
65+
return 0;
66+
67+
if (!netif_running(wx->netdev)) {
68+
for (i = 0; i < wx->num_tx_queues; i++)
69+
wx->tx_ring[i]->count = new_tx_count;
70+
for (i = 0; i < wx->num_rx_queues; i++)
71+
wx->rx_ring[i]->count = new_rx_count;
72+
wx->tx_ring_count = new_tx_count;
73+
wx->rx_ring_count = new_rx_count;
74+
75+
return 0;
76+
}
77+
78+
/* allocate temporary buffer to store rings in */
79+
i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
80+
temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
81+
if (!temp_ring)
82+
return -ENOMEM;
83+
84+
ngbe_down(wx);
85+
86+
wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring);
87+
kvfree(temp_ring);
88+
89+
wx_configure(wx);
90+
ngbe_up(wx);
91+
92+
return 0;
93+
}
94+
4495
static const struct ethtool_ops ngbe_ethtool_ops = {
4596
.get_drvinfo = wx_get_drvinfo,
4697
.get_link = ethtool_op_get_link,
@@ -56,6 +107,8 @@ static const struct ethtool_ops ngbe_ethtool_ops = {
56107
.get_pause_stats = wx_get_pause_stats,
57108
.get_pauseparam = wx_get_pauseparam,
58109
.set_pauseparam = wx_set_pauseparam,
110+
.get_ringparam = wx_get_ringparam,
111+
.set_ringparam = ngbe_set_ringparam,
59112
};
60113

61114
void ngbe_set_ethtool_ops(struct net_device *netdev)

drivers/net/ethernet/wangxun/ngbe/ngbe_main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,15 +334,15 @@ static void ngbe_disable_device(struct wx *wx)
334334
wx_update_stats(wx);
335335
}
336336

337-
static void ngbe_down(struct wx *wx)
337+
void ngbe_down(struct wx *wx)
338338
{
339339
phylink_stop(wx->phylink);
340340
ngbe_disable_device(wx);
341341
wx_clean_all_tx_rings(wx);
342342
wx_clean_all_rx_rings(wx);
343343
}
344344

345-
static void ngbe_up(struct wx *wx)
345+
void ngbe_up(struct wx *wx)
346346
{
347347
wx_configure_vectors(wx);
348348

drivers/net/ethernet/wangxun/ngbe/ngbe_type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,7 @@
130130

131131
extern char ngbe_driver_name[];
132132

133+
void ngbe_down(struct wx *wx);
134+
void ngbe_up(struct wx *wx);
135+
133136
#endif /* _NGBE_TYPE_H_ */

drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,57 @@
77

88
#include "../libwx/wx_ethtool.h"
99
#include "../libwx/wx_type.h"
10+
#include "../libwx/wx_lib.h"
1011
#include "txgbe_type.h"
1112
#include "txgbe_ethtool.h"
1213

14+
static int txgbe_set_ringparam(struct net_device *netdev,
15+
struct ethtool_ringparam *ring,
16+
struct kernel_ethtool_ringparam *kernel_ring,
17+
struct netlink_ext_ack *extack)
18+
{
19+
struct wx *wx = netdev_priv(netdev);
20+
u32 new_rx_count, new_tx_count;
21+
struct wx_ring *temp_ring;
22+
int i;
23+
24+
new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
25+
new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
26+
27+
new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD);
28+
new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE);
29+
30+
if (new_tx_count == wx->tx_ring_count &&
31+
new_rx_count == wx->rx_ring_count)
32+
return 0;
33+
34+
if (!netif_running(wx->netdev)) {
35+
for (i = 0; i < wx->num_tx_queues; i++)
36+
wx->tx_ring[i]->count = new_tx_count;
37+
for (i = 0; i < wx->num_rx_queues; i++)
38+
wx->rx_ring[i]->count = new_rx_count;
39+
wx->tx_ring_count = new_tx_count;
40+
wx->rx_ring_count = new_rx_count;
41+
42+
return 0;
43+
}
44+
45+
/* allocate temporary buffer to store rings in */
46+
i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
47+
temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
48+
if (!temp_ring)
49+
return -ENOMEM;
50+
51+
txgbe_down(wx);
52+
53+
wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring);
54+
kvfree(temp_ring);
55+
56+
txgbe_up(wx);
57+
58+
return 0;
59+
}
60+
1361
static const struct ethtool_ops txgbe_ethtool_ops = {
1462
.get_drvinfo = wx_get_drvinfo,
1563
.nway_reset = wx_nway_reset,
@@ -23,6 +71,8 @@ static const struct ethtool_ops txgbe_ethtool_ops = {
2371
.get_pause_stats = wx_get_pause_stats,
2472
.get_pauseparam = wx_get_pauseparam,
2573
.set_pauseparam = wx_set_pauseparam,
74+
.get_ringparam = wx_get_ringparam,
75+
.set_ringparam = txgbe_set_ringparam,
2676
};
2777

2878
void txgbe_set_ethtool_ops(struct net_device *netdev)

drivers/net/ethernet/wangxun/txgbe/txgbe_main.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static void txgbe_disable_device(struct wx *wx)
288288
wx_update_stats(wx);
289289
}
290290

291-
static void txgbe_down(struct wx *wx)
291+
void txgbe_down(struct wx *wx)
292292
{
293293
txgbe_disable_device(wx);
294294
txgbe_reset(wx);
@@ -298,6 +298,12 @@ static void txgbe_down(struct wx *wx)
298298
wx_clean_all_rx_rings(wx);
299299
}
300300

301+
void txgbe_up(struct wx *wx)
302+
{
303+
wx_configure(wx);
304+
txgbe_up_complete(wx);
305+
}
306+
301307
/**
302308
* txgbe_init_type_code - Initialize the shared code
303309
* @wx: pointer to hardware structure

0 commit comments

Comments
 (0)