diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-10-11 19:47:22 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-11 22:17:17 -0700 |
commit | 295b54c4902c52cd00d7c837d50a86e39e26caec (patch) | |
tree | 53eda6f30c1e0f655da536e6217f6957ae0d2357 /drivers/net | |
parent | e86908614f2c7fec401827e5cefd7a6ea9407f85 (diff) | |
download | op-kernel-dev-295b54c4902c52cd00d7c837d50a86e39e26caec.zip op-kernel-dev-295b54c4902c52cd00d7c837d50a86e39e26caec.tar.gz |
[SKY2]: ethtool register reserved area blackout
Make sure and not dump reserved areas of device space.
Touching some of these causes machine check exceptions on boards
like D-Link DGE-550SX.
Coding note, used a complex switch statement rather than bitmap
because it is easier to relate the block values to the documentation
rather than looking at a encoded bitmask.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sky2.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 0a32034..4832f64 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3569,20 +3569,64 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, { const struct sky2_port *sky2 = netdev_priv(dev); const void __iomem *io = sky2->hw->regs; + unsigned int b; regs->version = 1; - memset(p, 0, regs->len); - memcpy_fromio(p, io, B3_RAM_ADDR); - - /* skip diagnostic ram region */ - memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, 0x2000 - B3_RI_WTO_R1); + for (b = 0; b < 128; b++) { + /* This complicated switch statement is to make sure and + * only access regions that are unreserved. + * Some blocks are only valid on dual port cards. + * and block 3 has some special diagnostic registers that + * are poison. + */ + switch (b) { + case 3: + /* skip diagnostic ram region */ + memcpy_fromio(p + 0x10, io + 0x10, 128 - 0x10); + break; - /* copy GMAC registers */ - memcpy_fromio(p + BASE_GMAC_1, io + BASE_GMAC_1, 0x1000); - if (sky2->hw->ports > 1) - memcpy_fromio(p + BASE_GMAC_2, io + BASE_GMAC_2, 0x1000); + /* dual port cards only */ + case 5: /* Tx Arbiter 2 */ + case 9: /* RX2 */ + case 14 ... 15: /* TX2 */ + case 17: case 19: /* Ram Buffer 2 */ + case 22 ... 23: /* Tx Ram Buffer 2 */ + case 25: /* Rx MAC Fifo 1 */ + case 27: /* Tx MAC Fifo 2 */ + case 31: /* GPHY 2 */ + case 40 ... 47: /* Pattern Ram 2 */ + case 52: case 54: /* TCP Segmentation 2 */ + case 112 ... 116: /* GMAC 2 */ + if (sky2->hw->ports == 1) + goto reserved; + /* fall through */ + case 0: /* Control */ + case 2: /* Mac address */ + case 4: /* Tx Arbiter 1 */ + case 7: /* PCI express reg */ + case 8: /* RX1 */ + case 12 ... 13: /* TX1 */ + case 16: case 18:/* Rx Ram Buffer 1 */ + case 20 ... 21: /* Tx Ram Buffer 1 */ + case 24: /* Rx MAC Fifo 1 */ + case 26: /* Tx MAC Fifo 1 */ + case 28 ... 29: /* Descriptor and status unit */ + case 30: /* GPHY 1*/ + case 32 ... 39: /* Pattern Ram 1 */ + case 48: case 50: /* TCP Segmentation 1 */ + case 56 ... 60: /* PCI space */ + case 80 ... 84: /* GMAC 1 */ + memcpy_fromio(p, io, 128); + break; + default: +reserved: + memset(p, 0, 128); + } + p += 128; + io += 128; + } } /* In order to do Jumbo packets on these chips, need to turn off the |