[PATCH] gianfar: Fall back to software tcp/udp checksum on older controllers

2011-01-27 Thread Alex Dubov
As specified by errata eTSEC49 of MPC8548 and errata eTSEC12 of MPC83xx,
older revisions of gianfar controllers will be unable to calculate a TCP/UDP
packet checksum for some aligments of the appropriate FCB. This patch checks
for FCB alignment on such controllers and falls back to software checksumming
if the aligment is known to be bad.

Signed-off-by: Alex Dubov oa...@yahoo.com
---
This is my, somewhat different approach to Matthew Creech proposed solution.

 drivers/net/gianfar.c |   21 +++--
 drivers/net/gianfar.h |1 +
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 5ed8f9f..b4f0e99 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -950,6 +950,11 @@ static void gfar_detect_errata(struct gfar_private *priv)
(pvr == 0x80861010  (mod  0xfff9) == 0x80c0))
priv-errata |= GFAR_ERRATA_A002;
 
+   /* MPC8313 Rev  2.0, MPC8548 rev 2.0 */
+   if ((pvr == 0x80850010  mod == 0x80b0  rev  0x0020)
+   || (pvr == 0x80210020  mod == 0x8030  rev == 0x0020))
+   priv-errata |= GFAR_ERRATA_12;
+
if (priv-errata)
dev_info(dev, enabled errata workarounds, flags: 0x%x\n,
 priv-errata);
@@ -2156,8 +2161,20 @@ static int gfar_start_xmit(struct sk_buff *skb, struct 
net_device *dev)
/* Set up checksumming */
if (CHECKSUM_PARTIAL == skb-ip_summed) {
fcb = gfar_add_fcb(skb);
-   lstatus |= BD_LFLAG(TXBD_TOE);
-   gfar_tx_checksum(skb, fcb);
+   switch (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12))
+   ? 1 : 0) {
+   case 1:
+   /* as specified by errata */
+   if (((unsigned long)fcb % 0x20)  0x18) { 
+   __skb_pull(skb, GMAC_FCB_LEN);
+   skb_checksum_help(skb);
+   break;
+   }
+   /* otherwise, fall through */
+   default:
+   lstatus |= BD_LFLAG(TXBD_TOE);
+   gfar_tx_checksum(skb, fcb);
+   }
}
 
