aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/files
diff options
context:
space:
mode:
authorJonas Gorski <jogo@openwrt.org>2015-02-27 17:40:17 +0000
committerJonas Gorski <jogo@openwrt.org>2015-02-27 17:40:17 +0000
commitaa4d5abef003bad1eea90560ab8a5d507a349de0 (patch)
treea5593f9bedc20d4b71279f3e1babbba599f83e16 /target/linux/generic/files
parentc5696515d1ae7d88c59291367198ed3a73d5de59 (diff)
downloadmaster-187ad058-aa4d5abef003bad1eea90560ab8a5d507a349de0.tar.gz
master-187ad058-aa4d5abef003bad1eea90560ab8a5d507a349de0.tar.bz2
master-187ad058-aa4d5abef003bad1eea90560ab8a5d507a349de0.zip
b53: fix mmap register read/writes > 32 bit
For bcm63xx integrated switches, broadcom changed the data endianess to match the system endianess. But this only applies to within one word, which causes 48/64 bit values to be still split into their "litte endian" groups. E.g. 48 bit values (with 5 being the most significant byte) aligned 0x00 ..01 or 0123 0x04 2345 45.. will become 0x00 ..10 resp. 3210 0x04 5432 54.. Likewise for 64 bit values. Signed-off-by: Jonas Gorski <jogo@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@44568 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic/files')
-rw-r--r--target/linux/generic/files/drivers/net/phy/b53/b53_mmap.c70
1 files changed, 36 insertions, 34 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_mmap.c b/target/linux/generic/files/drivers/net/phy/b53/b53_mmap.c
index 272360f6de..b8681660cc 100644
--- a/target/linux/generic/files/drivers/net/phy/b53/b53_mmap.c
+++ b/target/linux/generic/files/drivers/net/phy/b53/b53_mmap.c
@@ -64,19 +64,25 @@ static int b53_mmap_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val)
static int b53_mmap_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val)
{
- u8 __iomem *regs = dev->priv;
-
- if (WARN_ON(reg % 4))
+ if (WARN_ON(reg % 2))
return -EINVAL;
- if (dev->pdata && dev->pdata->big_endian) {
- *val = readl_be(regs + (page << 8) + reg);
- *val <<= 16;
- *val |= readw_be(regs + (page << 8) + reg + 4);
+ if (reg % 4) {
+ u16 lo;
+ u32 hi;
+
+ b53_mmap_read16(dev, page, reg, &lo);
+ b53_mmap_read32(dev, page, reg + 2, &hi);
+
+ *val = ((u64)hi << 16) | lo;
} else {
- *val |= readw(regs + (page << 8) + reg + 4);
- *val <<= 32;
- *val = readl(regs + (page << 8) + reg);
+ u32 lo;
+ u16 hi;
+
+ b53_mmap_read32(dev, page, reg, &lo);
+ b53_mmap_read16(dev, page, reg + 4, &hi);
+
+ *val = ((u64)hi << 32) | lo;
}
return 0;
@@ -84,19 +90,13 @@ static int b53_mmap_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val)
static int b53_mmap_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val)
{
- u8 __iomem *regs = dev->priv;
u32 hi, lo;
if (WARN_ON(reg % 4))
return -EINVAL;
- if (dev->pdata && dev->pdata->big_endian) {
- lo = readl_be(regs + (page << 8) + reg);
- hi = readl_be(regs + (page << 8) + reg + 4);
- } else {
- lo = readl(regs + (page << 8) + reg);
- hi = readl(regs + (page << 8) + reg + 4);
- }
+ b53_mmap_read32(dev, page, reg, &lo);
+ b53_mmap_read32(dev, page, reg + 4, &hi);
*val = ((u64)hi << 32) | lo;
@@ -147,17 +147,21 @@ static int b53_mmap_write32(struct b53_device *dev, u8 page, u8 reg,
static int b53_mmap_write48(struct b53_device *dev, u8 page, u8 reg,
u64 value)
{
- u8 __iomem *regs = dev->priv;
-
- if (WARN_ON(reg % 4))
+ if (WARN_ON(reg % 2))
return -EINVAL;
- if (dev->pdata && dev->pdata->big_endian) {
- writel_be((u32)(value >> 16), regs + (page << 8) + reg);
- writew_be((u16)value, regs + (page << 8) + reg + 4);
+ if (reg % 4) {
+ u32 hi = (u32)(value >> 16);
+ u16 lo = (u16)value;
+
+ b53_mmap_write16(dev, page, reg, lo);
+ b53_mmap_write32(dev, page, reg + 2, hi);
} else {
- writel((u32)value, regs + (page << 8) + reg);
- writew((u16)(value >> 32), regs + (page << 8) + reg + 4);
+ u16 hi = (u16)(value >> 32);
+ u32 lo = (u32)value;
+
+ b53_mmap_write32(dev, page, reg, lo);
+ b53_mmap_write16(dev, page, reg + 4, hi);
}
return 0;
@@ -166,18 +170,16 @@ static int b53_mmap_write48(struct b53_device *dev, u8 page, u8 reg,
static int b53_mmap_write64(struct b53_device *dev, u8 page, u8 reg,
u64 value)
{
- u8 __iomem *regs = dev->priv;
+ u32 hi, lo;
+
+ hi = (u32)(value >> 32);
+ lo = (u32)value;
if (WARN_ON(reg % 4))
return -EINVAL;
- if (dev->pdata && dev->pdata->big_endian) {
- writel_be((u32)(value >> 32), regs + (page << 8) + reg);
- writel_be((u32)value, regs + (page << 8) + reg + 4);
- } else {
- writel((u32)value, regs + (page << 8) + reg);
- writel((u32)(value >> 32), regs + (page << 8) + reg + 4);
- }
+ b53_mmap_write32(dev, page, reg, lo);
+ b53_mmap_write32(dev, page, reg + 4, hi);
return 0;
}