Message ID | 1376730263-9352-1-git-send-email-lekensteyn@gmail.com |
---|---|
State | Superseded, archived |
Delegated to: | David Miller |
Headers | show |
On Sat, 2013-08-17 at 11:04 +0200, Peter Wu wrote: > From: Peter Wu <lekensteyn@gmail.com> > > For some reason, my PCIe RTL8111E onboard NIC on a GA-Z68X-UD3H-B3 > motherboard reads as FFs when reading from MMIO with a block size > larger than 7. Therefore change to reading blocks of four bytes. > > Thanks to Francois for a better implementation. > > Signed-off-by: Peter Wu <lekensteyn@gmail.com> > --- > drivers/net/ethernet/realtek/r8169.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c > index b5eb419..2943916 100644 > --- a/drivers/net/ethernet/realtek/r8169.c > +++ b/drivers/net/ethernet/realtek/r8169.c > @@ -1897,12 +1897,16 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, > void *p) > { > struct rtl8169_private *tp = netdev_priv(dev); > + u32 __iomem *data = tp->mmio_addr; > + u32 *dw = p; > + int i; > > if (regs->len > R8169_REGS_SIZE) > regs->len = R8169_REGS_SIZE; > > rtl_lock_work(tp); > - memcpy_fromio(p, tp->mmio_addr, regs->len); > + for (i = regs->len; i > 0; i -= 4) > + memcpy_fromio(dw++, data++, min(4, i)); I would be very wary of accessing registers with any width other than the usual (32 bits). And as I said, the kernel buffer is always large enough for all your registers, so this could just be: for (i = 0; i < R8169_REGS_SIZE; i += 4) memcpy_fromio(dw++, data++, 4); Ben. > rtl_unlock_work(tp); > } >
Ben Hutchings <bhutchings@solarflare.com> : [...] > I would be very wary of accessing registers with any width other than > the usual (32 bits). You are right. Most registers do not seem to care - some are 8 bits wide - but the 8168c datasheet states that it's out of spec for the descriptor ring address registers. Peter, please use Ben's suggestion as is.
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index b5eb419..2943916 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1897,12 +1897,16 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct rtl8169_private *tp = netdev_priv(dev); + u32 __iomem *data = tp->mmio_addr; + u32 *dw = p; + int i; if (regs->len > R8169_REGS_SIZE) regs->len = R8169_REGS_SIZE; rtl_lock_work(tp); - memcpy_fromio(p, tp->mmio_addr, regs->len); + for (i = regs->len; i > 0; i -= 4) + memcpy_fromio(dw++, data++, min(4, i)); rtl_unlock_work(tp); }