if (vlan_tx_tag_present(skb)) {
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 54de413..ec5d595 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1039,6 +1039,7 @@ enum gfar_errata {
GFAR_ERRATA_74  = 0x01,
GFAR_ERRATA_76  = 0x02,
GFAR_ERRATA_A002= 0x04,
+   GFAR_ERRATA_12  = 0x08, /* a.k.a errata eTSEC49 */
 };
 
 /* Struct stolen almost completely (and shamelessly) from the FCC enet source
-- 
1.7.3.2




  
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: FSL DMA engine transfer to PCI memory

2011-01-27 Thread Felix Radensky

Hi Ira,

On 01/25/2011 06:29 PM, Ira W. Snyder wrote:

On Tue, Jan 25, 2011 at 04:32:02PM +0200, Felix Radensky wrote:

Hi Ira,

On 01/25/2011 02:18 AM, Ira W. Snyder wrote:

On Tue, Jan 25, 2011 at 01:39:39AM +0200, Felix Radensky wrote:

Hi Ira, Scott

On 01/25/2011 12:26 AM, Ira W. Snyder wrote:

On Mon, Jan 24, 2011 at 11:47:22PM +0200, Felix Radensky wrote:

Hi,

I'm trying to use FSL DMA engine to perform DMA transfer from
memory buffer obtained by kmalloc() to PCI memory. This is on
custom board based on P2020 running linux-2.6.35. The PCI
device is Altera FPGA, connected directly to SoC PCI-E controller.

01:00.0 Unassigned class [ff00]: Altera Corporation Unknown device
0004 (rev 01)
Subsystem: Altera Corporation Unknown device 0004
Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast
TAbort-TAbort-MAbort-SERR-PERR-
Interrupt: pin A routed to IRQ 16
Region 0: Memory at c000 (32-bit, non-prefetchable)
[size=128K]
Capabilities: [50] Message Signalled Interrupts: Mask- 64bit+
Queue=0/0 Enable-
Address:   Data: 
Capabilities: [78] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [80] Express Endpoint IRQ 0
Device: Supported: MaxPayload 256 bytes, PhantFunc 0,
ExtTag-
Device: Latency L0s64ns, L11us
Device: AtnBtn- AtnInd- PwrInd-
Device: Errors: Correctable- Non-Fatal- Fatal-
Unsupported-
Device: RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
Device: MaxPayload 128 bytes, MaxReadReq 512 bytes
Link: Supported Speed 2.5Gb/s, Width x1, ASPM L0s, Port 1
Link: Latency L0s unlimited, L1 unlimited
Link: ASPM Disabled RCB 64 bytes CommClk- ExtSynch-
Link: Speed 2.5Gb/s, Width x1
Capabilities: [100] Virtual Channel


I can successfully writel() to PCI memory via address obtained from
pci_ioremap_bar().
Here's my DMA transfer routine

static int dma_transfer(struct dma_chan *chan, void *dst, void *src,
size_t len)
{
int rc = 0;
dma_addr_t dma_src;
dma_addr_t dma_dst;
dma_cookie_t cookie;
struct completion cmp;
enum dma_status status;
enum dma_ctrl_flags flags = 0;
struct dma_device *dev = chan-device;
struct dma_async_tx_descriptor *tx = NULL;
unsigned long tmo = msecs_to_jiffies(FPGA_DMA_TIMEOUT_MS);

dma_src = dma_map_single(dev-dev, src, len, DMA_TO_DEVICE);
if (dma_mapping_error(dev-dev, dma_src)) {
printk(KERN_ERR Failed to map src for DMA\n);
return -EIO;
}

dma_dst = (dma_addr_t)dst;

flags = DMA_CTRL_ACK |
DMA_COMPL_SRC_UNMAP_SINGLE  |
DMA_COMPL_SKIP_DEST_UNMAP |
DMA_PREP_INTERRUPT;

tx = dev-device_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags);
if (!tx) {
printk(KERN_ERR %s: Failed to prepare DMA transfer\n,
   __FUNCTION__);
dma_unmap_single(dev-dev, dma_src, len, DMA_TO_DEVICE);
return -ENOMEM;
}

init_completion(cmp);
tx-callback = dma_callback;
tx-callback_param =cmp;
cookie = tx-tx_submit(tx);

if (dma_submit_error(cookie)) {
printk(KERN_ERR %s: Failed to start DMA transfer\n,
   __FUNCTION__);
return -ENOMEM;
}

dma_async_issue_pending(chan);

tmo = wait_for_completion_timeout(cmp, tmo);
status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);

if (tmo == 0) {
printk(KERN_ERR %s: Transfer timed out\n, __FUNCTION__);
rc = -ETIMEDOUT;
} else if (status != DMA_SUCCESS) {
printk(KERN_ERR %s: Transfer failed: status is %s\n,
   __FUNCTION__,
   status == DMA_ERROR ? error : in progress);

dev-device_control(chan, DMA_TERMINATE_ALL, 0);
rc = -EIO;
}

return rc;
}

The destination address is PCI memory address returned by
pci_ioremap_bar().
The transfer silently fails, destination buffer doesn't change
contents, but no
error condition is reported.

What am I doing wrong ?

Thanks a lot in advance.


Your destination address is wrong. The device_prep_dma_memcpy() routine
works in physical addresses only (dma_addr_t type). Your source address
looks fine: you're using the result of dma_map_single(), which returns a
physical address.

Your destination address should be something that comes from struct
pci_dev.resource[x].start 

Re: [PATCH] gianfar: Fall back to software tcp/udp checksum on older controllers

2011-01-27 Thread Anton Vorontsov
Hello Alex,

On Thu, Jan 27, 2011 at 12:14:21AM -0800, Alex Dubov wrote:
 As specified by errata eTSEC49 of MPC8548 and errata eTSEC12 of MPC83xx,
 older revisions of gianfar controllers will be unable to calculate a TCP/UDP
 packet checksum for some aligments of the appropriate FCB. This patch checks
 for FCB alignment on such controllers and falls back to software checksumming
 if the aligment is known to be bad.
 
 Signed-off-by: Alex Dubov oa...@yahoo.com
 ---
 This is my, somewhat different approach to Matthew Creech proposed solution.
 
  drivers/net/gianfar.c |   21 +++--
  drivers/net/gianfar.h |1 +
  2 files changed, 20 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
 index 5ed8f9f..b4f0e99 100644
 --- a/drivers/net/gianfar.c
 +++ b/drivers/net/gianfar.c
 @@ -950,6 +950,11 @@ static void gfar_detect_errata(struct gfar_private *priv)
   (pvr == 0x80861010  (mod  0xfff9) == 0x80c0))
   priv-errata |= GFAR_ERRATA_A002;
  
 + /* MPC8313 Rev  2.0, MPC8548 rev 2.0 */
 + if ((pvr == 0x80850010  mod == 0x80b0  rev  0x0020)
 + || (pvr == 0x80210020  mod == 0x8030  rev == 0x0020))

Please indent it like the above: with two tabs. This is
to keep things consistent.

 + priv-errata |= GFAR_ERRATA_12;
 +
   if (priv-errata)
   dev_info(dev, enabled errata workarounds, flags: 0x%x\n,
priv-errata);
 @@ -2156,8 +2161,20 @@ static int gfar_start_xmit(struct sk_buff *skb, struct 
 net_device *dev)
   /* Set up checksumming */
   if (CHECKSUM_PARTIAL == skb-ip_summed) {
   fcb = gfar_add_fcb(skb);
 - lstatus |= BD_LFLAG(TXBD_TOE);
 - gfar_tx_checksum(skb, fcb);
 + switch (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12))
 + ? 1 : 0) {

The switch construction is quite bizarre. ;-) Why not

