aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJesper Dangaard Brouer <hawk@comx.dk>2009-05-26 09:50:31 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-26 23:35:05 -0400
commit8c0ab70ab9cc849af59ef6592bd652a938b21c79 (patch)
treef7be759f12ba98ea679ba8c7b161f17eaba7fdeb /drivers/net
parent3c514ce2f9ae20c06fb17c7ccff40cad1516cc41 (diff)
igb: Implement reading of reg RQDPC (Receive Queue Drop Packet Count)
Based on the previous patches from Jesper Dangaard Brouer <hawk@comx.dk> Implement reading the per queue drop stats register RQDPC (Receive Queue Drop Packet Count). It counts the number of packets dropped by a queue due to lack of descriptors available. Notice RQDPC (Receive Queue Drop Packet Count) stats only gets incremented, if the DROP_EN bit it set (in the SRRCTL register for that queue). If DROP_EN bit is NOT set, then the some what equivalent count is stored in RNBC (not per queue basis). The RQDPC register is only 12 bit, thus the precision might suffer due to overrun in-netween the watchdog polling interval. Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> CC: Jesper Dangaard Brouer <hawk@comx.dk> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/igb/igb.h13
-rw-r--r--drivers/net/igb/igb_ethtool.c16
-rw-r--r--drivers/net/igb/igb_main.c19
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
140struct igb_queue_stats { 140struct igb_tx_queue_stats {
141 u64 packets; 141 u64 packets;
142 u64 bytes; 142 u64 bytes;
143}; 143};
144 144
145struct igb_rx_queue_stats {
146 u64 packets;
147 u64 bytes;
148 u64 drops;
149};
150
145struct igb_ring { 151struct 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 +