Skip to content

Commit f6f25ee

Browse files
committedMay 17, 2024
Merge branch 'wangxun-fixes'
Jiawen Wu says: ==================== Wangxun fixes Fixed some bugs when using ethtool to operate network devices. v4 -> v5: - Simplify if...else... to fix features. v3 -> v4: - Require both ctag and stag to be enabled or disabled. v2 -> v3: - Drop the first patch. v1 -> v2: - Factor out the same code. - Remove statistics printing with more than 64 queues. - Detail the commit logs to describe issues. - Remove reset flag check in wx_update_stats(). - Change to set VLAN CTAG and STAG to be consistent. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 581073f + 1d3c641 commit f6f25ee

File tree

9 files changed

+137
-14
lines changed

9 files changed

+137
-14
lines changed
 

‎drivers/net/ethernet/wangxun/libwx/wx_hw.c

+2
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,8 @@ int wx_sw_init(struct wx *wx)
19581958
return -ENOMEM;
19591959
}
19601960

1961+
bitmap_zero(wx->state, WX_STATE_NBITS);
1962+
19611963
return 0;
19621964
}
19631965
EXPORT_SYMBOL(wx_sw_init);

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

+52-4
Original file line numberDiff line numberDiff line change
@@ -2690,15 +2690,63 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
26902690
wx->rss_enabled = false;
26912691
}
26922692

2693-
if (changed &
2694-
(NETIF_F_HW_VLAN_CTAG_RX |
2695-
NETIF_F_HW_VLAN_STAG_RX))
2693+
netdev->features = features;
2694+
2695+
if (wx->mac.type == wx_mac_sp && changed & NETIF_F_HW_VLAN_CTAG_RX)
2696+
wx->do_reset(netdev);
2697+
else if (changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER))
26962698
wx_set_rx_mode(netdev);
26972699

2698-
return 1;
2700+
return 0;
26992701
}
27002702
EXPORT_SYMBOL(wx_set_features);
27012703