if (gfar_has_errata()  (ulong)fcb % 0x20  18) {
csum_help();
} else {
lstatus |=...
tx_csum();
}

?

Thanks,

 + case 1:
 + /* as specified by errata */
 + if (((unsigned long)fcb % 0x20)  0x18) { 
 + __skb_pull(skb, GMAC_FCB_LEN);
 + skb_checksum_help(skb);
 + break;
 + }
 + /* otherwise, fall through */
 + default:
 + lstatus |= BD_LFLAG(TXBD_TOE);
 + gfar_tx_checksum(skb, fcb);
 + }
   }

-- 
Anton Vorontsov
Email: cbouatmai...@gmail.com
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH -mm 2/6] powerpc: convert little-endian bitops macros to static inline functions

2011-01-27 Thread Akinobu Mita
(This patch is intended to be folded into the patch in -mm:
powerpc-introduce-little-endian-bitops.patch)

The little-endian bitops on powerpc are written as preprocessor
macros with the cast to unsigned long *.
This means that even non-pointers will be accepted without an error, and
that is a Very Bad Thing.

This converts the little-endian bitops macros to static inline functions
with proper prototypes.

Suggested-by: H. Peter Anvin h...@zytor.com
Signed-off-by: Akinobu Mita akinobu.m...@gmail.com
Cc: Benjamin Herrenschmidt b...@kernel.crashing.org
Cc: Paul Mackerras pau...@samba.org
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/bitops.h |   43 +
 1 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/bitops.h 
b/arch/powerpc/include/asm/bitops.h
index fe67024..2e56187 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -288,20 +288,35 @@ static __inline__ int test_bit_le(unsigned long nr,
return (tmp[nr  3]  (nr  7))  1;
 }
 
