Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <davem@davemloft.net>

+137 -14
+2
drivers/net/ethernet/wangxun/libwx/wx_hw.c
··· 1958 1958 return -ENOMEM; 1959 1959 } 1960 1960 1961 + bitmap_zero(wx->state, WX_STATE_NBITS); 1962 + 1961 1963 return 0; 1962 1964 } 1963 1965 EXPORT_SYMBOL(wx_sw_init);
+52 -4
drivers/net/ethernet/wangxun/libwx/wx_lib.c
··· 2690 2690 wx->rss_enabled = false; 2691 2691 } 2692 2692 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)) 2696 2698 wx_set_rx_mode(netdev); 2697 2699 2698 - return 1; 2700 + return 0; 2699 2701 } 2700 2702 EXPORT_SYMBOL(wx_set_features); 2703 + 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); 2701 2749 2702 2750 void wx_set_ring(struct wx *wx, u32 new_tx_count, 2703 2751 u32 new_rx_count, struct wx_ring *temp_ring)
+2
drivers/net/ethernet/wangxun/libwx/wx_lib.h
··· 30 30 void wx_get_stats64(struct net_device *netdev, 31 31 struct rtnl_link_stats64 *stats); 32 32 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); 33 35 void wx_set_ring(struct wx *wx, u32 new_tx_count, 34 36 u32 new_rx_count, struct wx_ring *temp_ring); 35 37
+22
drivers/net/ethernet/wangxun/libwx/wx_type.h
··· 982 982 u64 qmprc; 983 983 }; 984 984 985 + enum wx_state { 986 + WX_STATE_RESETTING, 987 + WX_STATE_NBITS, /* must be last */ 988 + }; 985 989 struct wx { 986 990 unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 991 + DECLARE_BITMAP(state, WX_STATE_NBITS); 987 992 988 993 void *priv; 989 994 u8 __iomem *hw_addr; ··· 1076 1071 u64 hw_csum_rx_good; 1077 1072 u64 hw_csum_rx_error; 1078 1073 u64 alloc_rx_buff_failed; 1074 + 1075 + void (*do_reset)(struct net_device *netdev); 1079 1076 }; 1080 1077 1081 1078 #define WX_INTR_ALL (~0ULL) ··· 1136 1129 static inline struct wx *phylink_to_wx(struct phylink_config *config) 1137 1130 { 1138 1131 return container_of(config, struct wx, phylink_config); 1132 + } 1133 + 1134 + static inline int wx_set_state_reset(struct wx *wx) 1135 + { 1136 + u8 timeout = 50; 1137 + 1138 + while (test_and_set_bit(WX_STATE_RESETTING, wx->state)) { 1139 + timeout--; 1140 + if (!timeout) 1141 + return -EBUSY; 1142 + 1143 + usleep_range(1000, 2000); 1144 + } 1145 + 1146 + return 0; 1139 1147 } 1140 1148 1141 1149 #endif /* _WX_TYPE_H_ */
+13 -5
drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
··· 52 52 struct wx *wx = netdev_priv(netdev); 53 53 u32 new_rx_count, new_tx_count; 54 54 struct wx_ring *temp_ring; 55 - int i; 55 + int i, err = 0; 56 56 57 57 new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD); 58 58 new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE); ··· 64 64 new_rx_count == wx->rx_ring_count) 65 65 return 0; 66 66 67 + err = wx_set_state_reset(wx); 68 + if (err) 69 + return err; 70 + 67 71 if (!netif_running(wx->netdev)) { 68 72 for (i = 0; i < wx->num_tx_queues; i++) 69 73 wx->tx_ring[i]->count = new_tx_count; ··· 76 72 wx->tx_ring_count = new_tx_count; 77 73 wx->rx_ring_count = new_rx_count; 78 74 79 - return 0; 75 + goto clear_reset; 80 76 } 81 77 82 78 /* allocate temporary buffer to store rings in */ 83 79 i = max_t(int, wx->num_tx_queues, wx->num_rx_queues); 84 80 temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL); 85 - if (!temp_ring) 86 - return -ENOMEM; 81 + if (!temp_ring) { 82 + err = -ENOMEM; 83 + goto clear_reset; 84 + } 87 85 88 86 ngbe_down(wx); 89 87 ··· 95 89 wx_configure(wx); 96 90 ngbe_up(wx); 97 91 98 - return 0; 92 + clear_reset: 93 + clear_bit(WX_STATE_RESETTING, wx->state); 94 + return err; 99 95 } 100 96 101 97 static int ngbe_set_channels(struct net_device *dev,
+1
drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
··· 499 499 .ndo_start_xmit = wx_xmit_frame, 500 500 .ndo_set_rx_mode = wx_set_rx_mode, 501 501 .ndo_set_features = wx_set_features, 502 + .ndo_fix_features = wx_fix_features, 502 503 .ndo_validate_addr = eth_validate_addr, 503 504 .ndo_set_mac_address = wx_set_mac, 504 505 .ndo_get_stats64 = wx_get_stats64,
+13 -5
drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
··· 19 19 struct wx *wx = netdev_priv(netdev); 20 20 u32 new_rx_count, new_tx_count; 21 21 struct wx_ring *temp_ring; 22 - int i; 22 + int i, err = 0; 23 23 24 24 new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD); 25 25 new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE); ··· 31 31 new_rx_count == wx->rx_ring_count) 32 32 return 0; 33 33 34 + err = wx_set_state_reset(wx); 35 + if (err) 36 + return err; 37 + 34 38 if (!netif_running(wx->netdev)) { 35 39 for (i = 0; i < wx->num_tx_queues; i++) 36 40 wx->tx_ring[i]->count = new_tx_count; ··· 43 39 wx->tx_ring_count = new_tx_count; 44 40 wx->rx_ring_count = new_rx_count; 45 41 46 - return 0; 42 + goto clear_reset; 47 43 } 48 44 49 45 /* allocate temporary buffer to store rings in */ 50 46 i = max_t(int, wx->num_tx_queues, wx->num_rx_queues); 51 47 temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL); 52 - if (!temp_ring) 53 - return -ENOMEM; 48 + if (!temp_ring) { 49 + err = -ENOMEM; 50 + goto clear_reset; 51 + } 54 52 55 53 txgbe_down(wx); 56 54 ··· 61 55 62 56 txgbe_up(wx); 63 57 64 - return 0; 58 + clear_reset: 59 + clear_bit(WX_STATE_RESETTING, wx->state); 60 + return err; 65 61 } 66 62 67 63 static int txgbe_set_channels(struct net_device *dev,
+31
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
··· 269 269 wx->tx_work_limit = TXGBE_DEFAULT_TX_WORK; 270 270 wx->rx_work_limit = TXGBE_DEFAULT_RX_WORK; 271 271 272 + wx->do_reset = txgbe_do_reset; 273 + 272 274 return 0; 273 275 } 274 276 ··· 423 421 return 0; 424 422 } 425 423 424 + static void txgbe_reinit_locked(struct wx *wx) 425 + { 426 + int err = 0; 427 + 428 + netif_trans_update(wx->netdev); 429 + 430 + err = wx_set_state_reset(wx); 431 + if (err) { 432 + wx_err(wx, "wait device reset timeout\n"); 433 + return; 434 + } 435 + 436 + txgbe_down(wx); 437 + txgbe_up(wx); 438 + 439 + clear_bit(WX_STATE_RESETTING, wx->state); 440 + } 441 + 442 + void txgbe_do_reset(struct net_device *netdev) 443 + { 444 + struct wx *wx = netdev_priv(netdev); 445 + 446 + if (netif_running(netdev)) 447 + txgbe_reinit_locked(wx); 448 + else 449 + txgbe_reset(wx); 450 + } 451 + 426 452 static const struct net_device_ops txgbe_netdev_ops = { 427 453 .ndo_open = txgbe_open, 428 454 .ndo_stop = txgbe_close, ··· 458 428 .ndo_start_xmit = wx_xmit_frame, 459 429 .ndo_set_rx_mode = wx_set_rx_mode, 460 430 .ndo_set_features = wx_set_features, 431 + .ndo_fix_features = wx_fix_features, 461 432 .ndo_validate_addr = eth_validate_addr, 462 433 .ndo_set_mac_address = wx_set_mac, 463 434 .ndo_get_stats64 = wx_get_stats64,
+1
drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
··· 134 134 void txgbe_down(struct wx *wx); 135 135 void txgbe_up(struct wx *wx); 136 136 int txgbe_setup_tc(struct net_device *dev, u8 tc); 137 + void txgbe_do_reset(struct net_device *netdev); 137 138 138 139 #define NODE_PROP(_NAME, _PROP) \ 139 140 (const struct software_node) { \