2704+
#define NETIF_VLAN_STRIPPING_FEATURES (NETIF_F_HW_VLAN_CTAG_RX | \
2705+
NETIF_F_HW_VLAN_STAG_RX)
2706+
2707+
#define NETIF_VLAN_INSERTION_FEATURES (NETIF_F_HW_VLAN_CTAG_TX | \
2708+
NETIF_F_HW_VLAN_STAG_TX)
2709+
2710+
#define NETIF_VLAN_FILTERING_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \
2711+
NETIF_F_HW_VLAN_STAG_FILTER)
2712+
2713+
netdev_features_t wx_fix_features(struct net_device *netdev,
2714+
netdev_features_t features)
2715+
{
2716+
netdev_features_t changed = netdev->features ^ features;
2717+
struct wx *wx = netdev_priv(netdev);
2718+
2719+
if (changed & NETIF_VLAN_STRIPPING_FEATURES) {
2720+
if ((features & NETIF_VLAN_STRIPPING_FEATURES) != NETIF_VLAN_STRIPPING_FEATURES &&
2721+
(features & NETIF_VLAN_STRIPPING_FEATURES) != 0) {
2722+
features &= ~NETIF_VLAN_STRIPPING_FEATURES;
2723+
features |= netdev->features & NETIF_VLAN_STRIPPING_FEATURES;
2724+
wx_err(wx, "802.1Q and 802.1ad VLAN stripping must be either both on or both off.");
2725+
}
2726+
}
2727+
2728+
if (changed & NETIF_VLAN_INSERTION_FEATURES) {
2729+
if ((features & NETIF_VLAN_INSERTION_FEATURES) != NETIF_VLAN_INSERTION_FEATURES &&
2730+
(features & NETIF_VLAN_INSERTION_FEATURES) != 0) {
2731+
features &= ~NETIF_VLAN_INSERTION_FEATURES;
2732+
features |= netdev->features & NETIF_VLAN_INSERTION_FEATURES;
2733+
wx_err(wx, "802.1Q and 802.1ad VLAN insertion must be either both on or both off.");
2734+
}
2735+
}
2736+
2737+
if (changed & NETIF_VLAN_FILTERING_FEATURES) {
2738+
if ((features & NETIF_VLAN_FILTERING_FEATURES) != NETIF_VLAN_FILTERING_FEATURES &&
2739+
(features & NETIF_VLAN_FILTERING_FEATURES) != 0) {
2740+
features &= ~NETIF_VLAN_FILTERING_FEATURES;
2741+
features |= netdev->features & NETIF_VLAN_FILTERING_FEATURES;
2742+
wx_err(wx, "802.1Q and 802.1ad VLAN filtering must be either both on or both off.");
2743+
}
2744+
}
2745+
2746+
return features;
2747+
}
2748+
EXPORT_SYMBOL(wx_fix_features);
2749+
27022750
void wx_set_ring(struct wx *wx, u32 new_tx_count,
27032751
u32 new_rx_count, struct wx_ring *temp_ring)
27042752
{

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

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ int wx_setup_resources(struct wx *wx);
3030
void wx_get_stats64(struct net_device *netdev,
3131
struct rtnl_link_stats64 *stats);
3232
int wx_set_features(struct net_device *netdev, netdev_features_t features);
33+
netdev_features_t wx_fix_features(struct net_device *netdev,
34+
netdev_features_t features);
3335
void wx_set_ring(struct wx *wx, u32 new_tx_count,
3436
u32 new_rx_count, struct wx_ring *temp_ring);
3537

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

+22
Original file line numberDiff line numberDiff line change
@@ -982,8 +982,13 @@ struct wx_hw_stats {
982982
u64 qmprc;
983983
};
984984

985+
enum wx_state {
986+
WX_STATE_RESETTING,
987+
WX_STATE_NBITS, /* must be last */
988+
};
985989
struct wx {
986990
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
991+
DECLARE_BITMAP(state, WX_STATE_NBITS);
987992

988993
void *priv;
989994
u8 __iomem *hw_addr;
@@ -1071,6 +1076,8 @@ struct wx {
10711076
u64 hw_csum_rx_good;
10721077
u64 hw_csum_rx_error;
10731078
u64 alloc_rx_buff_failed;
1079+
1080+
void (*do_reset)(struct net_device *netdev);
10741081
};
10751082

10761083
#define WX_INTR_ALL (~0ULL)
@@ -1131,4 +1138,19 @@ static inline struct wx *phylink_to_wx(struct phylink_config *config)
11311138
return container_of(config, struct wx, phylink_config);
11321139
}
11331140

1141+
static inline int wx_set_state_reset(struct wx *wx)
1142+
{
1143+
u8 timeout = 50;
1144+
1145+
while (test_and_set_bit(WX_STATE_RESETTING, wx->state)) {
1146+
timeout--;
1147+
if (!timeout)
1148+
return -EBUSY;
1149+
1150+
usleep_range(1000, 2000);
1151+
}
1152+
1153+
return 0;
1154+
}
1155+
11341156
#endif /* _WX_TYPE_H_ */

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

+13-5
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ static int ngbe_set_ringparam(struct net_device *netdev,
5252
struct wx *wx = netdev_priv(netdev);
5353
u32 new_rx_count, new_tx_count;
5454
struct wx_ring *temp_ring;
55-
int i;
55+
int i, err = 0;
5656

5757
new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
5858
new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
@@ -64,6 +64,10 @@ static int ngbe_set_ringparam(struct net_device *netdev,
6464
new_rx_count == wx->rx_ring_count)
6565
return 0;
6666

67+
err = wx_set_state_reset(wx);
68+
if (err)
69+
return err;
70+
6771
if (!netif_running(wx->netdev)) {
6872
for (i = 0; i < wx->num_tx_queues; i++)
6973
wx->tx_ring[i]->count = new_tx_count;
@@ -72,14 +76,16 @@ static int ngbe_set_ringparam(struct net_device *netdev,
7276
wx->tx_ring_count = new_tx_count;
7377
wx->rx_ring_count = new_rx_count;
7478

75-
return 0;
79+
goto clear_reset;
7680
}
7781

7882
/* allocate temporary buffer to store rings in */
7983
i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
8084
temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
81-
if (!temp_ring)
82-
return -ENOMEM;
85+
if (!temp_ring) {
86+
err = -ENOMEM;
87+
goto clear_reset;
88+
}
8389

8490
ngbe_down(wx);
8591

@@ -89,7 +95,9 @@ static int ngbe_set_ringparam(struct net_device *netdev,
8995
wx_configure(wx);
9096
ngbe_up(wx);
9197

92-
return 0;
98+
clear_reset:
99+
clear_bit(WX_STATE_RESETTING, wx->state);
100+
return err;
93101
}
94102

95103
static int ngbe_set_channels(struct net_device *dev,

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

+1
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ static const struct net_device_ops ngbe_netdev_ops = {
499499
.ndo_start_xmit = wx_xmit_frame,
500500
.ndo_set_rx_mode = wx_set_rx_mode,
501501
.ndo_set_features = wx_set_features,
502+
.ndo_fix_features = wx_fix_features,
502503
.ndo_validate_addr = eth_validate_addr,
503504
.ndo_set_mac_address = wx_set_mac,
504505
.ndo_get_stats64 = wx_get_stats64,

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

+13-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ static int txgbe_set_ringparam(struct net_device *netdev,
1919
struct wx *wx = netdev_priv(netdev);
2020
u32 new_rx_count, new_tx_count;
2121
struct wx_ring *temp_ring;
22-
int i;
22+
int i, err = 0;
2323

2424
new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
2525
new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
@@ -31,6 +31,10 @@ static int txgbe_set_ringparam(struct net_device *netdev,
3131
new_rx_count == wx->rx_ring_count)
3232
return 0;
3333

34+
err = wx_set_state_reset(wx);
35+
if (err)
36+
return err;
37+
3438
if (!netif_running(wx->netdev)) {
3539
for (i = 0; i < wx->num_tx_queues; i++)
3640
wx->tx_ring[i]->count = new_tx_count;
@@ -39,14 +43,16 @@ static int txgbe_set_ringparam(struct net_device *netdev,
3943
wx->tx_ring_count = new_tx_count;
4044
wx->rx_ring_count = new_rx_count;
4145

42-
return 0;
46+
goto clear_reset;
4347
}
4448

4549
/* allocate temporary buffer to store rings in */
4650
i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
4751
temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
48-
if (!temp_ring)
49-
return -ENOMEM;
52+
if (!temp_ring) {
53+
err = -ENOMEM;
54+
goto clear_reset;
55+
}
5056

5157
txgbe_down(wx);
5258

@@ -55,7 +61,9 @@ static int txgbe_set_ringparam(struct net_device *netdev,
5561

5662
txgbe_up(wx);
5763

58-
return 0;
64+
clear_reset:
65+
clear_bit(WX_STATE_RESETTING, wx->state);
66+
return err;
5967
}
6068

6169
static int txgbe_set_channels(struct net_device *dev,

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

+31
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ static int txgbe_sw_init(struct wx *wx)
269269
wx->tx_work_limit = TXGBE_DEFAULT_TX_WORK;
270270
wx->rx_work_limit = TXGBE_DEFAULT_RX_WORK;
271271

272+
wx->do_reset = txgbe_do_reset;
273+
272274
return 0;
273275
}
274276

@@ -421,13 +423,42 @@ int txgbe_setup_tc(struct net_device *dev, u8 tc)
421423
return 0;
422424
}
423425

426+
static void txgbe_reinit_locked(struct wx *wx)
427+
{
428+
int err = 0;
429+
430+
netif_trans_update(wx->netdev);
431+
432+
err = wx_set_state_reset(wx);
433+
if (err) {
434+
wx_err(wx, "wait device reset timeout\n");
435+
return;
436+
}
437+
438+
txgbe_down(wx);
439+
txgbe_up(wx);
440+
441+
clear_bit(WX_STATE_RESETTING, wx->state);
442+
}
443+
444+
void txgbe_do_reset(struct net_device *netdev)
445+
{
446+
struct wx *wx = netdev_priv(netdev);
447+
448+
if (netif_running(netdev))
449+
txgbe_reinit_locked(wx);
450+
else
451+
txgbe_reset(wx);
452+
}
453+
424454
static const struct net_device_ops txgbe_netdev_ops = {
425455
.ndo_open = txgbe_open,
426456
.ndo_stop = txgbe_close,
427457
.ndo_change_mtu = wx_change_mtu,
428458
.ndo_start_xmit = wx_xmit_frame,
429459
.ndo_set_rx_mode = wx_set_rx_mode,
430460
.ndo_set_features = wx_set_features,
461+
.ndo_fix_features = wx_fix_features,
431462
.ndo_validate_addr = eth_validate_addr,
432463
.ndo_set_mac_address = wx_set_mac,
433464
.ndo_get_stats64 = wx_get_stats64,

‎drivers/net/ethernet/wangxun/txgbe/txgbe_type.h

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ extern char txgbe_driver_name[];
134134
void txgbe_down(struct wx *wx);
135135
void txgbe_up(struct wx *wx);
136136
int txgbe_setup_tc(struct net_device *dev, u8 tc);
137+
void txgbe_do_reset(struct net_device *netdev);
137138

138139
#define NODE_PROP(_NAME, _PROP) \
139140
(const struct software_node) { \

0 commit comments

Comments
 (0)
Please sign in to comment.