-#define __set_bit_le(nr, addr) \
-   __set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-#define __clear_bit_le(nr, addr) \
-   __clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-
-#define test_and_set_bit_le(nr, addr) \
-   test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-#define test_and_clear_bit_le(nr, addr) \
-   test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-
-#define __test_and_set_bit_le(nr, addr) \
-   __test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
-#define __test_and_clear_bit_le(nr, addr) \
-   __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (unsigned long *)(addr))
+static inline void __set_bit_le(int nr, void *addr)
+{
+   __set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline void __clear_bit_le(int nr, void *addr)
+{
+   __clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline int test_and_set_bit_le(int nr, void *addr)
+{
+   return test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline int test_and_clear_bit_le(int nr, void *addr)
+{
+   return test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline int __test_and_set_bit_le(int nr, void *addr)
+{
+   return __test_and_set_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
+
+static inline int __test_and_clear_bit_le(int nr, void *addr)
+{
+   return __test_and_clear_bit(nr ^ BITOP_LE_SWIZZLE, addr);
+}
 
 #define find_first_zero_bit_le(addr, size) \
find_next_zero_bit_le((addr), (size), 0)
-- 
1.7.3.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: FSL DMA engine transfer to PCI memory

2011-01-27 Thread Ira W. Snyder
On Thu, Jan 27, 2011 at 10:32:19AM +0200, Felix Radensky wrote:
 Hi Ira,
 
 On 01/25/2011 06:29 PM, Ira W. Snyder wrote:
  On Tue, Jan 25, 2011 at 04:32:02PM +0200, Felix Radensky wrote:
  Hi Ira,
 
  On 01/25/2011 02:18 AM, Ira W. Snyder wrote:
  On Tue, Jan 25, 2011 at 01:39:39AM +0200, Felix Radensky wrote:
  Hi Ira, Scott
 
  On 01/25/2011 12:26 AM, Ira W. Snyder wrote:
  On Mon, Jan 24, 2011 at 11:47:22PM +0200, Felix Radensky wrote:
  Hi,
 
  I'm trying to use FSL DMA engine to perform DMA transfer from
  memory buffer obtained by kmalloc() to PCI memory. This is on
  custom board based on P2020 running linux-2.6.35. The PCI
  device is Altera FPGA, connected directly to SoC PCI-E controller.
 
  01:00.0 Unassigned class [ff00]: Altera Corporation Unknown device
  0004 (rev 01)
  Subsystem: Altera Corporation Unknown device 0004
  Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop-
  ParErr- Stepping- SERR- FastB2B-
  Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast
  TAbort-TAbort-MAbort-SERR-PERR-
  Interrupt: pin A routed to IRQ 16
  Region 0: Memory at c000 (32-bit, non-prefetchable)
  [size=128K]
  Capabilities: [50] Message Signalled Interrupts: Mask- 
  64bit+
  Queue=0/0 Enable-
  Address:   Data: 
  Capabilities: [78] Power Management version 3
  Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
  PME(D0-,D1-,D2-,D3hot-,D3cold-)
  Status: D0 PME-Enable- DSel=0 DScale=0 PME-
  Capabilities: [80] Express Endpoint IRQ 0
  Device: Supported: MaxPayload 256 bytes, PhantFunc 
  0,
  ExtTag-
  Device: Latency L0s64ns, L11us
  Device: AtnBtn- AtnInd- PwrInd-
  Device: Errors: Correctable- Non-Fatal- Fatal-
  Unsupported-
  Device: RlxdOrd+ ExtTag- PhantFunc- AuxPwr- 
  NoSnoop+
  Device: MaxPayload 128 bytes, MaxReadReq 512 bytes
  Link: Supported Speed 2.5Gb/s, Width x1, ASPM L0s, 
  Port 1
  Link: Latency L0s unlimited, L1 unlimited
  Link: ASPM Disabled RCB 64 bytes CommClk- ExtSynch-
  Link: Speed 2.5Gb/s, Width x1
  Capabilities: [100] Virtual Channel
 
 
  I can successfully writel() to PCI memory via address obtained from
  pci_ioremap_bar().
  Here's my DMA transfer routine
 
  static int dma_transfer(struct dma_chan *chan, void *dst, void *src,
  size_t len)
  {
  int rc = 0;
  dma_addr_t dma_src;
  dma_addr_t dma_dst;
  dma_cookie_t cookie;
  struct completion cmp;
  enum dma_status status;
  enum dma_ctrl_flags flags = 0;
  struct dma_device *dev = chan-device;
  struct dma_async_tx_descriptor *tx = NULL;
  unsigned long tmo = msecs_to_jiffies(FPGA_DMA_TIMEOUT_MS);
 
  dma_src = dma_map_single(dev-dev, src, len, DMA_TO_DEVICE);
  if (dma_mapping_error(dev-dev, dma_src)) {
  printk(KERN_ERR Failed to map src for DMA\n);
  return -EIO;
  }
 
  dma_dst = (dma_addr_t)dst;
 
  flags = DMA_CTRL_ACK |
  DMA_COMPL_SRC_UNMAP_SINGLE  |
  DMA_COMPL_SKIP_DEST_UNMAP |
  DMA_PREP_INTERRUPT;
 
  tx = dev-device_prep_dma_memcpy(chan, dma_dst, dma_src, len, 
  flags);
  if (!tx) {
  printk(KERN_ERR %s: Failed to prepare DMA transfer\n,
 __FUNCTION__);
  dma_unmap_single(dev-dev, dma_src, len, DMA_TO_DEVICE);
  return -ENOMEM;
  }
 
  init_completion(cmp);
  tx-callback = dma_callback;
  tx-callback_param =cmp;
  cookie = tx-tx_submit(tx);
 
  if (dma_submit_error(cookie)) {
  printk(KERN_ERR %s: Failed to start DMA transfer\n,
 __FUNCTION__);
  return -ENOMEM;
  }
 
  dma_async_issue_pending(chan);
 
  tmo = wait_for_completion_timeout(cmp, tmo);
  status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
 
  if (tmo == 0) {
  printk(KERN_ERR %s: Transfer timed out\n, __FUNCTION__);
  rc = -ETIMEDOUT;
  } else if (status != DMA_SUCCESS) {
  printk(KERN_ERR %s: Transfer failed: status is %s\n,
 __FUNCTION__,
 status == DMA_ERROR ? error : in progress);
 
  dev-device_control(chan, DMA_TERMINATE_ALL, 0);
  rc = -EIO;
  }
 
  return rc;
  }
 
  The destination address is PCI memory address returned by
  pci_ioremap_bar().
  The transfer silently fails, destination buffer doesn't change
  contents, but no
  error condition is reported.
 
  What am I doing wrong ?
 
  Thanks a lot in advance.
 
  Your destination 

Re: [PATCH 2/7] PowerPC: add unlikely() to BUG_ON()

2011-01-27 Thread David Daney
Why not also CC the PPC maintainers as well?  I am not certain, but I 
think they may be reached at:


linuxppc-dev@lists.ozlabs.org


On 01/27/2011 04:12 AM, Coly Li wrote:

Current BUG_ON() arch/powerpc/include/asm/bug.h does not use unlikely(),
in order to get better branch predict result, source code may have to call
BUG_ON() with unlikely() explicitly. This is not a suggested method
to use BUG_ON().

This patch adds unlikely() inside BUG_ON implementation on PPC
code, callers can use BUG_ON without explicit unlikely() now.

I don't have any PPC hardware to compile and test this fix, any feedback
of this patch is welcome.

Signed-off-by: Coly Libosong...@taobao.com
Cc: Jeremy Fitzhardingejer...@goop.org
Cc: David Daneydda...@caviumnetworks.com
Cc: Wang Congxiyou.wangc...@gmail.com
Cc: Yong Zhangyong.zha...@gmail.com
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 065c590..10889a6 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -2,6 +2,7 @@
  #define _ASM_POWERPC_BUG_H
  #ifdef __KERNEL__

+#includelinux/compiler.h
  #includeasm/asm-compat.h

  /*
@@ -71,7 +72,7 @@
unreachable();  \
  } while (0)

-#define BUG_ON(x) do { \
+#define __BUG_ON(x) do {   \
if (__builtin_constant_p(x)) {  \
if (x)  \
BUG();  \
@@ -85,6 +86,8 @@
}   \
  } while (0)

+#define BUG_ON(x) __BUG_ON(unlikely(x))
+


This is the same type of frobbing you were trying to do to MIPS.

I will let the powerpc maintainers weigh in on it, but my opinion is 
that, as with MIPS, BUG_ON() is expanded to a single machine 
instruction, and this unlikely() business will not change the generated 
code in any useful way.  It is thus gratuitous code churn and 
complexification.


David Daney


  #define __WARN_TAINT(taint) do {  \
__asm__ __volatile__(   \
1:twi 31,0,0\n  \


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/7] PowerPC: add unlikely() to BUG_ON()

2011-01-27 Thread Scott Wood
On Thu, 27 Jan 2011 09:57:39 -0800
David Daney dda...@caviumnetworks.com wrote:

 On 01/27/2011 04:12 AM, Coly Li wrote:
  diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
  index 065c590..10889a6 100644
  --- a/arch/powerpc/include/asm/bug.h
  +++ b/arch/powerpc/include/asm/bug.h
  @@ -2,6 +2,7 @@
#define _ASM_POWERPC_BUG_H
#ifdef __KERNEL__
 
  +#includelinux/compiler.h
#includeasm/asm-compat.h
 
/*
  @@ -71,7 +72,7 @@
  unreachable();  \
} while (0)
 
  -#define BUG_ON(x) do { \
  +#define __BUG_ON(x) do {   \
  if (__builtin_constant_p(x)) {  \
  if (x)  \
  BUG();  \
  @@ -85,6 +86,8 @@
  }   \
} while (0)
 
  +#define BUG_ON(x) __BUG_ON(unlikely(x))
  +
 
 This is the same type of frobbing you were trying to do to MIPS.
 
 I will let the powerpc maintainers weigh in on it, but my opinion is 
 that, as with MIPS, BUG_ON() is expanded to a single machine 
 instruction, and this unlikely() business will not change the generated 
 code in any useful way.  It is thus gratuitous code churn and 
 complexification.

What about just doing this:

#define BUG() __builtin_trap()

#define BUG_ON(x) do {  \
if (x) \
BUG(); \
} while (0)

GCC should produce better code than forcing it into twnei.  A simple
BUG_ON(x != y) currently generates something like this (GCC 4.3):

xor r0,r11,r0
addic   r10,r0,-1
subfe   r9,r10,r0
twnei   r9,0

Or this (GCC 4.5):

xor r0,r11,r0
cntlzw  r0,r0
srwir0,r0,5
xorir0,r0,1
twnei   r0,0

Instead of:

twner0,r11

And if GCC doesn't treat code paths that lead to __builtin_trap() as
unlikely (which could make a difference with complex expressions,
even with a conditional trap instruction), that's something that could
and should be fixed in GCC.

The downside is that GCC says, The mechanism used may vary from
release to release so you should not rely on any particular
implementation.  However, some architectures (sparc, m68k, ia64)
already use __builtin_trap() for this, it seems unlikely that future GCC
versions would switch away from using the trap instruction[1], and there
doesn't seem to be a better-defined way to make GCC generate trap
instructions intelligently.

-Scott

[1] A more likely possibility is that an older compiler just generates a
call to abort() or similar, and later versions implemented trap -- need
to check what the oldest supported GCC does.

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: fix pfn_valid() when memory starts at a non-zero address

2011-01-27 Thread Scott Wood
max_mapnr is a pfn, not an index innto mem_map[].  So don't add
ARCH_PFN_OFFSET a second time.

Signed-off-by: Scott Wood scottw...@freescale.com
---
 arch/powerpc/include/asm/page.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 53b64be..da4b200 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -101,7 +101,7 @@ extern phys_addr_t kernstart_addr;
 
 #ifdef CONFIG_FLATMEM
 #define ARCH_PFN_OFFSET(MEMORY_START  PAGE_SHIFT)
-#define pfn_valid(pfn) ((pfn) = ARCH_PFN_OFFSET  (pfn)  
(ARCH_PFN_OFFSET + max_mapnr))
+#define pfn_valid(pfn) ((pfn) = ARCH_PFN_OFFSET  (pfn)  max_mapnr)
 #endif
 
 #define virt_to_page(kaddr)pfn_to_page(__pa(kaddr)  PAGE_SHIFT)
-- 
1.7.0.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/7] PowerPC: add unlikely() to BUG_ON()

2011-01-27 Thread David Daney

On 01/27/2011 12:04 PM, Scott Wood wrote:

On Thu, 27 Jan 2011 09:57:39 -0800
David Daneydda...@caviumnetworks.com  wrote:


On 01/27/2011 04:12 AM, Coly Li wrote:

diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 065c590..10889a6 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -2,6 +2,7 @@
   #define _ASM_POWERPC_BUG_H
   #ifdef __KERNEL__

+#includelinux/compiler.h
   #includeasm/asm-compat.h

   /*
@@ -71,7 +72,7 @@
unreachable();  \
   } while (0)

-#define BUG_ON(x) do { \
+#define __BUG_ON(x) do {   \
if (__builtin_constant_p(x)) {  \
if (x)  \
BUG();  \
@@ -85,6 +86,8 @@
}   \
   } while (0)

+#define BUG_ON(x) __BUG_ON(unlikely(x))
+


This is the same type of frobbing you were trying to do to MIPS.

I will let the powerpc maintainers weigh in on it, but my opinion is
that, as with MIPS, BUG_ON() is expanded to a single machine
instruction, and this unlikely() business will not change the generated
code in any useful way.  It is thus gratuitous code churn and
complexification.


What about just doing this:

#define BUG() __builtin_trap()

#define BUG_ON(x) do {  \
if (x) \
BUG(); \
} while (0)

GCC should produce better code than forcing it into twnei.  A simple
BUG_ON(x != y) currently generates something like this (GCC 4.3):

xor r0,r11,r0
addic   r10,r0,-1
subfe   r9,r10,r0
twnei   r9,0

Or this (GCC 4.5):

xor r0,r11,r0
cntlzw  r0,r0
srwir0,r0,5
xorir0,r0,1
twnei   r0,0

Instead of:

twner0,r11

And if GCC doesn't treat code paths that lead to __builtin_trap() as
unlikely (which could make a difference with complex expressions,
even with a conditional trap instruction), that's something that could
and should be fixed in GCC.

The downside is that GCC says, The mechanism used may vary from
release to release so you should not rely on any particular
implementation.  However, some architectures (sparc, m68k, ia64)
already use __builtin_trap() for this, it seems unlikely that future GCC
versions would switch away from using the trap instruction[1], and there
doesn't seem to be a better-defined way to make GCC generate trap
instructions intelligently.



This is good in theory, however powerpc has this _EMIT_BUG_ENTRY 
business that wouldn't work with __builtin_trap().


David Daney


-Scott

[1] A more likely possibility is that an older compiler just generates a
call to abort() or similar, and later versions implemented trap -- need
to check what the oldest supported GCC does.



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc: fix memory limits when starting at a non-zero address

2011-01-27 Thread Scott Wood
memblock_enforce_memory_limit() takes the desired maximum quantity of memory
to end up with, not an address above which memory will not be used.

Signed-off-by: Scott Wood scottw...@freescale.com
---
 arch/powerpc/kernel/prom.c |2 +-
 arch/powerpc/mm/init_32.c  |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 7185f0d..05b7139 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -97,7 +97,7 @@ static void __init move_device_tree(void)
start = __pa(initial_boot_params);
size = be32_to_cpu(initial_boot_params-totalsize);
 
-   if ((memory_limit  (start + size)  memory_limit) ||
+   if ((memory_limit  (start + size)  PHYSICAL_START + memory_limit) ||
overlaps_crashkernel(start, size)) {
p = __va(memblock_alloc(size, PAGE_SIZE));
memcpy(p, initial_boot_params, size);
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 742da43..d65b591 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -148,7 +148,7 @@ void __init MMU_init(void)
lowmem_end_addr = memstart_addr + total_lowmem;
 #ifndef CONFIG_HIGHMEM
total_memory = total_lowmem;
-   memblock_enforce_memory_limit(lowmem_end_addr);
+   memblock_enforce_memory_limit(total_lowmem);
memblock_analyze();
 #endif /* CONFIG_HIGHMEM */
}
-- 
1.7.0.4

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] gianfar: Fall back to software tcp/udp checksum on older controllers

2011-01-27 Thread David Miller

Please CC: netdev on future submissions of this patch, otherwise I
won't see it in my queue.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 1/2] powerpc: document the MPIC device tree binding

2011-01-27 Thread Meador Inge

On 01/20/2011 09:50 AM, Yoder Stuart-B08248 wrote:




-Original Message-
From: Meador Inge [mailto:meador_i...@mentor.com]
Sent: Wednesday, January 19, 2011 6:08 PM
To: Yoder Stuart-B08248
Cc: Wood Scott-B07421; linuxppc-dev@lists.ozlabs.org; devicetree-
disc...@lists.ozlabs.org; Blanchard, Hollis
Subject: Re: [PATCH 1/2] powerpc: document the MPIC device tree binding

On 01/19/2011 04:14 PM, Yoder Stuart-B08248 wrote:



+** Optional properties:
+
+   - no-reset : The presence of this property indicates that the MPIC
+should not be reset during runtime initialization.
+   - protected-sources : Specifies a list of interrupt sources that
+ are not
+ available for use and whose corresponding
+ vectors
+ should not be initialized.  A typical use
+ case for
+ this property is in AMP systems where multiple
+ independent operating systems need to share
+ the MPIC
+ without clobbering each other.


Is protected-sources really needed for AMP systems to tell the OSes
not to clobber each other?  Won't each OS be given a device tree with
only its interrupt sources?  ...so you know what you are allowed to
touch.


This was discussed a little bit already [1, 2].  The MPIC driver currently
initializes the VECPRI register for all interrupt sources, which can lead
to the aforementioned clobbering.


For sources that are protected and not to be touched, it seems
that the other need is for the OS to know (be guaranteed?) that
those sources have been put in state where the source is masked
or directed to other cores.   You can't have interrupts occurring
on sources that you are not allowed to initialize.

So the no-reset property could potentially cover this as well-- if it was
defined to mean don't reset the mpic and boot firmware has put all sources
in a sane initial state.   And we wouldn't need the protected-sources
property any longer.



This seems reasonable to me.  If no-reset is there, then we will not 
reset the MPIC and *only* sources explicitly listed in interrupts 
properties are up for any sort of initialization (e.g. the VECPRI init). 
  If no-reset is not there, then anything is free game.


In terms of implementation, I think we can (1) pull the protected 
sources code, (2) keep the VECPRI initialization in 'mpic_init' from 
happening when no-reset is present, and (3) lazily perform the 
VECPRI initialization in 'mpic_host_map' (this way only sources 
mentioned in the device tree are initialized).


I will send out a patch with these updates tomorrow.  I also CC'd Ben, 
who wrote the original protected sources work, to make sure something 
about the original use case is not being missed.


--
Meador Inge | meador_inge AT mentor.com
Mentor Embedded | http://www.mentor.com/embedded-software
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] gianfar: Fall back to software tcp/udp checksum on older controllers

2011-01-27 Thread Alex Dubov
  -       
 gfar_tx_checksum(skb, fcb);
  +        switch
 (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12))
  +       
     ? 1 : 0) {
 
 The switch construction is quite bizarre. ;-) Why not
 

