[#5847] IPv6 not working in 2009R1 with bfin mac: "hw csum failure"

Document created by Aaronwu Employee on Sep 10, 2013
Version 1Show Document
  • View in full screen mode

[#5847] IPv6 not working in 2009R1 with bfin mac: "hw csum failure"

Submitted By: Jon Kowal

Open Date

2010-01-25 03:19:11     Close Date

2010-06-11 04:53:27

Priority:

Medium     Assignee:

Sonic Zhang

Status:

Closed     Fixed In Release:

N/A

Found In Release:

2009R1-RC6     Release:

Category:

N/A     Board:

N/A

Processor:

BF537     Silicon Revision:

Is this bug repeatable?:

Yes     Resolution:

Fixed

Uboot version or rev.:

    Toolchain version or rev.:

2009R1

App binary format:

N/A     

Summary: IPv6 not working in 2009R1 with bfin mac: "hw csum failure"

Details:

 

Hi,

 

I am using the current 2009R1 branch code, having IPv6 enabled in Kernel and Toolchain and am getting kernel dumps (see below) whenever an IPv6 is being received. I tested with UDP (mdns) and ICMP (ping6). Echo requests are not being answered over IPv6.

 

Is this a known (and maybe fixed) problem or should I investigate further? I didn't have these Problems with 2008R1-RC8.

 

# eth0: hw csum failure.

Hardware Trace:

   0 Target : <0x00004a80> { _dump_stack + 0x0 }

     Source : <0x000d110e> { _netdev_rx_csum_fault + 0x2e } JUMP.L

   1 Target : <0x000d1108> { _netdev_rx_csum_fault + 0x28 }

     Source : <0x0000d976> { _printk + 0x16 } RTS

   2 Target : <0x0000d972> { _printk + 0x12 }

     Source : <0x0000e1f8> { _vprintk + 0x12c } RTS

   3 Target : <0x0000e1ec> { _vprintk + 0x120 }

     Source : <0xffa00c8a> { __common_int_entry + 0xca } RTI

   4 Target : <0xffa00c28> { __common_int_entry + 0x68 }

     Source : <0xffa00a80> { _return_from_int + 0x58 } RTS

   5 Target : <0xffa00a80> { _return_from_int + 0x58 }

     Source : <0xffa00a56> { _return_from_int + 0x2e } IF !CC JUMP

   6 Target : <0xffa00a28> { _return_from_int + 0x0 }

     Source : <0xffa00c24> { __common_int_entry + 0x64 } CALL pcrel

   7 Target : <0xffa00c22> { __common_int_entry + 0x62 }

     Source : <0xffa0033a> { _asm_do_IRQ + 0x6e } RTS

   8 Target : <0xffa00332> { _asm_do_IRQ + 0x66 }

     Source : <0x00011b02> { _irq_exit + 0x2e } RTS

   9 Target : <0x00011b02> { _irq_exit + 0x2e }

     Source : <0x00011af0> { _irq_exit + 0x1c } IF !CC JUMP

  10 Target : <0x00011ad4> { _irq_exit + 0x0 }

     Source : <0xffa0032e> { _asm_do_IRQ + 0x62 } CALL pcrel

  11 Target : <0xffa0032e> { _asm_do_IRQ + 0x62 }

     Source : <0xffa00328> { _asm_do_IRQ + 0x5c } IF CC JUMP

  12 Target : <0xffa00304> { _asm_do_IRQ + 0x38 }

     Source : <0x00029986> { _handle_simple_irq + 0x6a } RTS

  13 Target : <0x0002997a> { _handle_simple_irq + 0x5e }

     Source : <0x00029990> { _handle_simple_irq + 0x74 } JUMP.S

  14 Target : <0x00029990> { _handle_simple_irq + 0x74 }

     Source : <0x00029102> { _note_interrupt + 0x82 } RTS

  15 Target : <0x000290ec> { _note_interrupt + 0x6c }

     Source : <0x0002909c> { _note_interrupt + 0x1c } IF CC JUMP

Stack info:

SP: [0x00193c9c] <0x00193c9c> /* kernel dynamic memory */

FP: (0x00193cb0)

Memory from 0x00193c90 to 00194000

00193c90: 00193c9c  00193c9c  0025d620 [0027e000]<000cdc12> 0025d620  00000000  03e6b1ac

00193cb0:(00193ce4)<0310b8de> ffff117e <000cdc26> 004c4828  feac37ff <0310c08a> 000d4b1c

00193cd0: 0044b920 <03117304> 0044b9b0  0027e000 <0310c26a>(00000000) 00181fbc  00000000

00193cf0:<0310c2b0> 0017c22c  00000000  00000000  00193d1c  00000000  00193d88  00193d78

00193d10: 00000001  00000003  00000002  00000001  0027e000 <0310c360> 004c4838  0025d620

00193d30: 003195a0  00193d6c  00181fbc  00000000  ffff3219  00181fbc  03e6b1ac  00000002

00193d50: 00193d6c  00000005 <0310c7de> 00193d88 <00009bd0><0311b850> 00011d68  00000000

00193d70: 00000002  00000000  003195a0 <031045f6> 0025d620  03133c28  00000006  ffff3055

00193d90: 0000003a  00000000  ffff3219  0000003a  00000000  00000000  00182288 <031047fa>

00193db0: 00182288 <0310480a> 0025d620  0025d620  0027e000  0000dd86  00182270  00182258

00193dd0: 0025d620  0027e000 <000d0f8c> 00182258  0000001f  0000ffff <000289e6> 0027e000

00193df0: 0018745c <000d2ef2> 001821c8  001821c4  001821e0  00000000  ffff3219  00000040

00193e10: 00312ee0  0025d620  00000000  00000000  00185858 <000d29fc> 001821e0  001821e8

00193e30: 001821c4  00000040  0000012c  00000100 <ffa00450> 0017d730  7355a2cc  00193e4c

00193e50: 00000001 <0001181a> 0017c298  00192000  0017c22c  00000001  0000000c  00000100

00193e70: 0000000a <00029990> 00188644  00000018  001728a4  00000018  00185858 <ffa00332>

00193e90: 001808ec  00192000  001728a4  00000018  00000000  00000000  00000000  03935988

00193eb0: ffa0126c  00000000 <ffa00c22> ffa00250  00172004  00000000  00000000  00000000

00193ed0: 00000000  ffa00274  03ec46c0  00000000  00000000  03d8a000  039cd538  ffa00274

00193ef0:<ffa00140> 0000000b  02002020  0043d915  ffa0134c  0043d914  ffa0134a  00000000

00193f10: 00000000  0000090b  00000000  003d08ce  00000000  00000000  00000000  00000000

00193f30: 00000000  00000000  00000000  00000000  00000000  00000000  00000000  00000000

00193f50: 00000000  00000000  00000000  00000000  0000c350  00194000  00185858  ffa00250

00193f70: 00192000  001728a4  00185858  00192000  ffa009b8  00172004  00000000  00000000

00193f90: 00000000  00000003  00000000  03ec46c0  0000ffff  0000ffff  ffa009b8  00000006

00193fb0: 00172004  00000000  00000000  001946ce  0017ebd0  001ace04  00172010  00172004

00193fd0: 00000000  001ace04  001718a0  00000011  001940a8  001af854  00194000  001a2944

00193ff0: 00000000  00000000  00000000  ffb00000

Return addresses in stack:

    address : <0x000cdc12> { ___skb_checksum_complete_head + 0x5e }

   frame  1 : <0x0310b8de> { :ipv6:___ip6_ins_rt + 0x36 }

    address : <0x000cdc26> { ___skb_checksum_complete + 0xe }

    address : <0x0310c08a> { :ipv6:_ip6_ins_rt + 0x22 }

    address : <0x03117304> { :ipv6:_icmpv6_rcv + 0x1b0 }

    address : <0x0310c26a> { :ipv6:_ip6_pol_route + 0x1da }

    address : <0x0310c2b0> { :ipv6:_ip6_pol_route + 0x220 }

    address : <0x0310c360> { :ipv6:_ip6_pol_route_input + 0x18 }

    address : <0x0310c7de> { :ipv6:_ip6_route_input + 0x9a }

    address : <0x00009bd0> { _enqueue_task_fair + 0x30 }

    address : <0x0311b850> { :ipv6:_ipv6_chk_mcast_addr + 0xa4 }

    address : <0x031045f6> { :ipv6:_ip6_input + 0xd6 }

    address : <0x031047fa> { :ipv6:_ip6_mc_input + 0x4e }

    address : <0x0310480a> { :ipv6:_ip6_mc_input + 0x5e }

    address : <0x000d0f8c> { _netif_receive_skb + 0x1cc }

    address : <0x000289e6> { ___enable_irq + 0x4e }

    address : <0x000d2ef2> { _process_backlog + 0x66 }

    address : <0x000d29fc> { _net_rx_action + 0x90 }

    address : <0xffa00450> { _timer_interrupt + 0xd0 }

    address : <0x0001181a> { ___do_softirq + 0x5a }

    address : <0x00029990> { _handle_simple_irq + 0x74 }

    address : <0xffa00332> { _asm_do_IRQ + 0x66 }

    address : <0xffa00c22> { __common_int_entry + 0x62 }

    address : <0xffa00140> { _cpu_idle + 0x20 }

 

Follow-ups

 

--- Jon Kowal                                                2010-01-25 04:53:46

As a workaround i undefined BFIN_MAC_CSUM_OFFLOAD in bfin_mac.h.

 

Maybe there should be a switch somewhere so that checksum offloading is only

enabled for IPv4 packets. Detecting those could be easily done by checking the

one byte in the packet that tells the IP version.

 

--- Sonic Zhang                                              2010-01-25 05:22:15

You walk around is correct. This has already been done in latest 2009R1.1

release. Duplicated bug of bug #5600

 

--- Jon Kowal                                                2010-01-25 05:36:18

No, my Cache policy is set to "Write through" and I am already using

the latest branch code with the workaround regarding cache WB implemented.

 

The bug I am experiencing only affects IPv6. And it does so for EVERY packet

being received, not just "sometimes" as is the case with WB enabled.

 

--- Jon Kowal                                                2010-01-25 06:03:04

I fixed the problem with the attached patch.

 

My reasoning: The blackfin checksum calculation is based on the assumption that

a standard IP packet has a header length of 20 bytes which is true for most IPv4

packets. This assumption is not true for IPv6 packets or IPv4 packets that make

use of header options. We must NOT use the blackfin calculated checksum for

those packets and that's what I achieve by checking assuring that IP version and

header length match the assumptions made in the blackfin hardware

implementation.

 

--- Mike Frysinger                                           2010-01-25 11:33:01

you didnt post a patch, you posted an entire file.  please post an actual diff

so we can see what you changed.

 

--- Jon Kowal                                                2010-01-26 05:06:59

Diff attached.

 

--- Robin Getz                                               2010-01-26 15:54:23

Jon:

 

Sorry to be picky - can you make a unified diff. (diff -u)

 

See :

https://docs.blackfin.uclinux.org/doku.php?id=patches_and_diffs

 

--- Sonic Zhang                                              2010-01-27 01:15:57

Applied. Thanks.

 

--- Robin Getz                                               2010-01-27 13:31:50

While this patch makes things work - it isn't the right thing to do.

 

 

From design:

=============

The IP checksums cover a fixed range of bytes in the frame, so there's

"some assembly required" to get the complete checksum for all packets.

The feature was _not_ designed to do smart content-based checksumming (looking

at certain bytes in the frame to decide whether to include other bytes in the

checksum.)

 

The plan was to give the driver software a preliminary checksum (doing the

heavy lifting of checksumming the hundreds of bytes in the payload), and the

driver software would implement protocol-specific adjustments to the raw

checksum (add or subtract a few bytes here and there to get the complete

checksum).

==========

 

Just ignoring the pre-computed value (which is what this patch does) isn't the

correct answer from a performance standpoint.

 

It should be able to use the preliminary checksum (from the hardware), and add

the few option bytes at the end. This will be much faster than it could doing

the entire thing in software...

 

 

--- Jon Kowal                                                2010-01-27 15:08:05

Robin, you're right. (and sorry about the diff earlier, I'm not used to that

process) I didn't have much time to dig into the issue but assumed IPv6

performing slowly is better than not working at all. Actually IPv6 is performing

just as well as it did before the bug was introduced.

 

I'd gladly see someone adapting the checksum calculation to IPv6 but I think we

should open a new ticket for that.

 

--- Sonic Zhang                                              2010-01-27 22:05:52

I add a new task 5853 "Decuce extra csum from hw csum for IPv6 and IPv4

packet with header options." This bug can be closed with the walk around

applied.

 

--- Mike Frysinger                                           2010-03-05 08:01:13

this patch seems to ignore the hardware csum completely in IPv6/IPv4+headers ?

cant the hardware checksum still be used as a partial checksum in these cases so

we dont have to calculate the entire thing ?

 

--- Robin Getz                                               2010-03-05 09:14:49

I think that is what Sonic's task is.

 

The patch uses the hardware in default packet sizes, but falls back to a 100%

software solution when non-standard packets come in. The task it so use the

partial hardware answer and twiddle the result in software to get the proper

CRC.

 

-Robin

 

 

 

    Files

    Changes

    Commits

    Dependencies

    Duplicates

    Associations

    Tags

 

File Name     File Type     File Size     Posted By

bfin_mac.c    text/x-csrc    31218    Jon Kowal

bfin_mac.c_diff    application/octet-stream    2054    Jon Kowal

Attachments

Outcomes