aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Daniel Kachhap <amit.kachhap@arm.com>2018-07-10 15:33:43 +0530
committerAmit Daniel Kachhap <amit.kachhap@arm.com>2018-07-10 15:33:43 +0530
commitd6a94052f8e4e6086facd579f20776b2348be2ec (patch)
tree9548bed9276a21c49761907833ba5d31c9769f50
parent4a81eaddc3190be263cb623f5c142e08efe69a90 (diff)
parentacb260838f627dafd172ff412253326acd24c175 (diff)
Merge branch 'latest-armlt-misc' into latest-armlt
-rw-r--r--drivers/net/ethernet/marvell/sky2.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 697d9b374f5e..77012649cb4e 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -3909,6 +3909,18 @@ static void sky2_get_stats(struct net_device *dev,
unsigned int start;
u64 _bytes, _packets;
+ /* Try and check if device if off. If it is, abort gathering stats as
+ * any attempt to read hardware registers will generate a bus fault.
+ * This test is hacky and racy as there's nothing stopping the device
+ * being powered off immediately after the test.
+ */
+ if (hw->pdev->pm_cap) {
+ u16 pmcsr;
+ int ret = pci_read_config_word(hw->pdev, hw->pdev->pm_cap + PCI_PM_CTRL, &pmcsr);
+ if (ret || (pmcsr & PCI_PM_CTRL_STATE_MASK) > PCI_D2)
+ return; /* Can't read power state or it's state D3 (off) */
+ }
+
do {
start = u64_stats_fetch_begin_irq(&sky2->rx_stats.syncp);
_bytes = sky2->rx_stats.bytes;