My testing shows that even on broken chips unaligned packets are quite rare
(only some SYN packets seem to be affected). So I tried to leave the
checksum offload path as the most preferred one.



  
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


AUTO: Michael Barry is out of the office (returning 08/02/2011)

2011-01-27 Thread Michael Barry

I am out of the office until 08/02/2011.




Note: This is an automated response to your message  Linuxppc-dev Digest,
Vol 77, Issue 92 sent on 27/1/11 20:32:14.

This is the only notification you will receive while this person is away.

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2] gianfar: Fall back to software tcp/udp checksum on older controllers

2011-01-27 Thread Alex Dubov
As specified by errata eTSEC49 of MPC8548 and errata eTSEC12 of MPC83xx,
older revisions of gianfar controllers will be unable to calculate a TCP/UDP
packet checksum for some alignments of the appropriate FCB. This patch checks
for FCB alignment on such controllers and falls back to software checksumming
if the alignment is known to be bad.

Signed-off-by: Alex Dubov oa...@yahoo.com
---
Changes for v2:
   - Make indentation slightly more consistent.
   - Replace bizarre switch-based condition with plain boring one.

 drivers/net/gianfar.c |   16 ++--
 drivers/net/gianfar.h |1 +
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 5ed8f9f..3da19a5 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -950,6 +950,11 @@ static void gfar_detect_errata(struct gfar_private *priv)
(pvr == 0x80861010  (mod  0xfff9) == 0x80c0))
priv-errata |= GFAR_ERRATA_A002;
 
