diff options
-rw-r--r-- | drivers/net/igb/igb.h | 13 | ||||
-rw-r--r-- | drivers/net/igb/igb_ethtool.c | 16 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 19 |
3 files changed, 38 insertions, 10 deletions
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 154c5acc6fce..b2c98dea9eed 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h | |||
@@ -137,11 +137,17 @@ struct igb_buffer { | |||
137 | }; | 137 | }; |
138 | }; | 138 | }; |
139 | 139 | ||
140 | struct igb_queue_stats { | 140 | struct igb_tx_queue_stats { |
141 | u64 packets; | 141 | u64 packets; |
142 | u64 bytes; | 142 | u64 bytes; |
143 | }; | 143 | }; |
144 | 144 | ||
145 | struct igb_rx_queue_stats { | ||
146 | u64 packets; | ||
147 | u64 bytes; | ||
148 | u64 drops; | ||
149 | }; | ||
150 | |||
145 | struct igb_ring { | 151 | struct igb_ring { |
146 | struct igb_adapter *adapter; /* backlink */ | 152 | struct igb_adapter *adapter; /* backlink */ |
147 | void *desc; /* descriptor ring memory */ | 153 | void *desc; /* descriptor ring memory */ |
@@ -167,12 +173,13 @@ struct igb_ring { | |||
167 | union { | 173 | union { |
168 | /* TX */ | 174 | /* TX */ |
169 | struct { | 175 | struct { |
170 | struct igb_queue_stats tx_stats; | 176 | struct igb_tx_queue_stats tx_stats; |
171 | bool detect_tx_hung; | 177 | bool detect_tx_hung; |
172 | }; | 178 | }; |
173 | /* RX */ | 179 | /* RX */ |
174 | struct { | 180 | struct { |
175 | struct igb_queue_stats rx_stats; | 181 | struct igb_rx_queue_stats rx_stats; |
182 | u64 rx_queue_drops; | ||
176 | struct napi_struct napi; | 183 | struct napi_struct napi; |
177 | int set_itr; | 184 | int set_itr; |
178 | struct igb_ring *buddy; | 185 | struct igb_ring *buddy; |
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index b8551a57dd3f..2ae98f91372e 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
@@ -96,9 +96,10 @@ static const struct igb_stats igb_gstrings_stats[] = { | |||
96 | }; | 96 | }; |
97 | 97 | ||
98 | #define IGB_QUEUE_STATS_LEN \ | 98 | #define IGB_QUEUE_STATS_LEN \ |
99 | ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues + \ | 99 | (((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues)* \ |
100 | ((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \ | 100 | (sizeof(struct igb_rx_queue_stats) / sizeof(u64))) + \ |
101 | (sizeof(struct igb_queue_stats) / sizeof(u64))) | 101 | ((((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \ |
102 | (sizeof(struct igb_tx_queue_stats) / sizeof(u64)))) | ||
102 | #define IGB_GLOBAL_STATS_LEN \ | 103 | #define IGB_GLOBAL_STATS_LEN \ |
103 | sizeof(igb_gstrings_stats) / sizeof(struct igb_stats) | 104 | sizeof(igb_gstrings_stats) / sizeof(struct igb_stats) |
104 | #define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN) | 105 | #define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN) |
@@ -1960,7 +1961,8 @@ static void igb_get_ethtool_stats(struct net_device *netdev, | |||
1960 | { | 1961 | { |
1961 | struct igb_adapter *adapter = netdev_priv(netdev); | 1962 | struct igb_adapter *adapter = netdev_priv(netdev); |
1962 | u64 *queue_stat; | 1963 | u64 *queue_stat; |
1963 | int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64); | 1964 | int stat_count_tx = sizeof(struct igb_tx_queue_stats) / sizeof(u64); |
1965 | int stat_count_rx = sizeof(struct igb_rx_queue_stats) / sizeof(u64); | ||
1964 | int j; | 1966 | int j; |
1965 | int i; | 1967 | int i; |
1966 | 1968 | ||
@@ -1973,14 +1975,14 @@ static void igb_get_ethtool_stats(struct net_device *netdev, | |||
1973 | for (j = 0; j < adapter->num_tx_queues; j++) { | 1975 | for (j = 0; j < adapter->num_tx_queues; j++) { |
1974 | int k; | 1976 | int k; |
1975 | queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats; | 1977 | queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats; |
1976 | for (k = 0; k < stat_count; k++) | 1978 | for (k = 0; k < stat_count_tx; k++) |
1977 | data[i + k] = queue_stat[k]; | 1979 | data[i + k] = queue_stat[k]; |
1978 | i += k; | 1980 | i += k; |
1979 | } | 1981 | } |
1980 | for (j = 0; j < adapter->num_rx_queues; j++) { | 1982 | for (j = 0; j < adapter->num_rx_queues; j++) { |
1981 | int k; | 1983 | int k; |
1982 | queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats; | 1984 | queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats; |
1983 | for (k = 0; k < stat_count; k++) | 1985 | for (k = 0; k < stat_count_rx; k++) |
1984 | data[i + k] = queue_stat[k]; | 1986 | data[i + k] = queue_stat[k]; |
1985 | i += k; | 1987 | i += k; |
1986 | } | 1988 | } |
@@ -2014,6 +2016,8 @@ static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | |||
2014 | p += ETH_GSTRING_LEN; | 2016 | p += ETH_GSTRING_LEN; |
2015 | sprintf(p, "rx_queue_%u_bytes", i); | 2017 | sprintf(p, "rx_queue_%u_bytes", i); |
2016 | p += ETH_GSTRING_LEN; | 2018 | p += ETH_GSTRING_LEN; |
2019 | sprintf(p, "rx_queue_%u_drops", i); | ||
2020 | p += ETH_GSTRING_LEN; | ||
2017 | } | 2021 | } |
2018 | /* BUG_ON(p - data != IGB_STATS_LEN * ETH_GSTRING_LEN); */ | 2022 | /* BUG_ON(p - data != IGB_STATS_LEN * ETH_GSTRING_LEN); */ |
2019 | break; | 2023 | break; |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 2ec98091948b..4ae81331dca5 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -3588,8 +3588,25 @@ void igb_update_stats(struct igb_adapter *adapter) | |||
3588 | 3588 | ||
3589 | /* Rx Errors */ | 3589 | /* Rx Errors */ |
3590 | 3590 | ||
3591 | if (hw->mac.type != e1000_82575) { | ||
3592 | u32 rqdpc_tmp; | ||
3593 | int i; | ||
3594 | /* Read out drops stats per RX queue. Notice RQDPC (Receive | ||
3595 | * Queue Drop Packet Count) stats only gets incremented, if | ||
3596 | * the DROP_EN but it set (in the SRRCTL register for that | ||
3597 | * queue). If DROP_EN bit is NOT set, then the some what | ||
3598 | * equivalent count is stored in RNBC (not per queue basis). | ||
3599 | * Also note the drop count is due to lack of available | ||
3600 | * descriptors. | ||
3601 | */ | ||
3602 | for (i = 0; i < adapter->num_rx_queues; i++) { | ||
3603 | rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0xFFF; | ||
3604 | adapter->rx_ring[i].rx_stats.drops += rqdpc_tmp; | ||
3605 | } | ||
3606 | } | ||
3607 | |||
3591 | /* RLEC on some newer hardware can be incorrect so build | 3608 | /* RLEC on some newer hardware can be incorrect so build |
3592 | * our own version based on RUC and ROC */ | 3609 | * our own version based on RUC and ROC */ |
3593 | adapter->net_stats.rx_errors = adapter->stats.rxerrc + | 3610 | adapter->net_stats.rx_errors = adapter->stats.rxerrc + |
3594 | adapter->stats.crcerrs + adapter->stats.algnerrc + | 3611 | adapter->stats.crcerrs + adapter->stats.algnerrc + |
3595 | adapter->stats.ruc + adapter->stats.roc + | 3612 | adapter->stats.ruc + adapter->stats.roc + |