[PATCH] gianfar: Fall back to software tcp/udp checksum on older controllers
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
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
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
(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
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()
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()
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
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()
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
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
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
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
- 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)
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
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