+   /* MPC8313 Rev  2.0, MPC8548 rev 2.0 */
+   if ((pvr == 0x80850010  mod == 0x80b0  rev  0x0020) ||
+   (pvr == 0x80210020  mod == 0x8030  rev == 0x0020))
+   priv-errata |= GFAR_ERRATA_12;
+
if (priv-errata)
dev_info(dev, enabled errata workarounds, flags: 0x%x\n,
 priv-errata);
@@ -2156,8 +2161,15 @@ static int gfar_start_xmit(struct sk_buff *skb, struct 
net_device *dev)
/* Set up checksumming */
if (CHECKSUM_PARTIAL == skb-ip_summed) {
fcb = gfar_add_fcb(skb);
-   lstatus |= BD_LFLAG(TXBD_TOE);
-   gfar_tx_checksum(skb, fcb);
+   /* as specified by errata */
+   if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12)
+ ((unsigned long)fcb % 0x20)  0x18)) {
+   __skb_pull(skb, GMAC_FCB_LEN);
+   skb_checksum_help(skb);
+   } else {
+   lstatus |= BD_LFLAG(TXBD_TOE);
+   gfar_tx_checksum(skb, fcb);
+   }
}
 
if (vlan_tx_tag_present(skb)) {
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 54de413..ec5d595 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1039,6 +1039,7 @@ enum gfar_errata {
GFAR_ERRATA_74  = 0x01,
GFAR_ERRATA_76  = 0x02,
GFAR_ERRATA_A002= 0x04,
+   GFAR_ERRATA_12  = 0x08, /* a.k.a errata eTSEC49 */
 };
 
 /* Struct stolen almost completely (and shamelessly) from the FCC enet source
-- 
1.7.3.2




  
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev