axen Ethernet device errors on both USB3.0 and USB2.0 ports

classic Classic list List threaded Threaded
32 messages Options
12
Reply | Threaded
Open this post in threaded view
|

axen Ethernet device errors on both USB3.0 and USB2.0 ports

Denis Lapshin-2
Every time (after 2-3 minutes of work) ASIX Electronics USB-Ethernet
device reports:

axen0: usb errors on rx: IOERROR
axen0: usb errors on rx: IOERROR
axen0: usb errors on tx: IOERROR
axen0: watchdog timeout
axen0: usb errors on tx: IOERROR

The device hangs and must be reattached to have it working again for 2-3
minutes.

Tested on AMD and Intel platforms

Intended to work on AMD GX-420CA SOC with Radeon(tm) HD Graphics with
dmesg below

------
OpenBSD 6.3 (GENERIC.MP) #107: Sat Mar 24 14:21:59 MDT 2018
    [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 7964327936 (7595MB)
avail mem = 7715876864 (7358MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xe0840 (38 entries)
bios0: vendor Phoenix Technologies Ltd. version "SBCFP4_3.0.0.312_11
X64" date 09/21/2014
bios0: CompuLab fit-PC4
acpi0 at bios0: rev 2
acpi0: sleep states S0 S3 S4 S5
acpi0: tables DSDT FACP HPET APIC MCFG FPDT UEFI POAT BATB SSDT SSDT UEFI
acpi0: wakeup devices GPP0(S4) GPP1(S4) GPP2(S4) GPP3(S4) GFX_(S4)
XHC0(S4) OHC1(S4) EHC1(S4) OHC2(S4) EHC2(S4) SBAZ(S4) UAR1(S3)
acpitimer0 at acpi0: 3579545 Hz, 32 bits
acpihpet0 at acpi0: 14318180 Hz
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: AMD GX-420CA SOC with Radeon(tm) HD Graphics, 1996.49 MHz
cpu0:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TOPEXT,DBKP,PCTRL3,ITSC,BMI1
cpu0: 32KB 64b/line 2-way I-cache, 32KB 64b/line 8-way D-cache, 2MB
64b/line 16-way L2 cache
cpu0: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu0: DTLB 40 4KB entries fully associative, 8 4MB entries fully associative
acpihpet0: recalibrated TSC frequency 1996262805 Hz
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 99MHz
cpu0: mwait min=64, max=64, IBE
cpu1 at mainbus0: apid 1 (application processor)
cpu1: AMD GX-420CA SOC with Radeon(tm) HD Graphics, 1996.26 MHz
cpu1:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TOPEXT,DBKP,PCTRL3,ITSC,BMI1
cpu1: 32KB 64b/line 2-way I-cache, 32KB 64b/line 8-way D-cache, 2MB
64b/line 16-way L2 cache
cpu1: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu1: DTLB 40 4KB entries fully associative, 8 4MB entries fully associative
cpu1: smt 0, core 1, package 0
cpu2 at mainbus0: apid 2 (application processor)
cpu2: AMD GX-420CA SOC with Radeon(tm) HD Graphics, 1996.26 MHz
cpu2:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TOPEXT,DBKP,PCTRL3,ITSC,BMI1
cpu2: 32KB 64b/line 2-way I-cache, 32KB 64b/line 8-way D-cache, 2MB
64b/line 16-way L2 cache
cpu2: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu2: DTLB 40 4KB entries fully associative, 8 4MB entries fully associative
cpu2: smt 0, core 2, package 0
cpu3 at mainbus0: apid 3 (application processor)
cpu3: AMD GX-420CA SOC with Radeon(tm) HD Graphics, 1996.26 MHz
cpu3:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TOPEXT,DBKP,PCTRL3,ITSC,BMI1
cpu3: 32KB 64b/line 2-way I-cache, 32KB 64b/line 8-way D-cache, 2MB
64b/line 16-way L2 cache
cpu3: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
cpu3: DTLB 40 4KB entries fully associative, 8 4MB entries fully associative
cpu3: smt 0, core 3, package 0
ioapic0 at mainbus0: apid 4 pa 0xfec00000, version 21, 24 pins
, remapped to apid 4
ioapic1 at mainbus0: apid 5 pa 0xfec01000, version 21, 32 pins
, remapped to apid 5
acpimcfg0 at acpi0 addr 0xf8000000, bus 0-63
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus 2 (GPP0)
acpiprt2 at acpi0: bus -1 (GPP1)
acpiprt3 at acpi0: bus 4 (GPP2)
acpiprt4 at acpi0: bus 5 (GPP3)
acpiprt5 at acpi0: bus 1 (GFX_)
acpicpu0 at acpi0: C2(0@400 io@0x841), C1(@1 halt!), PSS
acpicpu1 at acpi0: C2(0@400 io@0x841), C1(@1 halt!), PSS
acpicpu2 at acpi0: C2(0@400 io@0x841), C1(@1 halt!), PSS
acpicpu3 at acpi0: C2(0@400 io@0x841), C1(@1 halt!), PSS
acpibtn0 at acpi0: PWRB
"PNP0A05" at acpi0 not configured
acpivideo0 at acpi0: VGA_
cpu0: 1996 MHz: speeds: 2000 1800 1600 1200 1000 800 MHz
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "AMD AMD64 16h Host" rev 0x00
vga1 at pci0 dev 1 function 0 vendor "ATI", unknown product 0x9831 rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
azalia0 at pci0 dev 1 function 1 "ATI Radeon HD Audio" rev 0x00: msi
azalia0: no supported codecs
pchb1 at pci0 dev 2 function 0 vendor "AMD", unknown product 0x1538 rev 0x00
ppb0 at pci0 dev 2 function 1 "AMD AMD64 16h PCIE" rev 0x00: msi
pci1 at ppb0 bus 1
ppb1 at pci0 dev 2 function 2 "AMD AMD64 16h PCIE" rev 0x00: msi
pci2 at ppb1 bus 2
athn0 at pci2 dev 0 function 0 "Atheros AR5418" rev 0x01: apic 5 int 4
athn0: MAC AR5418 rev 2, RF AR5133 (2T3R), ROM rev 5, address
xx:xx:xx:xx:xx:xx
ppb2 at pci0 dev 2 function 4 "AMD AMD64 16h PCIE" rev 0x00: msi
pci3 at ppb2 bus 4
em0 at pci3 dev 0 function 0 "Intel I211" rev 0x03: msi, address
xx:xx:xx:xx:xx:xx
ppb3 at pci0 dev 2 function 5 "AMD AMD64 16h PCIE" rev 0x00: msi
pci4 at ppb3 bus 5
em1 at pci4 dev 0 function 0 "Intel I211" rev 0x03: msi, address
xx:xx:xx:xx:xx:xx
xhci0 at pci0 dev 16 function 0 "AMD Bolton xHCI" rev 0x01: msi
usb0 at xhci0: USB revision 3.0
uhub0 at usb0 configuration 1 interface 0 "AMD xHCI root hub" rev
3.00/1.00 addr 1
ahci0 at pci0 dev 17 function 0 "AMD Hudson-2 SATA" rev 0x40: msi, AHCI 1.3
ahci0: port 0: 6.0Gb/s
scsibus1 at ahci0: 32 targets
sd0 at scsibus1 targ 0 lun 0: <ATA, ST500, 0001> SCSI3 0/direct fixed
naa.5000c500ac5b7fb7
sd0: 476940MB, 512 bytes/sector, 976773168 sectors
ohci0 at pci0 dev 18 function 0 "AMD Hudson-2 USB" rev 0x39: apic 4 int
18, version 1.0, legacy support
ehci0 at pci0 dev 18 function 2 "AMD Hudson-2 USB2" rev 0x39: apic 4 int 17
usb1 at ehci0: USB revision 2.0
uhub1 at usb1 configuration 1 interface 0 "AMD EHCI root hub" rev
2.00/1.00 addr 1
ohci1 at pci0 dev 19 function 0 "AMD Hudson-2 USB" rev 0x39: apic 4 int
18, version 1.0, legacy support
ehci1 at pci0 dev 19 function 2 "AMD Hudson-2 USB2" rev 0x39: apic 4 int 17
usb2 at ehci1: USB revision 2.0
uhub2 at usb2 configuration 1 interface 0 "AMD EHCI root hub" rev
2.00/1.00 addr 1
piixpm0 at pci0 dev 20 function 0 "AMD Hudson-2 SMBus" rev 0x3a: polling
iic0 at piixpm0
spdmem0 at iic0 addr 0x51: 8GB DDR3 SDRAM PC3-12800 SO-DIMM
azalia1 at pci0 dev 20 function 2 "AMD Hudson-2 HD Audio" rev 0x02: apic
4 int 16
azalia1: codecs: Realtek ALC888
audio0 at azalia1
pcib0 at pci0 dev 20 function 3 "AMD Hudson-2 LPC" rev 0x11
sdhc0 at pci0 dev 20 function 7 "AMD Bolton SD/MMC" rev 0x01: apic 4 int 16
sdhc0: SDHC 2.0, 50 MHz base clock
sdmmc0 at sdhc0: 4-bit, sd high-speed, mmc high-speed, dma
pchb2 at pci0 dev 24 function 0 "AMD AMD64 16h Link Cfg" rev 0x00
pchb3 at pci0 dev 24 function 1 "AMD AMD64 16h Address Map" rev 0x00
pchb4 at pci0 dev 24 function 2 "AMD AMD64 16h DRAM Cfg" rev 0x00
km0 at pci0 dev 24 function 3 "AMD AMD64 16h Misc Cfg" rev 0x00
pchb5 at pci0 dev 24 function 4 "AMD AMD64 16h CPU Power" rev 0x00
pchb6 at pci0 dev 24 function 5 vendor "AMD", unknown product 0x1535 rev
0x00
usb3 at ohci0: USB revision 1.0
uhub3 at usb3 configuration 1 interface 0 "AMD OHCI root hub" rev
1.00/1.00 addr 1
usb4 at ohci1: USB revision 1.0
uhub4 at usb4 configuration 1 interface 0 "AMD OHCI root hub" rev
1.00/1.00 addr 1
isa0 at pcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
vmm0 at mainbus0: SVM/RVI
sdmmc0: can't enable card
axen0 at uhub0 port 1 configuration 1 interface 0 "ASIX Elec. Corp.
AX88179" rev 3.00/1.00 addr 2
axen0: AX88179, address xx:xx:xx:xx:xx:xx
rgephy0 at axen0 phy 3: RTL8169S/8110S/8211 PHY, rev. 5
uhidev0 at uhub3 port 1 configuration 1 interface 0 "Dell Dell Smart
Card Reader Keyboard" rev 2.00/1.00 addr 2
uhidev0: iclass 3/1
ukbd0 at uhidev0: 8 variable keys, 6 key codes
wskbd0 at ukbd0: console keyboard, using wsdisplay0
ugen0 at uhub3 port 1 configuration 1 "Dell Dell Smart Card Reader
Keyboard" rev 2.00/1.00 addr 2
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
softraid0: sd1 was not shutdown properly
sd1 at scsibus3 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006> SCSI2 0/direct fixed
sd1: 476937MB, 512 bytes/sector, 976767473 sectors
root on sd1a (9990ff6713f15d12.a) swap on sd1b dump on sd1b

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Tinker
Denis,

That axen is broken is known from before. See

https://marc.info/?t=149601634700002&r=1&w=2

https://marc.info/?t=149141061800001&r=1&w=2

I requested Yojiro to fix the driver but afaik he has not done anything.

AFAIK the Axen hardware is stable so it's a driver problem indeed.
Overall I have a positive impression of Axen, it's designed and made
in Taiwan.

I've been running the Realtek 8153 on the CDCE driver and this has
been stable, but performance has been 100mbps. Didn't try running
the 8153 on the URE driver yet, may do later.

(Also note that the USB 3 stack separately is unstable, and maybe
also only supports the 1gbps mode, not 5gpbs superspeed.)

Tinker

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On July 27, 2018 5:14 PM, Denis <[hidden email]> wrote:

> Every time (after 2-3 minutes of work) ASIX Electronics USB-Ethernet
> device reports:
>
> axen0: usb errors on rx: IOERROR
> axen0: usb errors on rx: IOERROR
> axen0: usb errors on tx: IOERROR
> axen0: watchdog timeout
> axen0: usb errors on tx: IOERROR
>
> The device hangs and must be reattached to have it working again for 2-3
> minutes.
>
> Tested on AMD and Intel platforms
>
> Intended to work on AMD GX-420CA SOC with Radeon(tm) HD Graphics with
> dmesg below
>
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> OpenBSD 6.3 (GENERIC.MP) #107: Sat Mar 24 14:21:59 MDT 2018
> [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> real mem = 7964327936 (7595MB)
> avail mem = 7715876864 (7358MB)
> mpath0 at root
> scsibus0 at mpath0: 256 targets
> mainbus0 at root
> bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xe0840 (38 entries)
> bios0: vendor Phoenix Technologies Ltd. version "SBCFP4_3.0.0.312_11
> X64" date 09/21/2014
> bios0: CompuLab fit-PC4
> acpi0 at bios0: rev 2
> acpi0: sleep states S0 S3 S4 S5
> acpi0: tables DSDT FACP HPET APIC MCFG FPDT UEFI POAT BATB SSDT SSDT UEFI
> acpi0: wakeup devices GPP0(S4) GPP1(S4) GPP2(S4) GPP3(S4) GFX_(S4)
> XHC0(S4) OHC1(S4) EHC1(S4) OHC2(S4) EHC2(S4) SBAZ(S4) UAR1(S3)
> acpitimer0 at acpi0: 3579545 Hz, 32 bits
> acpihpet0 at acpi0: 14318180 Hz
> acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
> cpu0 at mainbus0: apid 0 (boot processor)
> cpu0: AMD GX-420CA SOC with Radeon(tm) HD Graphics, 1996.49 MHz
> cpu0:
> FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TOPEXT,DBKP,PCTRL3,ITSC,BMI1
> cpu0: 32KB 64b/line 2-way I-cache, 32KB 64b/line 8-way D-cache, 2MB
> 64b/line 16-way L2 cache
> cpu0: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
> cpu0: DTLB 40 4KB entries fully associative, 8 4MB entries fully associative
> acpihpet0: recalibrated TSC frequency 1996262805 Hz
> cpu0: smt 0, core 0, package 0
> mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
> cpu0: apic clock running at 99MHz
> cpu0: mwait min=64, max=64, IBE
> cpu1 at mainbus0: apid 1 (application processor)
> cpu1: AMD GX-420CA SOC with Radeon(tm) HD Graphics, 1996.26 MHz
> cpu1:
> FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TOPEXT,DBKP,PCTRL3,ITSC,BMI1
> cpu1: 32KB 64b/line 2-way I-cache, 32KB 64b/line 8-way D-cache, 2MB
> 64b/line 16-way L2 cache
> cpu1: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
> cpu1: DTLB 40 4KB entries fully associative, 8 4MB entries fully associative
> cpu1: smt 0, core 1, package 0
> cpu2 at mainbus0: apid 2 (application processor)
> cpu2: AMD GX-420CA SOC with Radeon(tm) HD Graphics, 1996.26 MHz
> cpu2:
> FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TOPEXT,DBKP,PCTRL3,ITSC,BMI1
> cpu2: 32KB 64b/line 2-way I-cache, 32KB 64b/line 8-way D-cache, 2MB
> 64b/line 16-way L2 cache
> cpu2: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
> cpu2: DTLB 40 4KB entries fully associative, 8 4MB entries fully associative
> cpu2: smt 0, core 2, package 0
> cpu3 at mainbus0: apid 3 (application processor)
> cpu3: AMD GX-420CA SOC with Radeon(tm) HD Graphics, 1996.26 MHz
> cpu3:
> FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TOPEXT,DBKP,PCTRL3,ITSC,BMI1
> cpu3: 32KB 64b/line 2-way I-cache, 32KB 64b/line 8-way D-cache, 2MB
> 64b/line 16-way L2 cache
> cpu3: ITLB 32 4KB entries fully associative, 8 4MB entries fully associative
> cpu3: DTLB 40 4KB entries fully associative, 8 4MB entries fully associative
> cpu3: smt 0, core 3, package 0
> ioapic0 at mainbus0: apid 4 pa 0xfec00000, version 21, 24 pins
> , remapped to apid 4
> ioapic1 at mainbus0: apid 5 pa 0xfec01000, version 21, 32 pins
> , remapped to apid 5
> acpimcfg0 at acpi0 addr 0xf8000000, bus 0-63
> acpiprt0 at acpi0: bus 0 (PCI0)
> acpiprt1 at acpi0: bus 2 (GPP0)
> acpiprt2 at acpi0: bus -1 (GPP1)
> acpiprt3 at acpi0: bus 4 (GPP2)
> acpiprt4 at acpi0: bus 5 (GPP3)
> acpiprt5 at acpi0: bus 1 (GFX_)
> acpicpu0 at acpi0: C2(0@400 io@0x841), C1(@1 halt!), PSS
> acpicpu1 at acpi0: C2(0@400 io@0x841), C1(@1 halt!), PSS
> acpicpu2 at acpi0: C2(0@400 io@0x841), C1(@1 halt!), PSS
> acpicpu3 at acpi0: C2(0@400 io@0x841), C1(@1 halt!), PSS
> acpibtn0 at acpi0: PWRB
> "PNP0A05" at acpi0 not configured
> acpivideo0 at acpi0: VGA_
> cpu0: 1996 MHz: speeds: 2000 1800 1600 1200 1000 800 MHz
> pci0 at mainbus0 bus 0
> pchb0 at pci0 dev 0 function 0 "AMD AMD64 16h Host" rev 0x00
> vga1 at pci0 dev 1 function 0 vendor "ATI", unknown product 0x9831 rev 0x00
> wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
> wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
> azalia0 at pci0 dev 1 function 1 "ATI Radeon HD Audio" rev 0x00: msi
> azalia0: no supported codecs
> pchb1 at pci0 dev 2 function 0 vendor "AMD", unknown product 0x1538 rev 0x00
> ppb0 at pci0 dev 2 function 1 "AMD AMD64 16h PCIE" rev 0x00: msi
> pci1 at ppb0 bus 1
> ppb1 at pci0 dev 2 function 2 "AMD AMD64 16h PCIE" rev 0x00: msi
> pci2 at ppb1 bus 2
> athn0 at pci2 dev 0 function 0 "Atheros AR5418" rev 0x01: apic 5 int 4
> athn0: MAC AR5418 rev 2, RF AR5133 (2T3R), ROM rev 5, address
> xx:xx:xx:xx:xx:xx
> ppb2 at pci0 dev 2 function 4 "AMD AMD64 16h PCIE" rev 0x00: msi
> pci3 at ppb2 bus 4
> em0 at pci3 dev 0 function 0 "Intel I211" rev 0x03: msi, address
> xx:xx:xx:xx:xx:xx
> ppb3 at pci0 dev 2 function 5 "AMD AMD64 16h PCIE" rev 0x00: msi
> pci4 at ppb3 bus 5
> em1 at pci4 dev 0 function 0 "Intel I211" rev 0x03: msi, address
> xx:xx:xx:xx:xx:xx
> xhci0 at pci0 dev 16 function 0 "AMD Bolton xHCI" rev 0x01: msi
> usb0 at xhci0: USB revision 3.0
> uhub0 at usb0 configuration 1 interface 0 "AMD xHCI root hub" rev
> 3.00/1.00 addr 1
> ahci0 at pci0 dev 17 function 0 "AMD Hudson-2 SATA" rev 0x40: msi, AHCI 1.3
> ahci0: port 0: 6.0Gb/s
> scsibus1 at ahci0: 32 targets
> sd0 at scsibus1 targ 0 lun 0: <ATA, ST500, 0001> SCSI3 0/direct fixed
> naa.5000c500ac5b7fb7
> sd0: 476940MB, 512 bytes/sector, 976773168 sectors
> ohci0 at pci0 dev 18 function 0 "AMD Hudson-2 USB" rev 0x39: apic 4 int
> 18, version 1.0, legacy support
> ehci0 at pci0 dev 18 function 2 "AMD Hudson-2 USB2" rev 0x39: apic 4 int 17
> usb1 at ehci0: USB revision 2.0
> uhub1 at usb1 configuration 1 interface 0 "AMD EHCI root hub" rev
> 2.00/1.00 addr 1
> ohci1 at pci0 dev 19 function 0 "AMD Hudson-2 USB" rev 0x39: apic 4 int
> 18, version 1.0, legacy support
> ehci1 at pci0 dev 19 function 2 "AMD Hudson-2 USB2" rev 0x39: apic 4 int 17
> usb2 at ehci1: USB revision 2.0
> uhub2 at usb2 configuration 1 interface 0 "AMD EHCI root hub" rev
> 2.00/1.00 addr 1
> piixpm0 at pci0 dev 20 function 0 "AMD Hudson-2 SMBus" rev 0x3a: polling
> iic0 at piixpm0
> spdmem0 at iic0 addr 0x51: 8GB DDR3 SDRAM PC3-12800 SO-DIMM
> azalia1 at pci0 dev 20 function 2 "AMD Hudson-2 HD Audio" rev 0x02: apic
> 4 int 16
> azalia1: codecs: Realtek ALC888
> audio0 at azalia1
> pcib0 at pci0 dev 20 function 3 "AMD Hudson-2 LPC" rev 0x11
> sdhc0 at pci0 dev 20 function 7 "AMD Bolton SD/MMC" rev 0x01: apic 4 int 16
> sdhc0: SDHC 2.0, 50 MHz base clock
> sdmmc0 at sdhc0: 4-bit, sd high-speed, mmc high-speed, dma
> pchb2 at pci0 dev 24 function 0 "AMD AMD64 16h Link Cfg" rev 0x00
> pchb3 at pci0 dev 24 function 1 "AMD AMD64 16h Address Map" rev 0x00
> pchb4 at pci0 dev 24 function 2 "AMD AMD64 16h DRAM Cfg" rev 0x00
> km0 at pci0 dev 24 function 3 "AMD AMD64 16h Misc Cfg" rev 0x00
> pchb5 at pci0 dev 24 function 4 "AMD AMD64 16h CPU Power" rev 0x00
> pchb6 at pci0 dev 24 function 5 vendor "AMD", unknown product 0x1535 rev
> 0x00
> usb3 at ohci0: USB revision 1.0
> uhub3 at usb3 configuration 1 interface 0 "AMD OHCI root hub" rev
> 1.00/1.00 addr 1
> usb4 at ohci1: USB revision 1.0
> uhub4 at usb4 configuration 1 interface 0 "AMD OHCI root hub" rev
> 1.00/1.00 addr 1
> isa0 at pcib0
> isadma0 at isa0
> com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
> pckbc0 at isa0 port 0x60/5 irq 1 irq 12
> pcppi0 at isa0 port 0x61
> spkr0 at pcppi0
> vmm0 at mainbus0: SVM/RVI
> sdmmc0: can't enable card
> axen0 at uhub0 port 1 configuration 1 interface 0 "ASIX Elec. Corp.
> AX88179" rev 3.00/1.00 addr 2
> axen0: AX88179, address xx:xx:xx:xx:xx:xx
> rgephy0 at axen0 phy 3: RTL8169S/8110S/8211 PHY, rev. 5
> uhidev0 at uhub3 port 1 configuration 1 interface 0 "Dell Dell Smart
> Card Reader Keyboard" rev 2.00/1.00 addr 2
> uhidev0: iclass 3/1
> ukbd0 at uhidev0: 8 variable keys, 6 key codes
> wskbd0 at ukbd0: console keyboard, using wsdisplay0
> ugen0 at uhub3 port 1 configuration 1 "Dell Dell Smart Card Reader
> Keyboard" rev 2.00/1.00 addr 2
> vscsi0 at root
> scsibus2 at vscsi0: 256 targets
> softraid0 at root
> scsibus3 at softraid0: 256 targets
> softraid0: sd1 was not shutdown properly
> sd1 at scsibus3 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006> SCSI2 0/direct fixed
> sd1: 476937MB, 512 bytes/sector, 976767473 sectors
> root on sd1a (9990ff6713f15d12.a) swap on sd1b dump on sd1b


Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Marcus MERIGHI
[hidden email] (Tinker), 2018.07.27 (Fri) 12:17 (CEST):
> (Also note that the USB 3 stack separately is unstable, and maybe

For the archives:

That statement is wrong, unless all the dozens of terabytes I've moved
over xhci(4) are broken now.

Do you mean the isochronous transfer thing? CVS log says:

----------------------------
RCS file: /cvs/src/sys/dev/usb/xhci.c,v
revision 1.77
date: 2017/09/08 10:25:19;  author: stsp;  state: Exp;  lines: +202 -25;
commitid: 6181T4xfBI8wUv3E;
Add support for isochronous transfers to xhci(4).

This is just a step forward which allows further progress to happen
in-tree.
The isochronous code path remains disabled for now. Playing audio over
xhci(4) does not work properly yet, and I haven't even tested video
input.

Based on a work-in-progress diff by mpi@ from 2015.
ok mpi@
----------------------------
revision 1.82
date: 2018/04/27 13:25:08;  author: mpi;  state: Exp;  lines: +72 -19;
commitid
: qNZkEhEejAdtaRlW;
Introduce an helper function to extract endpoint's max burst value.

Use this helper to calculate the Transfer Burst Count (TBC) and Transfer
Last Burst Packet Count (TLBPC) required for isochronous support.

Note that SS companion descriptors are still not read.

While here print the ETE and IST values in debug mode.
----------------------------

Marcus

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

sc.dying
In reply to this post by Denis Lapshin-2
Hi,

On 2018/07/27 09:14, Denis wrote:

> Every time (after 2-3 minutes of work) ASIX Electronics USB-Ethernet
> device reports:
>
> axen0: usb errors on rx: IOERROR
> axen0: usb errors on rx: IOERROR
> axen0: usb errors on tx: IOERROR
> axen0: watchdog timeout
> axen0: usb errors on tx: IOERROR
>
> The device hangs and must be reattached to have it working again for 2-3
> minutes.

Do you want to try this patch?

-----
  - header: fix comments
  - header: fix unused L3 type mask definition
  - rxeof: Avoid allocating mbuf if checksum errors are detected.
  - rxeof: Avoid loop to extract packets if pkt_count is 0.
  - rxeof: Add more sanity checks.
  - rxeof: Increament if_ierror in some error paths.
  - qctrl: Apply queuing control parameters from FreeBSD axge(4).
  - qctrl: Set qctrl in miireg_statchg dynamically, not statically.
  - Use DMA buffer aligned at 64KB boundary to avoid xhci bug.


--- sys/dev/usb/if_axenreg.h Fri Sep 16 22:17:07 2016
+++ sys/dev/usb/if_axenreg.h Mon Jun 19 10:54:28 2017
@@ -26,8 +26,8 @@
   *                     |    |     ++-----L3_type (1:ipv4, 0/2:ipv6)
   *        pkt_len(13)  |    |     ||+ ++-L4_type(0: icmp, 1: UDP, 4: TCP)
   * |765|43210 76543210|7654 3210 7654 3210|
- *  ||+-crc_err              |+-L4_err |+-L4_CSUM_ERR
- *  |+-mii_err               +--L3_err +--L3_CSUM_ERR
+ *  ||+-crc_err               |+-L4_err |+-L4_CSUM_ERR
+ *  |+-mii_err                +--L3_err +--L3_CSUM_ERR
   *  +-drop_err
   *
   * ex) pkt_hdr 0x00680820
@@ -70,7 +70,7 @@
  #define   AXEN_RXHDR_L4_TYPE_TCP 0x4
 
  /* L3 packet type (2bit) */
-#define AXEN_RXHDR_L3_TYPE_MASK 0x00000600
+#define AXEN_RXHDR_L3_TYPE_MASK 0x00000060
  #define AXEN_RXHDR_L3_TYPE_OFFSET 5
  #define   AXEN_RXHDR_L3_TYPE_UNDEF 0x0
  #define   AXEN_RXHDR_L3_TYPE_IPV4 0x1
--- sys/dev/usb/if_axen.c.orig Tue Jun 12 15:36:59 2018
+++ sys/dev/usb/if_axen.c Sun Jul 29 01:53:43 2018
@@ -53,6 +53,7 @@
  #include <dev/usb/usbdi_util.h>
  #include <dev/usb/usbdivar.h>
  #include <dev/usb/usbdevs.h>
+#include <dev/usb/usb_mem.h>
 
  #include <dev/usb/if_axenreg.h>
 
@@ -121,6 +122,13 @@ void axen_unlock_mii(struct axen_softc *sc);
 
  void axen_ax88179_init(struct axen_softc *);
 
+struct axen_qctrl axen_bulk_size[] = {
+ { 7, 0x4f, 0x00, 0x12, 0xff },
+ { 7, 0x20, 0x03, 0x16, 0xff },
+ { 7, 0xae, 0x07, 0x18, 0xff },
+ { 7, 0xcc, 0x4c, 0x18, 0x08 }
+};
+
  /* Get exclusive access to the MII registers */
  void
  axen_lock_mii(struct axen_softc *sc)
@@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev)
  int err;
  uint16_t val;
  uWord wval;
+ uint8_t linkstat = 0;
+ int qctrl;
 
  ifp = GET_IFP(sc);
  if (mii == NULL || ifp == NULL ||
@@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev)
  return;
 
  val = 0;
- if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
  val |= AXEN_MEDIUM_FDX;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
+ val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
+ val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
+ }
 
- val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
- val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
+ val |= AXEN_MEDIUM_RECV_EN;
 
+ /* bulkin queue setting */
+ axen_lock_mii(sc);
+ axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat);
+ axen_unlock_mii(sc);
+
  switch (IFM_SUBTYPE(mii->mii_media_active)) {
  case IFM_1000_T:
  val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
+ if (linkstat & AXEN_USB_SS)
+ qctrl = 0;
+ else if (linkstat & AXEN_USB_HS)
+ qctrl = 1;
+ else
+ qctrl = 3;
  break;
  case IFM_100_TX:
  val |= AXEN_MEDIUM_PS;
+ if (linkstat & (AXEN_USB_SS | AXEN_USB_HS))
+ qctrl = 2;
+ else
+ qctrl = 3;
  break;
  case IFM_10_T:
- /* doesn't need to be handled */
+ default:
+ qctrl = 3;
  break;
  }
 
  DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
  USETW(wval, val);
  axen_lock_mii(sc);
+ axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
+    &axen_bulk_size[qctrl]);
  err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
  axen_unlock_mii(sc);
  if (err) {
@@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc)
  uWord wval;
  uByte val;
  u_int16_t ctl, temp;
- struct axen_qctrl qctrl;
 
  axen_lock_mii(sc);
 
@@ -471,27 +502,12 @@ axen_ax88179_init(struct axen_softc *sc)
  switch (val) {
  case AXEN_USB_FS:
  DPRINTF(("uplink: USB1.1\n"));
- qctrl.ctrl = 0x07;
- qctrl.timer_low = 0xcc;
- qctrl.timer_high= 0x4c;
- qctrl.bufsize = AXEN_BUFSZ_LS - 1;
- qctrl.ifg = 0x08;
  break;
  case AXEN_USB_HS:
  DPRINTF(("uplink: USB2.0\n"));
- qctrl.ctrl = 0x07;
- qctrl.timer_low = 0x02;
- qctrl.timer_high= 0xa0;
- qctrl.bufsize = AXEN_BUFSZ_HS - 1;
- qctrl.ifg = 0xff;
  break;
  case AXEN_USB_SS:
  DPRINTF(("uplink: USB3.0\n"));
- qctrl.ctrl = 0x07;
- qctrl.timer_low = 0x4f;
- qctrl.timer_high= 0x00;
- qctrl.bufsize = AXEN_BUFSZ_SS - 1;
- qctrl.ifg = 0xff;
  break;
  default:
  printf("%s: unknown uplink bus:0x%02x\n",
@@ -499,7 +515,6 @@ axen_ax88179_init(struct axen_softc *sc)
  axen_unlock_mii(sc);
  return;
  }
- axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
 
  /* Set MAC address. */
  axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
@@ -622,22 +637,8 @@ axen_attach(struct device *parent, struct device *self
 
  id = usbd_get_interface_descriptor(sc->axen_iface);
 
- /* decide on what our bufsize will be */
- switch (sc->axen_udev->speed) {
- case USB_SPEED_FULL:
-     sc->axen_bufsz = AXEN_BUFSZ_LS * 1024;
- break;
- case USB_SPEED_HIGH:
-     sc->axen_bufsz = AXEN_BUFSZ_HS * 1024;
- break;
- case USB_SPEED_SUPER:
-     sc->axen_bufsz = AXEN_BUFSZ_SS * 1024;
- break;
- default:
- printf("%s: not supported usb bus type", sc->axen_dev.dv_xname);
- return;
- }
-
+ sc->axen_bufsz = 64 * 1024;
+
  /* Find endpoints. */
  for (i = 0; i < id->bNumEndpoints; i++) {
  ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i);
@@ -710,7 +711,8 @@ axen_attach(struct device *parent, struct device *self
  mii->mii_flags = MIIF_AUTOTSLEEP;
 
  ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts);
- mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
+ mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
+    MIIF_DOPAUSE);
 
  if (LIST_FIRST(&mii->mii_phys) == NULL) {
  ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
@@ -808,6 +810,23 @@ axen_newbuf(void)
  return m;
  }
 
+static void *
+axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
+{
+ struct usbd_bus *bus = xfer->device->bus;
+ usbd_status err;
+
+#ifdef DIAGNOSTIC
+ if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
+ printf("axen_alloc_buffer: xfer already has a buffer\n");
+#endif
+ err = usb_allocmem(bus, size, 65536, &xfer->dmabuf);
+ if (err)
+ return (NULL);
+ xfer->rqflags |= URQ_DEV_DMABUF;
+ return (KERNADDR(&xfer->dmabuf, 0));
+}
+
  int
  axen_rx_list_init(struct axen_softc *sc)
  {
@@ -827,7 +846,7 @@ axen_rx_list_init(struct axen_softc *sc)
  c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
  if (c->axen_xfer == NULL)
  return ENOBUFS;
- c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
+ c->axen_buf = axen_alloc_buffer(c->axen_xfer,
     sc->axen_bufsz);
  if (c->axen_buf == NULL) {
  usbd_free_xfer(c->axen_xfer);
@@ -858,7 +877,7 @@ axen_tx_list_init(struct axen_softc *sc)
  c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
  if (c->axen_xfer == NULL)
  return ENOBUFS;
- c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
+ c->axen_buf = axen_alloc_buffer(c->axen_xfer,
     sc->axen_bufsz);
  if (c->axen_buf == NULL) {
  usbd_free_xfer(c->axen_xfer);
@@ -888,7 +907,6 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
  u_int32_t *hdr_p;
  u_int16_t hdr_offset, pkt_count;
  size_t pkt_len;
- size_t temp;
  int s;
 
  DPRINTFN(10,("%s: %s: enter\n", sc->axen_dev.dv_xname,__func__));
@@ -914,10 +932,19 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
  usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
 
  if (total_len < sizeof(pkt_hdr)) {
+ printf("%s: rxeof: too short transfer\n",
+    sc->axen_dev.dv_xname);
  ifp->if_ierrors++;
  goto done;
  }
 
+ if (total_len > sc->axen_bufsz) {
+ printf("%s: rxeof: too large transfer\n",
+    sc->axen_dev.dv_xname);
+ ifp->if_ierrors++;
+ goto done;
+ }
+
  /*
  * buffer map
  * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
@@ -928,16 +955,10 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
  hdr_offset = (u_int16_t)(rx_hdr >> 16);
  pkt_count  = (u_int16_t)(rx_hdr & 0xffff);
 
- if (total_len > sc->axen_bufsz) {
- printf("%s: rxeof: too large transfer\n",
-    sc->axen_dev.dv_xname);
- goto done;
- }
-
  /* sanity check */
  if (hdr_offset > total_len) {
- ifp->if_ierrors++;
  usbd_delay_ms(sc->axen_udev, 100);
+ ifp->if_ierrors++;
  goto done;
  }
 
@@ -954,11 +975,14 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
  if (pkt_count > AXEN_MAX_PACKED_PACKET) {
  DPRINTF(("Too many packets (%d) in a transaction, discard.\n",
     pkt_count));
+ ifp->if_ierrors++;
  goto done;
  }
  #endif
 
- do {
+ for (; pkt_count > 0; pkt_count--) {
+ uint16_t csum_flags = 0;
+
  if ((buf[0] != 0xee) || (buf[1] != 0xee)){
  printf("%s: invalid buffer(pkt#%d), continue\n",
     sc->axen_dev.dv_xname, pkt_count);
@@ -972,34 +996,31 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
  DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
    pkt_count, pkt_hdr, pkt_len));
 
+ if (pkt_len > MCLBYTES || pkt_len < ETHER_MIN_LEN) {
+ printf("%s: invalid pkt_len %zu\n",
+    sc->axen_dev.dv_xname,pkt_len);
+ ifp->if_ierrors++;
+ goto nextpkt;
+ }
+
  if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) ||
         (pkt_hdr & AXEN_RXHDR_DROP_ERR)) {
-     ifp->if_ierrors++;
  /* move to next pkt header */
  DPRINTF(("crc err(pkt#%d)\n", pkt_count));
+     ifp->if_ierrors++;
  goto nextpkt;
  }
 
- /* process each packet */
- /* allocate mbuf */
- m = axen_newbuf();
- if (m == NULL) {
- ifp->if_ierrors++;
- goto nextpkt;
- }
-
- /* skip pseudo header (2byte) and trailer padding (4Byte) */
- m->m_pkthdr.len = m->m_len = pkt_len - 6;
-
  #ifdef AXEN_TOE
  /* cheksum err */
  if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) ||
     (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) {
  printf("%s: checksum err (pkt#%d)\n",
     sc->axen_dev.dv_xname, pkt_count);
+ ifp->if_ierrors++;
  goto nextpkt;
  } else {
- m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
+ csum_flags |= M_IPV4_CSUM_IN_OK;
  }
 
  int l4_type;
@@ -1008,12 +1029,23 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
 
  if ((l4_type == AXEN_RXHDR_L4_TYPE_TCP) ||
     (l4_type == AXEN_RXHDR_L4_TYPE_UDP))
- m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
-    M_UDP_CSUM_IN_OK;
+ csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
  #endif
 
- memcpy(mtod(m, char *), buf + 2, pkt_len - 6);
+ /* process each packet */
+ /* allocate mbuf */
+ m = axen_newbuf();
+ if (m == NULL) {
+ ifp->if_ierrors++;
+ goto nextpkt;
+ }
 
+ /* skip pseudo header (2byte) and trailer padding (4Byte) */
+ m->m_pkthdr.len = m->m_len = pkt_len - 6;
+ m->m_pkthdr.csum_flags |= csum_flags;
+
+ memcpy(mtod(m, char *), buf + 2, m->m_len);
+
  ml_enqueue(&ml, m);
 
  nextpkt:
@@ -1022,11 +1054,9 @@ nextpkt:
  * as each packet will be aligned 8byte boundary,
  * need to fix up the start point of the buffer.
  */
- temp = ((pkt_len + 7) & 0xfff8);
- buf = buf + temp;
+ buf += roundup(pkt_len, 8);
  hdr_p++;
- pkt_count--;
- } while( pkt_count > 0);
+ }
 
  done:
  /* push the packet up */

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Denis Lapshin-2
Hello,

Thank you for patch. I can apply it a bit later in the trip currently.



On 7/30/2018 3:11 AM, [hidden email] wrote:

> Hi,
>
> On 2018/07/27 09:14, Denis wrote:
>> Every time (after 2-3 minutes of work) ASIX Electronics USB-Ethernet
>> device reports:
>>
>> axen0: usb errors on rx: IOERROR
>> axen0: usb errors on rx: IOERROR
>> axen0: usb errors on tx: IOERROR
>> axen0: watchdog timeout
>> axen0: usb errors on tx: IOERROR
>>
>> The device hangs and must be reattached to have it working again for 2-3
>> minutes.
>
> Do you want to try this patch?
>
> -----
>  - header: fix comments
>  - header: fix unused L3 type mask definition
>  - rxeof: Avoid allocating mbuf if checksum errors are detected.
>  - rxeof: Avoid loop to extract packets if pkt_count is 0.
>  - rxeof: Add more sanity checks.
>  - rxeof: Increament if_ierror in some error paths.
>  - qctrl: Apply queuing control parameters from FreeBSD axge(4).
>  - qctrl: Set qctrl in miireg_statchg dynamically, not statically.
>  - Use DMA buffer aligned at 64KB boundary to avoid xhci bug.
>
>
> --- sys/dev/usb/if_axenreg.h    Fri Sep 16 22:17:07 2016
> +++ sys/dev/usb/if_axenreg.h    Mon Jun 19 10:54:28 2017
> @@ -26,8 +26,8 @@
>   *                     |    |     ++-----L3_type (1:ipv4, 0/2:ipv6)
>   *        pkt_len(13)  |    |     ||+ ++-L4_type(0: icmp, 1: UDP, 4: TCP)
>   * |765|43210 76543210|7654 3210 7654 3210|
> - *  ||+-crc_err              |+-L4_err |+-L4_CSUM_ERR
> - *  |+-mii_err               +--L3_err +--L3_CSUM_ERR
> + *  ||+-crc_err               |+-L4_err |+-L4_CSUM_ERR
> + *  |+-mii_err                +--L3_err +--L3_CSUM_ERR
>   *  +-drop_err
>   *
>   * ex) pkt_hdr 0x00680820
> @@ -70,7 +70,7 @@
>  #define   AXEN_RXHDR_L4_TYPE_TCP    0x4
>  
>  /* L3 packet type (2bit) */
> -#define AXEN_RXHDR_L3_TYPE_MASK    0x00000600
> +#define AXEN_RXHDR_L3_TYPE_MASK    0x00000060
>  #define AXEN_RXHDR_L3_TYPE_OFFSET    5
>  #define   AXEN_RXHDR_L3_TYPE_UNDEF    0x0
>  #define   AXEN_RXHDR_L3_TYPE_IPV4    0x1
> --- sys/dev/usb/if_axen.c.orig    Tue Jun 12 15:36:59 2018
> +++ sys/dev/usb/if_axen.c    Sun Jul 29 01:53:43 2018
> @@ -53,6 +53,7 @@
>  #include <dev/usb/usbdi_util.h>
>  #include <dev/usb/usbdivar.h>
>  #include <dev/usb/usbdevs.h>
> +#include <dev/usb/usb_mem.h>
>  
>  #include <dev/usb/if_axenreg.h>
>  
> @@ -121,6 +122,13 @@ void    axen_unlock_mii(struct axen_softc *sc);
>  
>  void    axen_ax88179_init(struct axen_softc *);
>  
> +struct axen_qctrl axen_bulk_size[] = {
> +    { 7, 0x4f, 0x00, 0x12, 0xff },
> +    { 7, 0x20, 0x03, 0x16, 0xff },
> +    { 7, 0xae, 0x07, 0x18, 0xff },
> +    { 7, 0xcc, 0x4c, 0x18, 0x08 }
> +};
> +
>  /* Get exclusive access to the MII registers */
>  void
>  axen_lock_mii(struct axen_softc *sc)
> @@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev)
>      int            err;
>      uint16_t        val;
>      uWord            wval;
> +    uint8_t            linkstat = 0;
> +    int            qctrl;
>  
>      ifp = GET_IFP(sc);
>      if (mii == NULL || ifp == NULL ||
> @@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev)
>          return;
>  
>      val = 0;
> -    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
> +    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
>          val |= AXEN_MEDIUM_FDX;
> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
> +            val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
> +            val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
> +    }
>  
> -    val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
> -    val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
> +    val |= AXEN_MEDIUM_RECV_EN;
>  
> +    /* bulkin queue setting */
> +    axen_lock_mii(sc);
> +    axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat);
> +    axen_unlock_mii(sc);
> +
>      switch (IFM_SUBTYPE(mii->mii_media_active)) {
>      case IFM_1000_T:
>          val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
> +        if (linkstat & AXEN_USB_SS)
> +            qctrl = 0;
> +        else if (linkstat & AXEN_USB_HS)
> +            qctrl = 1;
> +        else
> +            qctrl = 3;
>          break;
>      case IFM_100_TX:
>          val |= AXEN_MEDIUM_PS;
> +        if (linkstat & (AXEN_USB_SS | AXEN_USB_HS))
> +            qctrl = 2;
> +        else
> +            qctrl = 3;
>          break;
>      case IFM_10_T:
> -        /* doesn't need to be handled */
> +    default:
> +        qctrl = 3;
>          break;
>      }
>  
>      DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
>      USETW(wval, val);
>      axen_lock_mii(sc);
> +    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
> +        &axen_bulk_size[qctrl]);
>      err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
>      axen_unlock_mii(sc);
>      if (err) {
> @@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc)
>      uWord        wval;
>      uByte        val;
>      u_int16_t     ctl, temp;
> -    struct axen_qctrl qctrl;
>  
>      axen_lock_mii(sc);
>  
> @@ -471,27 +502,12 @@ axen_ax88179_init(struct axen_softc *sc)
>      switch (val) {
>      case AXEN_USB_FS:
>          DPRINTF(("uplink: USB1.1\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0xcc;
> -        qctrl.timer_high= 0x4c;
> -        qctrl.bufsize    = AXEN_BUFSZ_LS - 1;
> -        qctrl.ifg    = 0x08;
>          break;
>      case AXEN_USB_HS:
>          DPRINTF(("uplink: USB2.0\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0x02;
> -        qctrl.timer_high= 0xa0;
> -        qctrl.bufsize    = AXEN_BUFSZ_HS - 1;
> -        qctrl.ifg    = 0xff;
>          break;
>      case AXEN_USB_SS:
>          DPRINTF(("uplink: USB3.0\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0x4f;
> -        qctrl.timer_high= 0x00;
> -        qctrl.bufsize    = AXEN_BUFSZ_SS - 1;
> -        qctrl.ifg    = 0xff;
>          break;
>      default:
>          printf("%s: unknown uplink bus:0x%02x\n",
> @@ -499,7 +515,6 @@ axen_ax88179_init(struct axen_softc *sc)
>          axen_unlock_mii(sc);
>          return;
>      }
> -    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
>  
>      /* Set MAC address. */
>      axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
> @@ -622,22 +637,8 @@ axen_attach(struct device *parent, struct device *self
>  
>      id = usbd_get_interface_descriptor(sc->axen_iface);
>  
> -    /* decide on what our bufsize will be */
> -    switch (sc->axen_udev->speed) {
> -    case USB_SPEED_FULL:
> -            sc->axen_bufsz = AXEN_BUFSZ_LS * 1024;
> -        break;
> -    case USB_SPEED_HIGH:
> -            sc->axen_bufsz = AXEN_BUFSZ_HS * 1024;
> -        break;
> -    case USB_SPEED_SUPER:
> -            sc->axen_bufsz = AXEN_BUFSZ_SS * 1024;
> -        break;
> -    default:
> -        printf("%s: not supported usb bus type", sc->axen_dev.dv_xname);
> -        return;
> -    }
> -       
> +    sc->axen_bufsz = 64 * 1024;
> +
>      /* Find endpoints. */
>      for (i = 0; i < id->bNumEndpoints; i++) {
>          ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i);
> @@ -710,7 +711,8 @@ axen_attach(struct device *parent, struct device *self
>      mii->mii_flags = MIIF_AUTOTSLEEP;
>  
>      ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts);
> -    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
> +    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
> +        MIIF_DOPAUSE);
>  
>      if (LIST_FIRST(&mii->mii_phys) == NULL) {
>          ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
> @@ -808,6 +810,23 @@ axen_newbuf(void)
>      return m;
>  }
>  
> +static void *
> +axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
> +{
> +    struct usbd_bus *bus = xfer->device->bus;
> +    usbd_status err;
> +
> +#ifdef DIAGNOSTIC
> +    if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
> +        printf("axen_alloc_buffer: xfer already has a buffer\n");
> +#endif
> +    err = usb_allocmem(bus, size, 65536, &xfer->dmabuf);
> +    if (err)
> +        return (NULL);
> +    xfer->rqflags |= URQ_DEV_DMABUF;
> +    return (KERNADDR(&xfer->dmabuf, 0));
> +}
> +
>  int
>  axen_rx_list_init(struct axen_softc *sc)
>  {
> @@ -827,7 +846,7 @@ axen_rx_list_init(struct axen_softc *sc)
>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>              if (c->axen_xfer == NULL)
>                  return ENOBUFS;
> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>                  sc->axen_bufsz);
>              if (c->axen_buf == NULL) {
>                  usbd_free_xfer(c->axen_xfer);
> @@ -858,7 +877,7 @@ axen_tx_list_init(struct axen_softc *sc)
>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>              if (c->axen_xfer == NULL)
>                  return ENOBUFS;
> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>                  sc->axen_bufsz);
>              if (c->axen_buf == NULL) {
>                  usbd_free_xfer(c->axen_xfer);
> @@ -888,7 +907,6 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>      u_int32_t        *hdr_p;
>      u_int16_t        hdr_offset, pkt_count;
>      size_t            pkt_len;
> -    size_t            temp;
>      int            s;
>  
>      DPRINTFN(10,("%s: %s: enter\n", sc->axen_dev.dv_xname,__func__));
> @@ -914,10 +932,19 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
>  
>      if (total_len < sizeof(pkt_hdr)) {
> +        printf("%s: rxeof: too short transfer\n",
> +            sc->axen_dev.dv_xname);
>          ifp->if_ierrors++;
>          goto done;
>      }
>  
> +    if (total_len > sc->axen_bufsz) {
> +        printf("%s: rxeof: too large transfer\n",
> +            sc->axen_dev.dv_xname);
> +        ifp->if_ierrors++;
> +        goto done;
> +    }
> +
>      /*
>       * buffer map
>       * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
> @@ -928,16 +955,10 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      hdr_offset = (u_int16_t)(rx_hdr >> 16);
>      pkt_count  = (u_int16_t)(rx_hdr & 0xffff);
>  
> -    if (total_len > sc->axen_bufsz) {
> -        printf("%s: rxeof: too large transfer\n",
> -            sc->axen_dev.dv_xname);
> -        goto done;
> -    }
> -
>      /* sanity check */
>      if (hdr_offset > total_len) {
> -        ifp->if_ierrors++;
>          usbd_delay_ms(sc->axen_udev, 100);
> +        ifp->if_ierrors++;
>          goto done;
>      }
>  
> @@ -954,11 +975,14 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      if (pkt_count > AXEN_MAX_PACKED_PACKET) {
>          DPRINTF(("Too many packets (%d) in a transaction, discard.\n",
>              pkt_count));
> +        ifp->if_ierrors++;
>          goto done;
>      }
>  #endif
>  
> -    do {
> +    for (; pkt_count > 0; pkt_count--) {
> +        uint16_t csum_flags = 0;
> +
>          if ((buf[0] != 0xee) || (buf[1] != 0xee)){
>              printf("%s: invalid buffer(pkt#%d), continue\n",
>                  sc->axen_dev.dv_xname, pkt_count);
> @@ -972,34 +996,31 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>          DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
>             pkt_count, pkt_hdr, pkt_len));
>  
> +        if (pkt_len > MCLBYTES || pkt_len < ETHER_MIN_LEN) {
> +            printf("%s: invalid pkt_len %zu\n",
> +                sc->axen_dev.dv_xname,pkt_len);
> +            ifp->if_ierrors++;
> +            goto nextpkt;
> +        }
> +
>          if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) ||
>                  (pkt_hdr & AXEN_RXHDR_DROP_ERR)) {
> -                ifp->if_ierrors++;
>              /* move to next pkt header */
>              DPRINTF(("crc err(pkt#%d)\n", pkt_count));
> +                ifp->if_ierrors++;
>              goto nextpkt;
>          }
>  
> -        /* process each packet */
> -        /* allocate mbuf */
> -        m = axen_newbuf();
> -        if (m == NULL) {
> -            ifp->if_ierrors++;
> -            goto nextpkt;
> -        }
> -
> -        /* skip pseudo header (2byte) and trailer padding (4Byte) */
> -        m->m_pkthdr.len = m->m_len = pkt_len - 6;
> -
>  #ifdef AXEN_TOE
>          /* cheksum err */
>          if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) ||
>              (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) {
>              printf("%s: checksum err (pkt#%d)\n",
>                  sc->axen_dev.dv_xname, pkt_count);
> +            ifp->if_ierrors++;
>              goto nextpkt;
>          } else {
> -            m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
> +            csum_flags |= M_IPV4_CSUM_IN_OK;
>          }
>  
>          int l4_type;
> @@ -1008,12 +1029,23 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>  
>          if ((l4_type == AXEN_RXHDR_L4_TYPE_TCP) ||
>              (l4_type == AXEN_RXHDR_L4_TYPE_UDP))
> -            m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
> -                M_UDP_CSUM_IN_OK;
> +            csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
>  #endif
>  
> -        memcpy(mtod(m, char *), buf + 2, pkt_len - 6);
> +        /* process each packet */
> +        /* allocate mbuf */
> +        m = axen_newbuf();
> +        if (m == NULL) {
> +            ifp->if_ierrors++;
> +            goto nextpkt;
> +        }
>  
> +        /* skip pseudo header (2byte) and trailer padding (4Byte) */
> +        m->m_pkthdr.len = m->m_len = pkt_len - 6;
> +        m->m_pkthdr.csum_flags |= csum_flags;
> +
> +        memcpy(mtod(m, char *), buf + 2, m->m_len);
> +
>          ml_enqueue(&ml, m);
>  
>  nextpkt:
> @@ -1022,11 +1054,9 @@ nextpkt:
>           * as each packet will be aligned 8byte boundary,
>           * need to fix up the start point of the buffer.
>           */
> -        temp = ((pkt_len + 7) & 0xfff8);
> -        buf = buf + temp;
> +        buf += roundup(pkt_len, 8);
>          hdr_p++;
> -        pkt_count--;
> -    } while( pkt_count > 0);
> +    }
>  
>  done:
>      /* push the packet up */
>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

sc.dying
In reply to this post by sc.dying
On Mon, Jul 30, 2018 at 12:11 AM,  <[hidden email]> wrote:
>  - Use DMA buffer aligned at 64KB boundary to avoid xhci bug.

In function xhci_event_xfer() xfer->actlen should be calculated
from sum of transferred TRB length, not xfer->length - remain,
when the transfer is splitted to multiple TRBs.

The xhci driver may split a transfer into multiple TRBs if the DMA
buffer is larger than 64kB or crosses 64kB boundary.
For the example of unpatched axen, 24kB buffer of SS Bulk-In transfer
might be spliited like following.

 TRB #0 bulk-in len 0x1000 paddr 0xda3ff000 (CHAIN)
 TRB #1 bulk-in len 0x5000 paddr 0xda400000 (IOC)

On the completion of each TRB xhci_event_xfer() calculates actlen.
The size of inbound packet is usually less than given buffer size,
TRB #0 ends up with SHORT_XFER and TRB #1 ends up with SUCCESS.

 bulk-in idx 2 last 3 len 0x6000 remain 0xf98 (for TRB #0)
 bulk-in idx 3 last 3 len 0x6000 remain 0x5000 (for TRB #1)

For TRB #0, the actlen is xfer->length - remain = 0x6000 - 0xf98 = 0x5068.
This value is stored in xfer->actlen.
The actlen of #1 is 0x6000 - 0x5000 = 0x1000, but xfer->actlen is not zero
so the actlen of #1 is ignored.
Thus the actlen of this transfer is determined to be 0x5068, however,
it is actually 0x68.

When axen works on USB2 the unpatched axen uses 16kB buffer.
It's smaller than 24kB of SS, less possible the buffer crosses 64kB boundary,
you might not meet the problem.

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Denis Lapshin-2
In reply to this post by sc.dying
Can not patch original files in /usr/src/sys/dev/usb/ despite that
if_axenreg.h and if_axen.c files fetched directly from current CVS repo.

# patch -p0 < axen.patch
Hmm.. Lookd like a unified diff to me...
The text leading up to this was:
-------------------------
|--- sys/dev/usb/if_axenreg.h Fri Sep 16 22:17:07 2016
|+++ sys/dev/usb/if_axenreg.h Mon Jun 19 10:54:28 2017
-------------------------
Patching file sys/dev/usb/if_axenreg.h using Plan A...
Hunk #1 succeeded at 26.
Hunk #2 failed at 70.
1 out of 2 hunks failed--saving rejects to sys/dev/usb/if_axenreg.h.rej
Hmm... The next patch look like a unified diff to me...
The text leading up to this was:
-------------------------
|--- sys/dev/usb/if_axen.c.orig Tue Jun 12 15:36:59 2018
|+++ sys/dev/usb/if_axen.c Sun Jul 29 01:53:43 2018
-------------------------
Patching file sys/dev/usb/if_axen.c using Plan A...
Hunk #1 succeeded at 53.
Hunk #2 succeeded at 122 with fuzz 2.
Hunk #3 failed at 246.
Hunk #4 failed at 275.
Hunk #5 failed at 440.
Hunk #6 failed at 502.
Hunk #7 failed at 515.
Hunk #8 failed at 637.
Hunk #9 failed at 711.
Hunk #10 succeeded at 810 with fuzz 1.
Hunk #11 failed at 846.
Hunk #12 failed at 877.
Hunk #13 failed at 907.
Hunk #14 failed at 932.
Hunk #15 failed at 955.
Hunk #16 failed at 975.
Hunk #17 failed at 996.
Hunk #18 failed at 1029.
Hunk #19 failed at 1054.
16 out of 19 hunks failed--saving rejects to sys/dev/usb/if_axen.c.rej
done

On 7/30/2018 3:11 AM, [hidden email] wrote:

> Hi,
>
> On 2018/07/27 09:14, Denis wrote:
>> Every time (after 2-3 minutes of work) ASIX Electronics USB-Ethernet
>> device reports:
>>
>> axen0: usb errors on rx: IOERROR
>> axen0: usb errors on rx: IOERROR
>> axen0: usb errors on tx: IOERROR
>> axen0: watchdog timeout
>> axen0: usb errors on tx: IOERROR
>>
>> The device hangs and must be reattached to have it working again for 2-3
>> minutes.
>
> Do you want to try this patch?
>
> -----
>  - header: fix comments
>  - header: fix unused L3 type mask definition
>  - rxeof: Avoid allocating mbuf if checksum errors are detected.
>  - rxeof: Avoid loop to extract packets if pkt_count is 0.
>  - rxeof: Add more sanity checks.
>  - rxeof: Increament if_ierror in some error paths.
>  - qctrl: Apply queuing control parameters from FreeBSD axge(4).
>  - qctrl: Set qctrl in miireg_statchg dynamically, not statically.
>  - Use DMA buffer aligned at 64KB boundary to avoid xhci bug.
>
>
> --- sys/dev/usb/if_axenreg.h    Fri Sep 16 22:17:07 2016
> +++ sys/dev/usb/if_axenreg.h    Mon Jun 19 10:54:28 2017
> @@ -26,8 +26,8 @@
>   *                     |    |     ++-----L3_type (1:ipv4, 0/2:ipv6)
>   *        pkt_len(13)  |    |     ||+ ++-L4_type(0: icmp, 1: UDP, 4: TCP)
>   * |765|43210 76543210|7654 3210 7654 3210|
> - *  ||+-crc_err              |+-L4_err |+-L4_CSUM_ERR
> - *  |+-mii_err               +--L3_err +--L3_CSUM_ERR
> + *  ||+-crc_err               |+-L4_err |+-L4_CSUM_ERR
> + *  |+-mii_err                +--L3_err +--L3_CSUM_ERR
>   *  +-drop_err
>   *
>   * ex) pkt_hdr 0x00680820
> @@ -70,7 +70,7 @@
>  #define   AXEN_RXHDR_L4_TYPE_TCP    0x4
>  
>  /* L3 packet type (2bit) */
> -#define AXEN_RXHDR_L3_TYPE_MASK    0x00000600
> +#define AXEN_RXHDR_L3_TYPE_MASK    0x00000060
>  #define AXEN_RXHDR_L3_TYPE_OFFSET    5
>  #define   AXEN_RXHDR_L3_TYPE_UNDEF    0x0
>  #define   AXEN_RXHDR_L3_TYPE_IPV4    0x1
> --- sys/dev/usb/if_axen.c.orig    Tue Jun 12 15:36:59 2018
> +++ sys/dev/usb/if_axen.c    Sun Jul 29 01:53:43 2018
> @@ -53,6 +53,7 @@
>  #include <dev/usb/usbdi_util.h>
>  #include <dev/usb/usbdivar.h>
>  #include <dev/usb/usbdevs.h>
> +#include <dev/usb/usb_mem.h>
>  
>  #include <dev/usb/if_axenreg.h>
>  
> @@ -121,6 +122,13 @@ void    axen_unlock_mii(struct axen_softc *sc);
>  
>  void    axen_ax88179_init(struct axen_softc *);
>  
> +struct axen_qctrl axen_bulk_size[] = {
> +    { 7, 0x4f, 0x00, 0x12, 0xff },
> +    { 7, 0x20, 0x03, 0x16, 0xff },
> +    { 7, 0xae, 0x07, 0x18, 0xff },
> +    { 7, 0xcc, 0x4c, 0x18, 0x08 }
> +};
> +
>  /* Get exclusive access to the MII registers */
>  void
>  axen_lock_mii(struct axen_softc *sc)
> @@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev)
>      int            err;
>      uint16_t        val;
>      uWord            wval;
> +    uint8_t            linkstat = 0;
> +    int            qctrl;
>  
>      ifp = GET_IFP(sc);
>      if (mii == NULL || ifp == NULL ||
> @@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev)
>          return;
>  
>      val = 0;
> -    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
> +    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
>          val |= AXEN_MEDIUM_FDX;
> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
> +            val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
> +            val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
> +    }
>  
> -    val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
> -    val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
> +    val |= AXEN_MEDIUM_RECV_EN;
>  
> +    /* bulkin queue setting */
> +    axen_lock_mii(sc);
> +    axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat);
> +    axen_unlock_mii(sc);
> +
>      switch (IFM_SUBTYPE(mii->mii_media_active)) {
>      case IFM_1000_T:
>          val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
> +        if (linkstat & AXEN_USB_SS)
> +            qctrl = 0;
> +        else if (linkstat & AXEN_USB_HS)
> +            qctrl = 1;
> +        else
> +            qctrl = 3;
>          break;
>      case IFM_100_TX:
>          val |= AXEN_MEDIUM_PS;
> +        if (linkstat & (AXEN_USB_SS | AXEN_USB_HS))
> +            qctrl = 2;
> +        else
> +            qctrl = 3;
>          break;
>      case IFM_10_T:
> -        /* doesn't need to be handled */
> +    default:
> +        qctrl = 3;
>          break;
>      }
>  
>      DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
>      USETW(wval, val);
>      axen_lock_mii(sc);
> +    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
> +        &axen_bulk_size[qctrl]);
>      err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
>      axen_unlock_mii(sc);
>      if (err) {
> @@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc)
>      uWord        wval;
>      uByte        val;
>      u_int16_t     ctl, temp;
> -    struct axen_qctrl qctrl;
>  
>      axen_lock_mii(sc);
>  
> @@ -471,27 +502,12 @@ axen_ax88179_init(struct axen_softc *sc)
>      switch (val) {
>      case AXEN_USB_FS:
>          DPRINTF(("uplink: USB1.1\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0xcc;
> -        qctrl.timer_high= 0x4c;
> -        qctrl.bufsize    = AXEN_BUFSZ_LS - 1;
> -        qctrl.ifg    = 0x08;
>          break;
>      case AXEN_USB_HS:
>          DPRINTF(("uplink: USB2.0\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0x02;
> -        qctrl.timer_high= 0xa0;
> -        qctrl.bufsize    = AXEN_BUFSZ_HS - 1;
> -        qctrl.ifg    = 0xff;
>          break;
>      case AXEN_USB_SS:
>          DPRINTF(("uplink: USB3.0\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0x4f;
> -        qctrl.timer_high= 0x00;
> -        qctrl.bufsize    = AXEN_BUFSZ_SS - 1;
> -        qctrl.ifg    = 0xff;
>          break;
>      default:
>          printf("%s: unknown uplink bus:0x%02x\n",
> @@ -499,7 +515,6 @@ axen_ax88179_init(struct axen_softc *sc)
>          axen_unlock_mii(sc);
>          return;
>      }
> -    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
>  
>      /* Set MAC address. */
>      axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
> @@ -622,22 +637,8 @@ axen_attach(struct device *parent, struct device *self
>  
>      id = usbd_get_interface_descriptor(sc->axen_iface);
>  
> -    /* decide on what our bufsize will be */
> -    switch (sc->axen_udev->speed) {
> -    case USB_SPEED_FULL:
> -            sc->axen_bufsz = AXEN_BUFSZ_LS * 1024;
> -        break;
> -    case USB_SPEED_HIGH:
> -            sc->axen_bufsz = AXEN_BUFSZ_HS * 1024;
> -        break;
> -    case USB_SPEED_SUPER:
> -            sc->axen_bufsz = AXEN_BUFSZ_SS * 1024;
> -        break;
> -    default:
> -        printf("%s: not supported usb bus type", sc->axen_dev.dv_xname);
> -        return;
> -    }
> -       
> +    sc->axen_bufsz = 64 * 1024;
> +
>      /* Find endpoints. */
>      for (i = 0; i < id->bNumEndpoints; i++) {
>          ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i);
> @@ -710,7 +711,8 @@ axen_attach(struct device *parent, struct device *self
>      mii->mii_flags = MIIF_AUTOTSLEEP;
>  
>      ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts);
> -    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
> +    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
> +        MIIF_DOPAUSE);
>  
>      if (LIST_FIRST(&mii->mii_phys) == NULL) {
>          ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
> @@ -808,6 +810,23 @@ axen_newbuf(void)
>      return m;
>  }
>  
> +static void *
> +axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
> +{
> +    struct usbd_bus *bus = xfer->device->bus;
> +    usbd_status err;
> +
> +#ifdef DIAGNOSTIC
> +    if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
> +        printf("axen_alloc_buffer: xfer already has a buffer\n");
> +#endif
> +    err = usb_allocmem(bus, size, 65536, &xfer->dmabuf);
> +    if (err)
> +        return (NULL);
> +    xfer->rqflags |= URQ_DEV_DMABUF;
> +    return (KERNADDR(&xfer->dmabuf, 0));
> +}
> +
>  int
>  axen_rx_list_init(struct axen_softc *sc)
>  {
> @@ -827,7 +846,7 @@ axen_rx_list_init(struct axen_softc *sc)
>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>              if (c->axen_xfer == NULL)
>                  return ENOBUFS;
> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>                  sc->axen_bufsz);
>              if (c->axen_buf == NULL) {
>                  usbd_free_xfer(c->axen_xfer);
> @@ -858,7 +877,7 @@ axen_tx_list_init(struct axen_softc *sc)
>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>              if (c->axen_xfer == NULL)
>                  return ENOBUFS;
> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>                  sc->axen_bufsz);
>              if (c->axen_buf == NULL) {
>                  usbd_free_xfer(c->axen_xfer);
> @@ -888,7 +907,6 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>      u_int32_t        *hdr_p;
>      u_int16_t        hdr_offset, pkt_count;
>      size_t            pkt_len;
> -    size_t            temp;
>      int            s;
>  
>      DPRINTFN(10,("%s: %s: enter\n", sc->axen_dev.dv_xname,__func__));
> @@ -914,10 +932,19 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
>  
>      if (total_len < sizeof(pkt_hdr)) {
> +        printf("%s: rxeof: too short transfer\n",
> +            sc->axen_dev.dv_xname);
>          ifp->if_ierrors++;
>          goto done;
>      }
>  
> +    if (total_len > sc->axen_bufsz) {
> +        printf("%s: rxeof: too large transfer\n",
> +            sc->axen_dev.dv_xname);
> +        ifp->if_ierrors++;
> +        goto done;
> +    }
> +
>      /*
>       * buffer map
>       * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
> @@ -928,16 +955,10 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      hdr_offset = (u_int16_t)(rx_hdr >> 16);
>      pkt_count  = (u_int16_t)(rx_hdr & 0xffff);
>  
> -    if (total_len > sc->axen_bufsz) {
> -        printf("%s: rxeof: too large transfer\n",
> -            sc->axen_dev.dv_xname);
> -        goto done;
> -    }
> -
>      /* sanity check */
>      if (hdr_offset > total_len) {
> -        ifp->if_ierrors++;
>          usbd_delay_ms(sc->axen_udev, 100);
> +        ifp->if_ierrors++;
>          goto done;
>      }
>  
> @@ -954,11 +975,14 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      if (pkt_count > AXEN_MAX_PACKED_PACKET) {
>          DPRINTF(("Too many packets (%d) in a transaction, discard.\n",
>              pkt_count));
> +        ifp->if_ierrors++;
>          goto done;
>      }
>  #endif
>  
> -    do {
> +    for (; pkt_count > 0; pkt_count--) {
> +        uint16_t csum_flags = 0;
> +
>          if ((buf[0] != 0xee) || (buf[1] != 0xee)){
>              printf("%s: invalid buffer(pkt#%d), continue\n",
>                  sc->axen_dev.dv_xname, pkt_count);
> @@ -972,34 +996,31 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>          DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
>             pkt_count, pkt_hdr, pkt_len));
>  
> +        if (pkt_len > MCLBYTES || pkt_len < ETHER_MIN_LEN) {
> +            printf("%s: invalid pkt_len %zu\n",
> +                sc->axen_dev.dv_xname,pkt_len);
> +            ifp->if_ierrors++;
> +            goto nextpkt;
> +        }
> +
>          if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) ||
>                  (pkt_hdr & AXEN_RXHDR_DROP_ERR)) {
> -                ifp->if_ierrors++;
>              /* move to next pkt header */
>              DPRINTF(("crc err(pkt#%d)\n", pkt_count));
> +                ifp->if_ierrors++;
>              goto nextpkt;
>          }
>  
> -        /* process each packet */
> -        /* allocate mbuf */
> -        m = axen_newbuf();
> -        if (m == NULL) {
> -            ifp->if_ierrors++;
> -            goto nextpkt;
> -        }
> -
> -        /* skip pseudo header (2byte) and trailer padding (4Byte) */
> -        m->m_pkthdr.len = m->m_len = pkt_len - 6;
> -
>  #ifdef AXEN_TOE
>          /* cheksum err */
>          if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) ||
>              (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) {
>              printf("%s: checksum err (pkt#%d)\n",
>                  sc->axen_dev.dv_xname, pkt_count);
> +            ifp->if_ierrors++;
>              goto nextpkt;
>          } else {
> -            m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
> +            csum_flags |= M_IPV4_CSUM_IN_OK;
>          }
>  
>          int l4_type;
> @@ -1008,12 +1029,23 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>  
>          if ((l4_type == AXEN_RXHDR_L4_TYPE_TCP) ||
>              (l4_type == AXEN_RXHDR_L4_TYPE_UDP))
> -            m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
> -                M_UDP_CSUM_IN_OK;
> +            csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
>  #endif
>  
> -        memcpy(mtod(m, char *), buf + 2, pkt_len - 6);
> +        /* process each packet */
> +        /* allocate mbuf */
> +        m = axen_newbuf();
> +        if (m == NULL) {
> +            ifp->if_ierrors++;
> +            goto nextpkt;
> +        }
>  
> +        /* skip pseudo header (2byte) and trailer padding (4Byte) */
> +        m->m_pkthdr.len = m->m_len = pkt_len - 6;
> +        m->m_pkthdr.csum_flags |= csum_flags;
> +
> +        memcpy(mtod(m, char *), buf + 2, m->m_len);
> +
>          ml_enqueue(&ml, m);
>  
>  nextpkt:
> @@ -1022,11 +1054,9 @@ nextpkt:
>           * as each packet will be aligned 8byte boundary,
>           * need to fix up the start point of the buffer.
>           */
> -        temp = ((pkt_len + 7) & 0xfff8);
> -        buf = buf + temp;
> +        buf += roundup(pkt_len, 8);
>          hdr_p++;
> -        pkt_count--;
> -    } while( pkt_count > 0);
> +    }
>  
>  done:
>      /* push the packet up */
>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

sc.dying
Hi,

On 2018/08/05 15:31, Denis wrote:
> Can not patch original files in /usr/src/sys/dev/usb/ despite that
> if_axenreg.h and if_axen.c files fetched directly from current CVS repo.

Previous patch is for -current, but perhaps your source version is 6.3.
Please try the new patch below for 6.3.

The dmesg in the report says "OpenBSD 6.3", I missed it.
Sorry about that.

>
> # patch -p0 < axen.patch
> Hmm.. Lookd like a unified diff to me...
> The text leading up to this was:
> -------------------------
> |--- sys/dev/usb/if_axenreg.h Fri Sep 16 22:17:07 2016
> |+++ sys/dev/usb/if_axenreg.h Mon Jun 19 10:54:28 2017
> -------------------------
> Patching file sys/dev/usb/if_axenreg.h using Plan A...
> Hunk #1 succeeded at 26.
> Hunk #2 failed at 70.
> 1 out of 2 hunks failed--saving rejects to sys/dev/usb/if_axenreg.h.rej
> Hmm... The next patch look like a unified diff to me...
> The text leading up to this was:
> -------------------------
> |--- sys/dev/usb/if_axen.c.orig Tue Jun 12 15:36:59 2018
> |+++ sys/dev/usb/if_axen.c Sun Jul 29 01:53:43 2018
> -------------------------
> Patching file sys/dev/usb/if_axen.c using Plan A...
> Hunk #1 succeeded at 53.
> Hunk #2 succeeded at 122 with fuzz 2.
> Hunk #3 failed at 246.
> Hunk #4 failed at 275.
> Hunk #5 failed at 440.
> Hunk #6 failed at 502.
> Hunk #7 failed at 515.
> Hunk #8 failed at 637.
> Hunk #9 failed at 711.
> Hunk #10 succeeded at 810 with fuzz 1.
> Hunk #11 failed at 846.
> Hunk #12 failed at 877.
> Hunk #13 failed at 907.
> Hunk #14 failed at 932.
> Hunk #15 failed at 955.
> Hunk #16 failed at 975.
> Hunk #17 failed at 996.
> Hunk #18 failed at 1029.
> Hunk #19 failed at 1054.
> 16 out of 19 hunks failed--saving rejects to sys/dev/usb/if_axen.c.rej
> done

  - Only qctrl and buffer allocation are changed.
    (Omit some non-essential parts. It should work.)


--- sys/dev/usb/if_axen.c.orig Sun Jan 22 10:17:39 2017
+++ sys/dev/usb/if_axen.c Mon Aug  6 23:20:25 2018
@@ -53,6 +53,7 @@
  #include <dev/usb/usbdi_util.h>
  #include <dev/usb/usbdivar.h>
  #include <dev/usb/usbdevs.h>
+#include <dev/usb/usb_mem.h>
 
  #include <dev/usb/if_axenreg.h>
 
@@ -121,6 +122,13 @@ void axen_unlock_mii(struct axen_softc *sc);
 
  void axen_ax88179_init(struct axen_softc *);
 
+struct axen_qctrl axen_bulk_size[] = {
+ { 7, 0x4f, 0x00, 0x12, 0xff },
+ { 7, 0x20, 0x03, 0x16, 0xff },
+ { 7, 0xae, 0x07, 0x18, 0xff },
+ { 7, 0xcc, 0x4c, 0x18, 0x08 }
+};
+
  /* Get exclusive access to the MII registers */
  void
  axen_lock_mii(struct axen_softc *sc)
@@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev)
  int err;
  uint16_t val;
  uWord wval;
+ uint8_t linkstat = 0;
+ int qctrl;
 
  ifp = GET_IFP(sc);
  if (mii == NULL || ifp == NULL ||
@@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev)
  return;
 
  val = 0;
- if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
  val |= AXEN_MEDIUM_FDX;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
+ val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
+ val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
+ }
 
- val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
- val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
+ val |= AXEN_MEDIUM_RECV_EN;
 
+ /* bulkin queue setting */
+ axen_lock_mii(sc);
+ axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat);
+ axen_unlock_mii(sc);
+
  switch (IFM_SUBTYPE(mii->mii_media_active)) {
  case IFM_1000_T:
  val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
+ if (linkstat & AXEN_USB_SS)
+ qctrl = 0;
+ else if (linkstat & AXEN_USB_HS)
+ qctrl = 1;
+ else
+ qctrl = 3;
  break;
  case IFM_100_TX:
  val |= AXEN_MEDIUM_PS;
+ if (linkstat & (AXEN_USB_SS | AXEN_USB_HS))
+ qctrl = 2;
+ else
+ qctrl = 3;
  break;
  case IFM_10_T:
- /* doesn't need to be handled */
+ default:
+ qctrl = 3;
  break;
  }
 
  DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
  USETW(wval, val);
  axen_lock_mii(sc);
+ axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
+    &axen_bulk_size[qctrl]);
  err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
  axen_unlock_mii(sc);
  if (err) {
@@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc)
  uWord wval;
  uByte val;
  u_int16_t ctl, temp;
- struct axen_qctrl qctrl;
 
  axen_lock_mii(sc);
 
@@ -470,34 +501,18 @@ axen_ax88179_init(struct axen_softc *sc)
  switch (val) {
  case AXEN_USB_FS:
  DPRINTF(("uplink: USB1.1\n"));
- qctrl.ctrl = 0x07;
- qctrl.timer_low = 0xcc;
- qctrl.timer_high= 0x4c;
- qctrl.bufsize = AXEN_BUFSZ_LS - 1;
- qctrl.ifg = 0x08;
  break;
  case AXEN_USB_HS:
  DPRINTF(("uplink: USB2.0\n"));
- qctrl.ctrl = 0x07;
- qctrl.timer_low = 0x02;
- qctrl.timer_high= 0xa0;
- qctrl.bufsize = AXEN_BUFSZ_HS - 1;
- qctrl.ifg = 0xff;
  break;
  case AXEN_USB_SS:
  DPRINTF(("uplink: USB3.0\n"));
- qctrl.ctrl = 0x07;
- qctrl.timer_low = 0x4f;
- qctrl.timer_high= 0x00;
- qctrl.bufsize = AXEN_BUFSZ_SS - 1;
- qctrl.ifg = 0xff;
  break;
  default:
  printf("unknown uplink bus:0x%02x\n", val);
  axen_unlock_mii(sc);
  return;
  }
- axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
 
  /* Set MAC address. */
  axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
@@ -620,22 +635,8 @@ axen_attach(struct device *parent, struct device *self
 
  id = usbd_get_interface_descriptor(sc->axen_iface);
 
- /* decide on what our bufsize will be */
- switch (sc->axen_udev->speed) {
- case USB_SPEED_FULL:
-     sc->axen_bufsz = AXEN_BUFSZ_LS * 1024;
- break;
- case USB_SPEED_HIGH:
-     sc->axen_bufsz = AXEN_BUFSZ_HS * 1024;
- break;
- case USB_SPEED_SUPER:
-     sc->axen_bufsz = AXEN_BUFSZ_SS * 1024;
- break;
- default:
- printf("%s: not supported usb bus type", sc->axen_dev.dv_xname);
- return;
- }
-
+ sc->axen_bufsz = 64 * 1024;
+
  /* Find endpoints. */
  for (i = 0; i < id->bNumEndpoints; i++) {
  ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i);
@@ -708,7 +709,8 @@ axen_attach(struct device *parent, struct device *self
  mii->mii_flags = MIIF_AUTOTSLEEP;
 
  ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts);
- mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
+ mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
+    MIIF_DOPAUSE);
 
  if (LIST_FIRST(&mii->mii_phys) == NULL) {
  ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
@@ -806,6 +808,23 @@ axen_newbuf(void)
  return m;
  }
 
+static void *
+axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
+{
+ struct usbd_bus *bus = xfer->device->bus;
+ usbd_status err;
+
+#ifdef DIAGNOSTIC
+ if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
+ printf("axen_alloc_buffer: xfer already has a buffer\n");
+#endif
+ err = usb_allocmem(bus, size, 65536, &xfer->dmabuf);
+ if (err)
+ return (NULL);
+ xfer->rqflags |= URQ_DEV_DMABUF;
+ return (KERNADDR(&xfer->dmabuf, 0));
+}
+
  int
  axen_rx_list_init(struct axen_softc *sc)
  {
@@ -825,7 +844,7 @@ axen_rx_list_init(struct axen_softc *sc)
  c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
  if (c->axen_xfer == NULL)
  return ENOBUFS;
- c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
+ c->axen_buf = axen_alloc_buffer(c->axen_xfer,
     sc->axen_bufsz);
  if (c->axen_buf == NULL) {
  usbd_free_xfer(c->axen_xfer);
@@ -856,7 +875,7 @@ axen_tx_list_init(struct axen_softc *sc)
  c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
  if (c->axen_xfer == NULL)
  return ENOBUFS;
- c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
+ c->axen_buf = axen_alloc_buffer(c->axen_xfer,
     sc->axen_bufsz);
  if (c->axen_buf == NULL) {
  usbd_free_xfer(c->axen_xfer);

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Denis Lapshin-2
Hi,

axen.patch.1st has been applied to CURRENT src tree fetched from
official CVS with errors listed before.

Second patch has been applied to sources from official CVS -rOPENBSD_6_3
src. To test it one more time I've unpacked src.tar.gz and sys.tar.gz
from 6.3amd64 distribution CD and try axen.patch.2nd one more time...
the same errors like from official CVS.

What can be wrong?

# patch -p0 < axen.patch.2nd
Hmm.. Lookd like a unified diff to me...
The text leading up to this was:
-------------------------
|--- sys/dev/usb/if_axen.c.orig Sun Jan 22 10:17:39 2017
|+++ sys/dev/usb/if_axen.c Mon Aug 6 23:20:25 2018
-------------------------
Patching file sys/dev/usb/if_axen.c using Plan A...
Hunk #1 succeeded at 53.
Hunk #2 succeeded at 122 with fuzz 2.
Hunk #3 failed at 246.
Hunk #4 failed at 275.
Hunk #5 failed at 440.
Hunk #6 failed at 501.
Hunk #7 failed at 635.
Hunk #8 failed at 709.
Hunk #9 succeeded at 808 with fuzz 1.
Hunk #10 failed at 844.
Hunk #11 failed at 875.
8 out of 11 hunks failed--saving rejects to sys/dev/usb/if_axen.c.rej
done


On 8/7/2018 3:40 AM, [hidden email] wrote:

> Hi,
>
> On 2018/08/05 15:31, Denis wrote:
>> Can not patch original files in /usr/src/sys/dev/usb/ despite that
>> if_axenreg.h and if_axen.c files fetched directly from current CVS repo.
>
> Previous patch is for -current, but perhaps your source version is 6.3.
> Please try the new patch below for 6.3.
>
> The dmesg in the report says "OpenBSD 6.3", I missed it.
> Sorry about that.
>
>>
>> # patch -p0 < axen.patch
>> Hmm.. Lookd like a unified diff to me...
>> The text leading up to this was:
>> -------------------------
>> |--- sys/dev/usb/if_axenreg.h Fri Sep 16 22:17:07 2016
>> |+++ sys/dev/usb/if_axenreg.h Mon Jun 19 10:54:28 2017
>> -------------------------
>> Patching file sys/dev/usb/if_axenreg.h using Plan A...
>> Hunk #1 succeeded at 26.
>> Hunk #2 failed at 70.
>> 1 out of 2 hunks failed--saving rejects to sys/dev/usb/if_axenreg.h.rej
>> Hmm... The next patch look like a unified diff to me...
>> The text leading up to this was:
>> -------------------------
>> |--- sys/dev/usb/if_axen.c.orig Tue Jun 12 15:36:59 2018
>> |+++ sys/dev/usb/if_axen.c Sun Jul 29 01:53:43 2018
>> -------------------------
>> Patching file sys/dev/usb/if_axen.c using Plan A...
>> Hunk #1 succeeded at 53.
>> Hunk #2 succeeded at 122 with fuzz 2.
>> Hunk #3 failed at 246.
>> Hunk #4 failed at 275.
>> Hunk #5 failed at 440.
>> Hunk #6 failed at 502.
>> Hunk #7 failed at 515.
>> Hunk #8 failed at 637.
>> Hunk #9 failed at 711.
>> Hunk #10 succeeded at 810 with fuzz 1.
>> Hunk #11 failed at 846.
>> Hunk #12 failed at 877.
>> Hunk #13 failed at 907.
>> Hunk #14 failed at 932.
>> Hunk #15 failed at 955.
>> Hunk #16 failed at 975.
>> Hunk #17 failed at 996.
>> Hunk #18 failed at 1029.
>> Hunk #19 failed at 1054.
>> 16 out of 19 hunks failed--saving rejects to sys/dev/usb/if_axen.c.rej
>> done
>
>  - Only qctrl and buffer allocation are changed.
>    (Omit some non-essential parts. It should work.)
>
>
> --- sys/dev/usb/if_axen.c.orig    Sun Jan 22 10:17:39 2017
> +++ sys/dev/usb/if_axen.c    Mon Aug  6 23:20:25 2018
> @@ -53,6 +53,7 @@
>  #include <dev/usb/usbdi_util.h>
>  #include <dev/usb/usbdivar.h>
>  #include <dev/usb/usbdevs.h>
> +#include <dev/usb/usb_mem.h>
>  
>  #include <dev/usb/if_axenreg.h>
>  
> @@ -121,6 +122,13 @@ void    axen_unlock_mii(struct axen_softc *sc);
>  
>  void    axen_ax88179_init(struct axen_softc *);
>  
> +struct axen_qctrl axen_bulk_size[] = {
> +    { 7, 0x4f, 0x00, 0x12, 0xff },
> +    { 7, 0x20, 0x03, 0x16, 0xff },
> +    { 7, 0xae, 0x07, 0x18, 0xff },
> +    { 7, 0xcc, 0x4c, 0x18, 0x08 }
> +};
> +
>  /* Get exclusive access to the MII registers */
>  void
>  axen_lock_mii(struct axen_softc *sc)
> @@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev)
>      int            err;
>      uint16_t        val;
>      uWord            wval;
> +    uint8_t            linkstat = 0;
> +    int            qctrl;
>  
>      ifp = GET_IFP(sc);
>      if (mii == NULL || ifp == NULL ||
> @@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev)
>          return;
>  
>      val = 0;
> -    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
> +    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
>          val |= AXEN_MEDIUM_FDX;
> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
> +            val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
> +            val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
> +    }
>  
> -    val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
> -    val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
> +    val |= AXEN_MEDIUM_RECV_EN;
>  
> +    /* bulkin queue setting */
> +    axen_lock_mii(sc);
> +    axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat);
> +    axen_unlock_mii(sc);
> +
>      switch (IFM_SUBTYPE(mii->mii_media_active)) {
>      case IFM_1000_T:
>          val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
> +        if (linkstat & AXEN_USB_SS)
> +            qctrl = 0;
> +        else if (linkstat & AXEN_USB_HS)
> +            qctrl = 1;
> +        else
> +            qctrl = 3;
>          break;
>      case IFM_100_TX:
>          val |= AXEN_MEDIUM_PS;
> +        if (linkstat & (AXEN_USB_SS | AXEN_USB_HS))
> +            qctrl = 2;
> +        else
> +            qctrl = 3;
>          break;
>      case IFM_10_T:
> -        /* doesn't need to be handled */
> +    default:
> +        qctrl = 3;
>          break;
>      }
>  
>      DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
>      USETW(wval, val);
>      axen_lock_mii(sc);
> +    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
> +        &axen_bulk_size[qctrl]);
>      err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
>      axen_unlock_mii(sc);
>      if (err) {
> @@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc)
>      uWord        wval;
>      uByte        val;
>      u_int16_t     ctl, temp;
> -    struct axen_qctrl qctrl;
>  
>      axen_lock_mii(sc);
>  
> @@ -470,34 +501,18 @@ axen_ax88179_init(struct axen_softc *sc)
>      switch (val) {
>      case AXEN_USB_FS:
>          DPRINTF(("uplink: USB1.1\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0xcc;
> -        qctrl.timer_high= 0x4c;
> -        qctrl.bufsize    = AXEN_BUFSZ_LS - 1;
> -        qctrl.ifg    = 0x08;
>          break;
>      case AXEN_USB_HS:
>          DPRINTF(("uplink: USB2.0\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0x02;
> -        qctrl.timer_high= 0xa0;
> -        qctrl.bufsize    = AXEN_BUFSZ_HS - 1;
> -        qctrl.ifg    = 0xff;
>          break;
>      case AXEN_USB_SS:
>          DPRINTF(("uplink: USB3.0\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0x4f;
> -        qctrl.timer_high= 0x00;
> -        qctrl.bufsize    = AXEN_BUFSZ_SS - 1;
> -        qctrl.ifg    = 0xff;
>          break;
>      default:
>          printf("unknown uplink bus:0x%02x\n", val);
>          axen_unlock_mii(sc);
>          return;
>      }
> -    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
>  
>      /* Set MAC address. */
>      axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
> @@ -620,22 +635,8 @@ axen_attach(struct device *parent, struct device *self
>  
>      id = usbd_get_interface_descriptor(sc->axen_iface);
>  
> -    /* decide on what our bufsize will be */
> -    switch (sc->axen_udev->speed) {
> -    case USB_SPEED_FULL:
> -            sc->axen_bufsz = AXEN_BUFSZ_LS * 1024;
> -        break;
> -    case USB_SPEED_HIGH:
> -            sc->axen_bufsz = AXEN_BUFSZ_HS * 1024;
> -        break;
> -    case USB_SPEED_SUPER:
> -            sc->axen_bufsz = AXEN_BUFSZ_SS * 1024;
> -        break;
> -    default:
> -        printf("%s: not supported usb bus type", sc->axen_dev.dv_xname);
> -        return;
> -    }
> -       
> +    sc->axen_bufsz = 64 * 1024;
> +
>      /* Find endpoints. */
>      for (i = 0; i < id->bNumEndpoints; i++) {
>          ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i);
> @@ -708,7 +709,8 @@ axen_attach(struct device *parent, struct device *self
>      mii->mii_flags = MIIF_AUTOTSLEEP;
>  
>      ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts);
> -    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
> +    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
> +        MIIF_DOPAUSE);
>  
>      if (LIST_FIRST(&mii->mii_phys) == NULL) {
>          ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
> @@ -806,6 +808,23 @@ axen_newbuf(void)
>      return m;
>  }
>  
> +static void *
> +axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
> +{
> +    struct usbd_bus *bus = xfer->device->bus;
> +    usbd_status err;
> +
> +#ifdef DIAGNOSTIC
> +    if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
> +        printf("axen_alloc_buffer: xfer already has a buffer\n");
> +#endif
> +    err = usb_allocmem(bus, size, 65536, &xfer->dmabuf);
> +    if (err)
> +        return (NULL);
> +    xfer->rqflags |= URQ_DEV_DMABUF;
> +    return (KERNADDR(&xfer->dmabuf, 0));
> +}
> +
>  int
>  axen_rx_list_init(struct axen_softc *sc)
>  {
> @@ -825,7 +844,7 @@ axen_rx_list_init(struct axen_softc *sc)
>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>              if (c->axen_xfer == NULL)
>                  return ENOBUFS;
> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>                  sc->axen_bufsz);
>              if (c->axen_buf == NULL) {
>                  usbd_free_xfer(c->axen_xfer);
> @@ -856,7 +875,7 @@ axen_tx_list_init(struct axen_softc *sc)
>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>              if (c->axen_xfer == NULL)
>                  return ENOBUFS;
> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>                  sc->axen_bufsz);
>              if (c->axen_buf == NULL) {
>                  usbd_free_xfer(c->axen_xfer);
>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

sc.dying
Hi,

On 2018/08/07 09:23, Denis wrote:

> Hi,
>
> axen.patch.1st has been applied to CURRENT src tree fetched from
> official CVS with errors listed before.
>
> Second patch has been applied to sources from official CVS -rOPENBSD_6_3
> src. To test it one more time I've unpacked src.tar.gz and sys.tar.gz
> from 6.3amd64 distribution CD and try axen.patch.2nd one more time...
> the same errors like from official CVS.
>
> What can be wrong?
It is a whitespace problem caused by my mailer.
I attached both patches. I hope they help you.

axen.diff (11K) Download Attachment
axen2.diff (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Denis Lapshin-2
In reply to this post by sc.dying
Hi,

Using second diff applied to 6.3 sources and rebuilt kernel.

The issue is persistent + new kernel error message:

checksum err (pkt#1)

axen0: usb errors on rs: IOERROR
axen0: usb errors on rx: IOERROR
axen0: usb error on tx: IOERROR
axen0: watchdog timeout
axen0: usb error on tx: IOERROR
...

Right now axen is connected to USB3 if it will help.

On 7/30/2018 3:11 AM, [hidden email] wrote:

> Hi,
>
> On 2018/07/27 09:14, Denis wrote:
>> Every time (after 2-3 minutes of work) ASIX Electronics USB-Ethernet
>> device reports:
>>
>> axen0: usb errors on rx: IOERROR
>> axen0: usb errors on rx: IOERROR
>> axen0: usb errors on tx: IOERROR
>> axen0: watchdog timeout
>> axen0: usb errors on tx: IOERROR
>>
>> The device hangs and must be reattached to have it working again for 2-3
>> minutes.
>
> Do you want to try this patch?
>
> -----
>  - header: fix comments
>  - header: fix unused L3 type mask definition
>  - rxeof: Avoid allocating mbuf if checksum errors are detected.
>  - rxeof: Avoid loop to extract packets if pkt_count is 0.
>  - rxeof: Add more sanity checks.
>  - rxeof: Increament if_ierror in some error paths.
>  - qctrl: Apply queuing control parameters from FreeBSD axge(4).
>  - qctrl: Set qctrl in miireg_statchg dynamically, not statically.
>  - Use DMA buffer aligned at 64KB boundary to avoid xhci bug.
>
>
> --- sys/dev/usb/if_axenreg.h    Fri Sep 16 22:17:07 2016
> +++ sys/dev/usb/if_axenreg.h    Mon Jun 19 10:54:28 2017
> @@ -26,8 +26,8 @@
>   *                     |    |     ++-----L3_type (1:ipv4, 0/2:ipv6)
>   *        pkt_len(13)  |    |     ||+ ++-L4_type(0: icmp, 1: UDP, 4: TCP)
>   * |765|43210 76543210|7654 3210 7654 3210|
> - *  ||+-crc_err              |+-L4_err |+-L4_CSUM_ERR
> - *  |+-mii_err               +--L3_err +--L3_CSUM_ERR
> + *  ||+-crc_err               |+-L4_err |+-L4_CSUM_ERR
> + *  |+-mii_err                +--L3_err +--L3_CSUM_ERR
>   *  +-drop_err
>   *
>   * ex) pkt_hdr 0x00680820
> @@ -70,7 +70,7 @@
>  #define   AXEN_RXHDR_L4_TYPE_TCP    0x4
>  
>  /* L3 packet type (2bit) */
> -#define AXEN_RXHDR_L3_TYPE_MASK    0x00000600
> +#define AXEN_RXHDR_L3_TYPE_MASK    0x00000060
>  #define AXEN_RXHDR_L3_TYPE_OFFSET    5
>  #define   AXEN_RXHDR_L3_TYPE_UNDEF    0x0
>  #define   AXEN_RXHDR_L3_TYPE_IPV4    0x1
> --- sys/dev/usb/if_axen.c.orig    Tue Jun 12 15:36:59 2018
> +++ sys/dev/usb/if_axen.c    Sun Jul 29 01:53:43 2018
> @@ -53,6 +53,7 @@
>  #include <dev/usb/usbdi_util.h>
>  #include <dev/usb/usbdivar.h>
>  #include <dev/usb/usbdevs.h>
> +#include <dev/usb/usb_mem.h>
>  
>  #include <dev/usb/if_axenreg.h>
>  
> @@ -121,6 +122,13 @@ void    axen_unlock_mii(struct axen_softc *sc);
>  
>  void    axen_ax88179_init(struct axen_softc *);
>  
> +struct axen_qctrl axen_bulk_size[] = {
> +    { 7, 0x4f, 0x00, 0x12, 0xff },
> +    { 7, 0x20, 0x03, 0x16, 0xff },
> +    { 7, 0xae, 0x07, 0x18, 0xff },
> +    { 7, 0xcc, 0x4c, 0x18, 0x08 }
> +};
> +
>  /* Get exclusive access to the MII registers */
>  void
>  axen_lock_mii(struct axen_softc *sc)
> @@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev)
>      int            err;
>      uint16_t        val;
>      uWord            wval;
> +    uint8_t            linkstat = 0;
> +    int            qctrl;
>  
>      ifp = GET_IFP(sc);
>      if (mii == NULL || ifp == NULL ||
> @@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev)
>          return;
>  
>      val = 0;
> -    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
> +    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
>          val |= AXEN_MEDIUM_FDX;
> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
> +            val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
> +            val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
> +    }
>  
> -    val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
> -    val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
> +    val |= AXEN_MEDIUM_RECV_EN;
>  
> +    /* bulkin queue setting */
> +    axen_lock_mii(sc);
> +    axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat);
> +    axen_unlock_mii(sc);
> +
>      switch (IFM_SUBTYPE(mii->mii_media_active)) {
>      case IFM_1000_T:
>          val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
> +        if (linkstat & AXEN_USB_SS)
> +            qctrl = 0;
> +        else if (linkstat & AXEN_USB_HS)
> +            qctrl = 1;
> +        else
> +            qctrl = 3;
>          break;
>      case IFM_100_TX:
>          val |= AXEN_MEDIUM_PS;
> +        if (linkstat & (AXEN_USB_SS | AXEN_USB_HS))
> +            qctrl = 2;
> +        else
> +            qctrl = 3;
>          break;
>      case IFM_10_T:
> -        /* doesn't need to be handled */
> +    default:
> +        qctrl = 3;
>          break;
>      }
>  
>      DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
>      USETW(wval, val);
>      axen_lock_mii(sc);
> +    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
> +        &axen_bulk_size[qctrl]);
>      err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
>      axen_unlock_mii(sc);
>      if (err) {
> @@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc)
>      uWord        wval;
>      uByte        val;
>      u_int16_t     ctl, temp;
> -    struct axen_qctrl qctrl;
>  
>      axen_lock_mii(sc);
>  
> @@ -471,27 +502,12 @@ axen_ax88179_init(struct axen_softc *sc)
>      switch (val) {
>      case AXEN_USB_FS:
>          DPRINTF(("uplink: USB1.1\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0xcc;
> -        qctrl.timer_high= 0x4c;
> -        qctrl.bufsize    = AXEN_BUFSZ_LS - 1;
> -        qctrl.ifg    = 0x08;
>          break;
>      case AXEN_USB_HS:
>          DPRINTF(("uplink: USB2.0\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0x02;
> -        qctrl.timer_high= 0xa0;
> -        qctrl.bufsize    = AXEN_BUFSZ_HS - 1;
> -        qctrl.ifg    = 0xff;
>          break;
>      case AXEN_USB_SS:
>          DPRINTF(("uplink: USB3.0\n"));
> -        qctrl.ctrl    = 0x07;
> -        qctrl.timer_low    = 0x4f;
> -        qctrl.timer_high= 0x00;
> -        qctrl.bufsize    = AXEN_BUFSZ_SS - 1;
> -        qctrl.ifg    = 0xff;
>          break;
>      default:
>          printf("%s: unknown uplink bus:0x%02x\n",
> @@ -499,7 +515,6 @@ axen_ax88179_init(struct axen_softc *sc)
>          axen_unlock_mii(sc);
>          return;
>      }
> -    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
>  
>      /* Set MAC address. */
>      axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
> @@ -622,22 +637,8 @@ axen_attach(struct device *parent, struct device *self
>  
>      id = usbd_get_interface_descriptor(sc->axen_iface);
>  
> -    /* decide on what our bufsize will be */
> -    switch (sc->axen_udev->speed) {
> -    case USB_SPEED_FULL:
> -            sc->axen_bufsz = AXEN_BUFSZ_LS * 1024;
> -        break;
> -    case USB_SPEED_HIGH:
> -            sc->axen_bufsz = AXEN_BUFSZ_HS * 1024;
> -        break;
> -    case USB_SPEED_SUPER:
> -            sc->axen_bufsz = AXEN_BUFSZ_SS * 1024;
> -        break;
> -    default:
> -        printf("%s: not supported usb bus type", sc->axen_dev.dv_xname);
> -        return;
> -    }
> -       
> +    sc->axen_bufsz = 64 * 1024;
> +
>      /* Find endpoints. */
>      for (i = 0; i < id->bNumEndpoints; i++) {
>          ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i);
> @@ -710,7 +711,8 @@ axen_attach(struct device *parent, struct device *self
>      mii->mii_flags = MIIF_AUTOTSLEEP;
>  
>      ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts);
> -    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
> +    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
> +        MIIF_DOPAUSE);
>  
>      if (LIST_FIRST(&mii->mii_phys) == NULL) {
>          ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
> @@ -808,6 +810,23 @@ axen_newbuf(void)
>      return m;
>  }
>  
> +static void *
> +axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
> +{
> +    struct usbd_bus *bus = xfer->device->bus;
> +    usbd_status err;
> +
> +#ifdef DIAGNOSTIC
> +    if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
> +        printf("axen_alloc_buffer: xfer already has a buffer\n");
> +#endif
> +    err = usb_allocmem(bus, size, 65536, &xfer->dmabuf);
> +    if (err)
> +        return (NULL);
> +    xfer->rqflags |= URQ_DEV_DMABUF;
> +    return (KERNADDR(&xfer->dmabuf, 0));
> +}
> +
>  int
>  axen_rx_list_init(struct axen_softc *sc)
>  {
> @@ -827,7 +846,7 @@ axen_rx_list_init(struct axen_softc *sc)
>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>              if (c->axen_xfer == NULL)
>                  return ENOBUFS;
> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>                  sc->axen_bufsz);
>              if (c->axen_buf == NULL) {
>                  usbd_free_xfer(c->axen_xfer);
> @@ -858,7 +877,7 @@ axen_tx_list_init(struct axen_softc *sc)
>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>              if (c->axen_xfer == NULL)
>                  return ENOBUFS;
> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>                  sc->axen_bufsz);
>              if (c->axen_buf == NULL) {
>                  usbd_free_xfer(c->axen_xfer);
> @@ -888,7 +907,6 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>      u_int32_t        *hdr_p;
>      u_int16_t        hdr_offset, pkt_count;
>      size_t            pkt_len;
> -    size_t            temp;
>      int            s;
>  
>      DPRINTFN(10,("%s: %s: enter\n", sc->axen_dev.dv_xname,__func__));
> @@ -914,10 +932,19 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
>  
>      if (total_len < sizeof(pkt_hdr)) {
> +        printf("%s: rxeof: too short transfer\n",
> +            sc->axen_dev.dv_xname);
>          ifp->if_ierrors++;
>          goto done;
>      }
>  
> +    if (total_len > sc->axen_bufsz) {
> +        printf("%s: rxeof: too large transfer\n",
> +            sc->axen_dev.dv_xname);
> +        ifp->if_ierrors++;
> +        goto done;
> +    }
> +
>      /*
>       * buffer map
>       * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
> @@ -928,16 +955,10 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      hdr_offset = (u_int16_t)(rx_hdr >> 16);
>      pkt_count  = (u_int16_t)(rx_hdr & 0xffff);
>  
> -    if (total_len > sc->axen_bufsz) {
> -        printf("%s: rxeof: too large transfer\n",
> -            sc->axen_dev.dv_xname);
> -        goto done;
> -    }
> -
>      /* sanity check */
>      if (hdr_offset > total_len) {
> -        ifp->if_ierrors++;
>          usbd_delay_ms(sc->axen_udev, 100);
> +        ifp->if_ierrors++;
>          goto done;
>      }
>  
> @@ -954,11 +975,14 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>      if (pkt_count > AXEN_MAX_PACKED_PACKET) {
>          DPRINTF(("Too many packets (%d) in a transaction, discard.\n",
>              pkt_count));
> +        ifp->if_ierrors++;
>          goto done;
>      }
>  #endif
>  
> -    do {
> +    for (; pkt_count > 0; pkt_count--) {
> +        uint16_t csum_flags = 0;
> +
>          if ((buf[0] != 0xee) || (buf[1] != 0xee)){
>              printf("%s: invalid buffer(pkt#%d), continue\n",
>                  sc->axen_dev.dv_xname, pkt_count);
> @@ -972,34 +996,31 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>          DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
>             pkt_count, pkt_hdr, pkt_len));
>  
> +        if (pkt_len > MCLBYTES || pkt_len < ETHER_MIN_LEN) {
> +            printf("%s: invalid pkt_len %zu\n",
> +                sc->axen_dev.dv_xname,pkt_len);
> +            ifp->if_ierrors++;
> +            goto nextpkt;
> +        }
> +
>          if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) ||
>                  (pkt_hdr & AXEN_RXHDR_DROP_ERR)) {
> -                ifp->if_ierrors++;
>              /* move to next pkt header */
>              DPRINTF(("crc err(pkt#%d)\n", pkt_count));
> +                ifp->if_ierrors++;
>              goto nextpkt;
>          }
>  
> -        /* process each packet */
> -        /* allocate mbuf */
> -        m = axen_newbuf();
> -        if (m == NULL) {
> -            ifp->if_ierrors++;
> -            goto nextpkt;
> -        }
> -
> -        /* skip pseudo header (2byte) and trailer padding (4Byte) */
> -        m->m_pkthdr.len = m->m_len = pkt_len - 6;
> -
>  #ifdef AXEN_TOE
>          /* cheksum err */
>          if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) ||
>              (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) {
>              printf("%s: checksum err (pkt#%d)\n",
>                  sc->axen_dev.dv_xname, pkt_count);
> +            ifp->if_ierrors++;
>              goto nextpkt;
>          } else {
> -            m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
> +            csum_flags |= M_IPV4_CSUM_IN_OK;
>          }
>  
>          int l4_type;
> @@ -1008,12 +1029,23 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
> usbd_st
>  
>          if ((l4_type == AXEN_RXHDR_L4_TYPE_TCP) ||
>              (l4_type == AXEN_RXHDR_L4_TYPE_UDP))
> -            m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
> -                M_UDP_CSUM_IN_OK;
> +            csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
>  #endif
>  
> -        memcpy(mtod(m, char *), buf + 2, pkt_len - 6);
> +        /* process each packet */
> +        /* allocate mbuf */
> +        m = axen_newbuf();
> +        if (m == NULL) {
> +            ifp->if_ierrors++;
> +            goto nextpkt;
> +        }
>  
> +        /* skip pseudo header (2byte) and trailer padding (4Byte) */
> +        m->m_pkthdr.len = m->m_len = pkt_len - 6;
> +        m->m_pkthdr.csum_flags |= csum_flags;
> +
> +        memcpy(mtod(m, char *), buf + 2, m->m_len);
> +
>          ml_enqueue(&ml, m);
>  
>  nextpkt:
> @@ -1022,11 +1054,9 @@ nextpkt:
>           * as each packet will be aligned 8byte boundary,
>           * need to fix up the start point of the buffer.
>           */
> -        temp = ((pkt_len + 7) & 0xfff8);
> -        buf = buf + temp;
> +        buf += roundup(pkt_len, 8);
>          hdr_p++;
> -        pkt_count--;
> -    } while( pkt_count > 0);
> +    }
>  
>  done:
>      /* push the packet up */
>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

sc.dying
Hi,

On Wed, Aug 8, 2018 at 9:24 AM, Denis <[hidden email]> wrote:

> Hi,
>
> Using second diff applied to 6.3 sources and rebuilt kernel.
>
> The issue is persistent + new kernel error message:
>
> checksum err (pkt#1)
>
> axen0: usb errors on rs: IOERROR
> axen0: usb errors on rx: IOERROR
> axen0: usb error on tx: IOERROR
> axen0: watchdog timeout
> axen0: usb error on tx: IOERROR
> ...
>
> Right now axen is connected to USB3 if it will help.

Hmm, no idea.
Does your dongle and PC work properly on other OSes?

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Tinker
On August 9, 2018 1:39 PM, sc dying <[hidden email]> wrote:

> Hi,
>
> On Wed, Aug 8, 2018 at 9:24 AM, Denis [hidden email] wrote:
>
> > Hi,
> > Using second diff applied to 6.3 sources and rebuilt kernel.
> > The issue is persistent + new kernel error message:
> > checksum err (pkt#1)
> > axen0: usb errors on rs: IOERROR
> > axen0: usb errors on rx: IOERROR
> > axen0: usb error on tx: IOERROR
> > axen0: watchdog timeout
> > axen0: usb error on tx: IOERROR
> > ...
> > Right now axen is connected to USB3 if it will help.
>
> Hmm, no idea.
> Does your dongle and PC work properly on other OSes?

Compile kernel with XHCI_DEBUG to see if there's anything interesting there?

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Denis Lapshin-2
In reply to this post by Denis Lapshin-2
I have 6.3 kernel compiled with option XHCI_debug and axen2.diff
implemented.

I'm using lladdr option for /etc/hostname.axen0 to have the same IP addr
each session for different Ehternet adapters.

Here is debug output when axen is connected:

xhci0: port=2 change=0x04
xhci0: port=2 change=0x04
xhci0: xhci_cmd_slot_control
xhci0: dev 1, input=0xffffff0001988000 slot=0xffffff0001988020
ep0=0xffffff0001988040
xhci0: dev 1, setting DCBAA to 0x0000000001989000
xhci_pipe_init: pipe=0xffff800000a8d000 addr=0 depth=1 port=2 speed=4
dev 1 dci 1 (epAddr=0x0)
xhci0: xhci_cmd_set_address BSR=1
xhci0: xhci_cmd_set_address BSR=0
xhci0: dev 1 addr 1
axen0 at uhub0 port 2 configuration 1 interface 0 "ASIX Elec. Corp.
AX88179" rev 3.00/1.00 addr 2
axen0: AX88179, address xx:xx:xx:xx:xx:xx
ukphy0 at axen0 phy 3: Generic IEEE 802.3u media interface, rev. 5: OUI
0x000732, model 0x0011
xhci_pipe_init: pipe=0xffff800000b38000 addr=2 depth=1 port=2 speed=4
dev 1 dci 5 (epAddr=0x82)
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff800000bfc000 addr=2 depth=1 port=2 speed=4
dev 1 dci 6 (epAddr=0x3)
xhci0: xhci_cmd_configure_ep dev 1
xhci_abort_xfer: xfer=0xffffff044e6aee10 status=IN_PROGRESS
err=CANCELLED actlen=0 len=65536 idx=0
xhci0: xhci_cmd_stop_ep dev 1 dci 5
xhci_event_xfer: stopped xfer=0xffffff044e6aee10
xhci0: xhci_cmd_set_tr_deq_async dev 1 dci 5
xhci0: xhci_cmd_configure_ep dev 1
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff800000b3a000 addr=2 depth=1 port=2 speed=4
dev 1 dci 5 (epAddr=0x82)
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff800000b3e000 addr=2 depth=1 port=2 speed=4
dev 1 dci 6 (epAddr=0x3)
xhci0: xhci_cmd_configure_ep dev 1
xhci_abort_xfer: xfer=0xffffff044e6aed20 status=IN_PROGRESS
err=CANCELLED actlen=0 len=65536 idx=42
xhci0: xhci_cmd_stop_ep dev 1 dci 5
xhci_event_xfer: stopped xfer=0xffffff044e6aed20
xhci0: xhci_cmd_set_tr_deq_async dev 1 dci 5
xhci0: xhci_cmd_configure_ep dev 1
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff800000790000 addr=2 depth=1 port=2 speed=4
dev 1 dci 5 (epAddr=0x82)
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff800000791000 addr=2 depth=1 port=2 speed=4
dev 1 dci 6 (epAddr=0x3)
xhci0: xhci_cmd_configure_ep dev 1
xhci0: txerr? code 4
axen0: usb errors on rx: IOERROR
xhci_abort_xfer: xfer=0xffffff044e6aee10 status=NOT_STARTED
err=CANCELLED actlen=0 len=65536 idx=-1
xhci0: xhci_cmd_configure_ep dev 1
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff8000007a9000 addr=2 depth=1 port=2 speed=4
dev 1 dci 5 (epAddr=0x82)
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff8000007aa000 addr=2 depth=1 port=2 speed=4
dev 1 dci 6 (epAddr=0x3)
xhci0: xhci_cmd_configure_ep dev 1
xhci0: txerr? code 4
axen0: usb errors on rx: IOERROR
xhci0: txerr? code 4
axen0: usb error on tx: IOERROR
axen0: watchdog timeout
axen0: usb error on tx: IOERROR
xhci_abort_xfer: xfer=0xffffff044e6aed20 status=NOT_STARTED
err=CANCELLED actlen=0 len=65536 idx=-1
xhci0: xhci_cmd_configure_ep dev 1
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff800000865000 addr=2 depth=1 port=2 speed=4
dev 1 dci 5 (epAddr=0x82)
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff800000866000 addr=2 depth=1 port=2 speed=4
dev 1 dci 6 (epAddr=0x3)
xhci0: xhci_cmd_configure_ep dev 1
xhci0: txerr? code 4
axen0: usb errors on rx: IOERROR
xhci0: txerr? code 4
axen0: usb error on tx: IOERROR
xhci_abort_xfer: xfer=0xffffff044e6aee10 status=NOT_STARTED
err=CANCELLED actlen=0 len=65536 idx=-1
xhci0: xhci_cmd_configure_ep dev 1
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff80000087e000 addr=2 depth=1 port=2 speed=4
dev 1 dci 5 (epAddr=0x82)
xhci0: xhci_cmd_configure_ep dev 1
xhci_pipe_init: pipe=0xffff80000087f000 addr=2 depth=1 port=2 speed=4
dev 1 dci 6 (epAddr=0x3)
xhci0: xhci_cmd_configure_ep dev 1
xhci0: txerr? code 4
axen0: usb errors on rx: IOERROR
xhci0: txerr? code 4
axen0: usb error on tx: IOERROR
axen0: watchdog timeout


On 7/31/2018 11:08 AM, Denis wrote:

> Hello,
>
> Thank you for patch. I can apply it a bit later in the trip currently.
>
>
>
> On 7/30/2018 3:11 AM, [hidden email] wrote:
>> Hi,
>>
>> On 2018/07/27 09:14, Denis wrote:
>>> Every time (after 2-3 minutes of work) ASIX Electronics USB-Ethernet
>>> device reports:
>>>
>>> axen0: usb errors on rx: IOERROR
>>> axen0: usb errors on rx: IOERROR
>>> axen0: usb errors on tx: IOERROR
>>> axen0: watchdog timeout
>>> axen0: usb errors on tx: IOERROR
>>>
>>> The device hangs and must be reattached to have it working again for 2-3
>>> minutes.
>>
>> Do you want to try this patch?
>>
>> -----
>>  - header: fix comments
>>  - header: fix unused L3 type mask definition
>>  - rxeof: Avoid allocating mbuf if checksum errors are detected.
>>  - rxeof: Avoid loop to extract packets if pkt_count is 0.
>>  - rxeof: Add more sanity checks.
>>  - rxeof: Increament if_ierror in some error paths.
>>  - qctrl: Apply queuing control parameters from FreeBSD axge(4).
>>  - qctrl: Set qctrl in miireg_statchg dynamically, not statically.
>>  - Use DMA buffer aligned at 64KB boundary to avoid xhci bug.
>>
>>
>> --- sys/dev/usb/if_axenreg.h    Fri Sep 16 22:17:07 2016
>> +++ sys/dev/usb/if_axenreg.h    Mon Jun 19 10:54:28 2017
>> @@ -26,8 +26,8 @@
>>   *                     |    |     ++-----L3_type (1:ipv4, 0/2:ipv6)
>>   *        pkt_len(13)  |    |     ||+ ++-L4_type(0: icmp, 1: UDP, 4: TCP)
>>   * |765|43210 76543210|7654 3210 7654 3210|
>> - *  ||+-crc_err              |+-L4_err |+-L4_CSUM_ERR
>> - *  |+-mii_err               +--L3_err +--L3_CSUM_ERR
>> + *  ||+-crc_err               |+-L4_err |+-L4_CSUM_ERR
>> + *  |+-mii_err                +--L3_err +--L3_CSUM_ERR
>>   *  +-drop_err
>>   *
>>   * ex) pkt_hdr 0x00680820
>> @@ -70,7 +70,7 @@
>>  #define   AXEN_RXHDR_L4_TYPE_TCP    0x4
>>  
>>  /* L3 packet type (2bit) */
>> -#define AXEN_RXHDR_L3_TYPE_MASK    0x00000600
>> +#define AXEN_RXHDR_L3_TYPE_MASK    0x00000060
>>  #define AXEN_RXHDR_L3_TYPE_OFFSET    5
>>  #define   AXEN_RXHDR_L3_TYPE_UNDEF    0x0
>>  #define   AXEN_RXHDR_L3_TYPE_IPV4    0x1
>> --- sys/dev/usb/if_axen.c.orig    Tue Jun 12 15:36:59 2018
>> +++ sys/dev/usb/if_axen.c    Sun Jul 29 01:53:43 2018
>> @@ -53,6 +53,7 @@
>>  #include <dev/usb/usbdi_util.h>
>>  #include <dev/usb/usbdivar.h>
>>  #include <dev/usb/usbdevs.h>
>> +#include <dev/usb/usb_mem.h>
>>  
>>  #include <dev/usb/if_axenreg.h>
>>  
>> @@ -121,6 +122,13 @@ void    axen_unlock_mii(struct axen_softc *sc);
>>  
>>  void    axen_ax88179_init(struct axen_softc *);
>>  
>> +struct axen_qctrl axen_bulk_size[] = {
>> +    { 7, 0x4f, 0x00, 0x12, 0xff },
>> +    { 7, 0x20, 0x03, 0x16, 0xff },
>> +    { 7, 0xae, 0x07, 0x18, 0xff },
>> +    { 7, 0xcc, 0x4c, 0x18, 0x08 }
>> +};
>> +
>>  /* Get exclusive access to the MII registers */
>>  void
>>  axen_lock_mii(struct axen_softc *sc)
>> @@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev)
>>      int            err;
>>      uint16_t        val;
>>      uWord            wval;
>> +    uint8_t            linkstat = 0;
>> +    int            qctrl;
>>  
>>      ifp = GET_IFP(sc);
>>      if (mii == NULL || ifp == NULL ||
>> @@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev)
>>          return;
>>  
>>      val = 0;
>> -    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
>> +    if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
>>          val |= AXEN_MEDIUM_FDX;
>> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
>> +            val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
>> +        if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
>> +            val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
>> +    }
>>  
>> -    val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
>> -    val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
>> +    val |= AXEN_MEDIUM_RECV_EN;
>>  
>> +    /* bulkin queue setting */
>> +    axen_lock_mii(sc);
>> +    axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat);
>> +    axen_unlock_mii(sc);
>> +
>>      switch (IFM_SUBTYPE(mii->mii_media_active)) {
>>      case IFM_1000_T:
>>          val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
>> +        if (linkstat & AXEN_USB_SS)
>> +            qctrl = 0;
>> +        else if (linkstat & AXEN_USB_HS)
>> +            qctrl = 1;
>> +        else
>> +            qctrl = 3;
>>          break;
>>      case IFM_100_TX:
>>          val |= AXEN_MEDIUM_PS;
>> +        if (linkstat & (AXEN_USB_SS | AXEN_USB_HS))
>> +            qctrl = 2;
>> +        else
>> +            qctrl = 3;
>>          break;
>>      case IFM_10_T:
>> -        /* doesn't need to be handled */
>> +    default:
>> +        qctrl = 3;
>>          break;
>>      }
>>  
>>      DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
>>      USETW(wval, val);
>>      axen_lock_mii(sc);
>> +    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
>> +        &axen_bulk_size[qctrl]);
>>      err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
>>      axen_unlock_mii(sc);
>>      if (err) {
>> @@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc)
>>      uWord        wval;
>>      uByte        val;
>>      u_int16_t     ctl, temp;
>> -    struct axen_qctrl qctrl;
>>  
>>      axen_lock_mii(sc);
>>  
>> @@ -471,27 +502,12 @@ axen_ax88179_init(struct axen_softc *sc)
>>      switch (val) {
>>      case AXEN_USB_FS:
>>          DPRINTF(("uplink: USB1.1\n"));
>> -        qctrl.ctrl    = 0x07;
>> -        qctrl.timer_low    = 0xcc;
>> -        qctrl.timer_high= 0x4c;
>> -        qctrl.bufsize    = AXEN_BUFSZ_LS - 1;
>> -        qctrl.ifg    = 0x08;
>>          break;
>>      case AXEN_USB_HS:
>>          DPRINTF(("uplink: USB2.0\n"));
>> -        qctrl.ctrl    = 0x07;
>> -        qctrl.timer_low    = 0x02;
>> -        qctrl.timer_high= 0xa0;
>> -        qctrl.bufsize    = AXEN_BUFSZ_HS - 1;
>> -        qctrl.ifg    = 0xff;
>>          break;
>>      case AXEN_USB_SS:
>>          DPRINTF(("uplink: USB3.0\n"));
>> -        qctrl.ctrl    = 0x07;
>> -        qctrl.timer_low    = 0x4f;
>> -        qctrl.timer_high= 0x00;
>> -        qctrl.bufsize    = AXEN_BUFSZ_SS - 1;
>> -        qctrl.ifg    = 0xff;
>>          break;
>>      default:
>>          printf("%s: unknown uplink bus:0x%02x\n",
>> @@ -499,7 +515,6 @@ axen_ax88179_init(struct axen_softc *sc)
>>          axen_unlock_mii(sc);
>>          return;
>>      }
>> -    axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
>>  
>>      /* Set MAC address. */
>>      axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
>> @@ -622,22 +637,8 @@ axen_attach(struct device *parent, struct device *self
>>  
>>      id = usbd_get_interface_descriptor(sc->axen_iface);
>>  
>> -    /* decide on what our bufsize will be */
>> -    switch (sc->axen_udev->speed) {
>> -    case USB_SPEED_FULL:
>> -            sc->axen_bufsz = AXEN_BUFSZ_LS * 1024;
>> -        break;
>> -    case USB_SPEED_HIGH:
>> -            sc->axen_bufsz = AXEN_BUFSZ_HS * 1024;
>> -        break;
>> -    case USB_SPEED_SUPER:
>> -            sc->axen_bufsz = AXEN_BUFSZ_SS * 1024;
>> -        break;
>> -    default:
>> -        printf("%s: not supported usb bus type", sc->axen_dev.dv_xname);
>> -        return;
>> -    }
>> -       
>> +    sc->axen_bufsz = 64 * 1024;
>> +
>>      /* Find endpoints. */
>>      for (i = 0; i < id->bNumEndpoints; i++) {
>>          ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i);
>> @@ -710,7 +711,8 @@ axen_attach(struct device *parent, struct device *self
>>      mii->mii_flags = MIIF_AUTOTSLEEP;
>>  
>>      ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts);
>> -    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
>> +    mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
>> +        MIIF_DOPAUSE);
>>  
>>      if (LIST_FIRST(&mii->mii_phys) == NULL) {
>>          ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
>> @@ -808,6 +810,23 @@ axen_newbuf(void)
>>      return m;
>>  }
>>  
>> +static void *
>> +axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
>> +{
>> +    struct usbd_bus *bus = xfer->device->bus;
>> +    usbd_status err;
>> +
>> +#ifdef DIAGNOSTIC
>> +    if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
>> +        printf("axen_alloc_buffer: xfer already has a buffer\n");
>> +#endif
>> +    err = usb_allocmem(bus, size, 65536, &xfer->dmabuf);
>> +    if (err)
>> +        return (NULL);
>> +    xfer->rqflags |= URQ_DEV_DMABUF;
>> +    return (KERNADDR(&xfer->dmabuf, 0));
>> +}
>> +
>>  int
>>  axen_rx_list_init(struct axen_softc *sc)
>>  {
>> @@ -827,7 +846,7 @@ axen_rx_list_init(struct axen_softc *sc)
>>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>>              if (c->axen_xfer == NULL)
>>                  return ENOBUFS;
>> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
>> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>>                  sc->axen_bufsz);
>>              if (c->axen_buf == NULL) {
>>                  usbd_free_xfer(c->axen_xfer);
>> @@ -858,7 +877,7 @@ axen_tx_list_init(struct axen_softc *sc)
>>              c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>>              if (c->axen_xfer == NULL)
>>                  return ENOBUFS;
>> -            c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
>> +            c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>>                  sc->axen_bufsz);
>>              if (c->axen_buf == NULL) {
>>                  usbd_free_xfer(c->axen_xfer);
>> @@ -888,7 +907,6 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>>      u_int32_t        *hdr_p;
>>      u_int16_t        hdr_offset, pkt_count;
>>      size_t            pkt_len;
>> -    size_t            temp;
>>      int            s;
>>  
>>      DPRINTFN(10,("%s: %s: enter\n", sc->axen_dev.dv_xname,__func__));
>> @@ -914,10 +932,19 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
>> usbd_st
>>      usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
>>  
>>      if (total_len < sizeof(pkt_hdr)) {
>> +        printf("%s: rxeof: too short transfer\n",
>> +            sc->axen_dev.dv_xname);
>>          ifp->if_ierrors++;
>>          goto done;
>>      }
>>  
>> +    if (total_len > sc->axen_bufsz) {
>> +        printf("%s: rxeof: too large transfer\n",
>> +            sc->axen_dev.dv_xname);
>> +        ifp->if_ierrors++;
>> +        goto done;
>> +    }
>> +
>>      /*
>>       * buffer map
>>       * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
>> @@ -928,16 +955,10 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
>> usbd_st
>>      hdr_offset = (u_int16_t)(rx_hdr >> 16);
>>      pkt_count  = (u_int16_t)(rx_hdr & 0xffff);
>>  
>> -    if (total_len > sc->axen_bufsz) {
>> -        printf("%s: rxeof: too large transfer\n",
>> -            sc->axen_dev.dv_xname);
>> -        goto done;
>> -    }
>> -
>>      /* sanity check */
>>      if (hdr_offset > total_len) {
>> -        ifp->if_ierrors++;
>>          usbd_delay_ms(sc->axen_udev, 100);
>> +        ifp->if_ierrors++;
>>          goto done;
>>      }
>>  
>> @@ -954,11 +975,14 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
>> usbd_st
>>      if (pkt_count > AXEN_MAX_PACKED_PACKET) {
>>          DPRINTF(("Too many packets (%d) in a transaction, discard.\n",
>>              pkt_count));
>> +        ifp->if_ierrors++;
>>          goto done;
>>      }
>>  #endif
>>  
>> -    do {
>> +    for (; pkt_count > 0; pkt_count--) {
>> +        uint16_t csum_flags = 0;
>> +
>>          if ((buf[0] != 0xee) || (buf[1] != 0xee)){
>>              printf("%s: invalid buffer(pkt#%d), continue\n",
>>                  sc->axen_dev.dv_xname, pkt_count);
>> @@ -972,34 +996,31 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
>> usbd_st
>>          DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
>>             pkt_count, pkt_hdr, pkt_len));
>>  
>> +        if (pkt_len > MCLBYTES || pkt_len < ETHER_MIN_LEN) {
>> +            printf("%s: invalid pkt_len %zu\n",
>> +                sc->axen_dev.dv_xname,pkt_len);
>> +            ifp->if_ierrors++;
>> +            goto nextpkt;
>> +        }
>> +
>>          if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) ||
>>                  (pkt_hdr & AXEN_RXHDR_DROP_ERR)) {
>> -                ifp->if_ierrors++;
>>              /* move to next pkt header */
>>              DPRINTF(("crc err(pkt#%d)\n", pkt_count));
>> +                ifp->if_ierrors++;
>>              goto nextpkt;
>>          }
>>  
>> -        /* process each packet */
>> -        /* allocate mbuf */
>> -        m = axen_newbuf();
>> -        if (m == NULL) {
>> -            ifp->if_ierrors++;
>> -            goto nextpkt;
>> -        }
>> -
>> -        /* skip pseudo header (2byte) and trailer padding (4Byte) */
>> -        m->m_pkthdr.len = m->m_len = pkt_len - 6;
>> -
>>  #ifdef AXEN_TOE
>>          /* cheksum err */
>>          if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) ||
>>              (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) {
>>              printf("%s: checksum err (pkt#%d)\n",
>>                  sc->axen_dev.dv_xname, pkt_count);
>> +            ifp->if_ierrors++;
>>              goto nextpkt;
>>          } else {
>> -            m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
>> +            csum_flags |= M_IPV4_CSUM_IN_OK;
>>          }
>>  
>>          int l4_type;
>> @@ -1008,12 +1029,23 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv,
>> usbd_st
>>  
>>          if ((l4_type == AXEN_RXHDR_L4_TYPE_TCP) ||
>>              (l4_type == AXEN_RXHDR_L4_TYPE_UDP))
>> -            m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
>> -                M_UDP_CSUM_IN_OK;
>> +            csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
>>  #endif
>>  
>> -        memcpy(mtod(m, char *), buf + 2, pkt_len - 6);
>> +        /* process each packet */
>> +        /* allocate mbuf */
>> +        m = axen_newbuf();
>> +        if (m == NULL) {
>> +            ifp->if_ierrors++;
>> +            goto nextpkt;
>> +        }
>>  
>> +        /* skip pseudo header (2byte) and trailer padding (4Byte) */
>> +        m->m_pkthdr.len = m->m_len = pkt_len - 6;
>> +        m->m_pkthdr.csum_flags |= csum_flags;
>> +
>> +        memcpy(mtod(m, char *), buf + 2, m->m_len);
>> +
>>          ml_enqueue(&ml, m);
>>  
>>  nextpkt:
>> @@ -1022,11 +1054,9 @@ nextpkt:
>>           * as each packet will be aligned 8byte boundary,
>>           * need to fix up the start point of the buffer.
>>           */
>> -        temp = ((pkt_len + 7) & 0xfff8);
>> -        buf = buf + temp;
>> +        buf += roundup(pkt_len, 8);
>>          hdr_p++;
>> -        pkt_count--;
>> -    } while( pkt_count > 0);
>> +    }
>>  
>>  done:
>>      /* push the packet up */
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

sc.dying
Hi,

On 2018/08/14 08:19, Denis wrote:
> I have 6.3 kernel compiled with option XHCI_debug and axen2.diff
> implemented.
>
> I'm using lladdr option for /etc/hostname.axen0 to have the same IP addr
> each session for different Ehternet adapters.
>
> Here is debug output when axen is connected:

Thank you for sending report.

It looks someone (maybe DHCP) makes the interface down and up repeatedly.
That causes TXERR (transaction error) on RX pipe.
I guess there is something inconsistent between the state of xhci and
the device. xhci spec 1.1 sec 4.3.5 requires the driver shall do
set_config and configure endpoint.

I added set_config part to axen2.diff and attached as axen3.diff.
Can you try attached axen3.diff?

Thanks.

>
> xhci0: port=2 change=0x04
> xhci0: port=2 change=0x04
> xhci0: xhci_cmd_slot_control
> xhci0: dev 1, input=0xffffff0001988000 slot=0xffffff0001988020
> ep0=0xffffff0001988040
> xhci0: dev 1, setting DCBAA to 0x0000000001989000
> xhci_pipe_init: pipe=0xffff800000a8d000 addr=0 depth=1 port=2 speed=4
> dev 1 dci 1 (epAddr=0x0)
> xhci0: xhci_cmd_set_address BSR=1
> xhci0: xhci_cmd_set_address BSR=0
> xhci0: dev 1 addr 1
> axen0 at uhub0 port 2 configuration 1 interface 0 "ASIX Elec. Corp.
> AX88179" rev 3.00/1.00 addr 2
> axen0: AX88179, address xx:xx:xx:xx:xx:xx
> ukphy0 at axen0 phy 3: Generic IEEE 802.3u media interface, rev. 5: OUI
> 0x000732, model 0x0011
> xhci_pipe_init: pipe=0xffff800000b38000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 5 (epAddr=0x82)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff800000bfc000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 6 (epAddr=0x3)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_abort_xfer: xfer=0xffffff044e6aee10 status=IN_PROGRESS
> err=CANCELLED actlen=0 len=65536 idx=0
> xhci0: xhci_cmd_stop_ep dev 1 dci 5
> xhci_event_xfer: stopped xfer=0xffffff044e6aee10
> xhci0: xhci_cmd_set_tr_deq_async dev 1 dci 5
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff800000b3a000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 5 (epAddr=0x82)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff800000b3e000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 6 (epAddr=0x3)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_abort_xfer: xfer=0xffffff044e6aed20 status=IN_PROGRESS
> err=CANCELLED actlen=0 len=65536 idx=42
> xhci0: xhci_cmd_stop_ep dev 1 dci 5
> xhci_event_xfer: stopped xfer=0xffffff044e6aed20
> xhci0: xhci_cmd_set_tr_deq_async dev 1 dci 5
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff800000790000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 5 (epAddr=0x82)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff800000791000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 6 (epAddr=0x3)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: txerr? code 4
> axen0: usb errors on rx: IOERROR
> xhci_abort_xfer: xfer=0xffffff044e6aee10 status=NOT_STARTED
> err=CANCELLED actlen=0 len=65536 idx=-1
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff8000007a9000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 5 (epAddr=0x82)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff8000007aa000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 6 (epAddr=0x3)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: txerr? code 4
> axen0: usb errors on rx: IOERROR
> xhci0: txerr? code 4
> axen0: usb error on tx: IOERROR
> axen0: watchdog timeout
> axen0: usb error on tx: IOERROR
> xhci_abort_xfer: xfer=0xffffff044e6aed20 status=NOT_STARTED
> err=CANCELLED actlen=0 len=65536 idx=-1
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff800000865000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 5 (epAddr=0x82)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff800000866000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 6 (epAddr=0x3)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: txerr? code 4
> axen0: usb errors on rx: IOERROR
> xhci0: txerr? code 4
> axen0: usb error on tx: IOERROR
> xhci_abort_xfer: xfer=0xffffff044e6aee10 status=NOT_STARTED
> err=CANCELLED actlen=0 len=65536 idx=-1
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff80000087e000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 5 (epAddr=0x82)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci_pipe_init: pipe=0xffff80000087f000 addr=2 depth=1 port=2 speed=4
> dev 1 dci 6 (epAddr=0x3)
> xhci0: xhci_cmd_configure_ep dev 1
> xhci0: txerr? code 4
> axen0: usb errors on rx: IOERROR
> xhci0: txerr? code 4
> axen0: usb error on tx: IOERROR
> axen0: watchdog timeout
>
>


axen3.diff (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Denis Lapshin-2
Hi,

24 hour full load testing shows positive results.

After axen3.diff has been implemented there is no TX/RX error present at
all. But 'checksum err (pkt#1)' appears repeatedly like this:

...
checksum err (pkt#1)
checksum err (pkt#1)
checksum err (pkt#1)
...

You're right DHCP client is working for axen0:

# cat /etc/hostname.axen0
dhcp lladdr yy.yy.yy.yy.yy

What can cause 'checksum err (pkt#1)' for axen?

Denis

On 8/15/2018 2:29 AM, [hidden email] wrote:

> Hi,
>
> On 2018/08/14 08:19, Denis wrote:
>> I have 6.3 kernel compiled with option XHCI_debug and axen2.diff
>> implemented.
>>
>> I'm using lladdr option for /etc/hostname.axen0 to have the same IP addr
>> each session for different Ehternet adapters.
>>
>> Here is debug output when axen is connected:
>
> Thank you for sending report.
>
> It looks someone (maybe DHCP) makes the interface down and up repeatedly.
> That causes TXERR (transaction error) on RX pipe.
> I guess there is something inconsistent between the state of xhci and
> the device. xhci spec 1.1 sec 4.3.5 requires the driver shall do
> set_config and configure endpoint.
>
> I added set_config part to axen2.diff and attached as axen3.diff.
> Can you try attached axen3.diff?
>
> Thanks.
>
>>
>> xhci0: port=2 change=0x04
>> xhci0: port=2 change=0x04
>> xhci0: xhci_cmd_slot_control
>> xhci0: dev 1, input=0xffffff0001988000 slot=0xffffff0001988020
>> ep0=0xffffff0001988040
>> xhci0: dev 1, setting DCBAA to 0x0000000001989000
>> xhci_pipe_init: pipe=0xffff800000a8d000 addr=0 depth=1 port=2 speed=4
>> dev 1 dci 1 (epAddr=0x0)
>> xhci0: xhci_cmd_set_address BSR=1
>> xhci0: xhci_cmd_set_address BSR=0
>> xhci0: dev 1 addr 1
>> axen0 at uhub0 port 2 configuration 1 interface 0 "ASIX Elec. Corp.
>> AX88179" rev 3.00/1.00 addr 2
>> axen0: AX88179, address xx:xx:xx:xx:xx:xx
>> ukphy0 at axen0 phy 3: Generic IEEE 802.3u media interface, rev. 5: OUI
>> 0x000732, model 0x0011
>> xhci_pipe_init: pipe=0xffff800000b38000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 5 (epAddr=0x82)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff800000bfc000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 6 (epAddr=0x3)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_abort_xfer: xfer=0xffffff044e6aee10 status=IN_PROGRESS
>> err=CANCELLED actlen=0 len=65536 idx=0
>> xhci0: xhci_cmd_stop_ep dev 1 dci 5
>> xhci_event_xfer: stopped xfer=0xffffff044e6aee10
>> xhci0: xhci_cmd_set_tr_deq_async dev 1 dci 5
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff800000b3a000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 5 (epAddr=0x82)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff800000b3e000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 6 (epAddr=0x3)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_abort_xfer: xfer=0xffffff044e6aed20 status=IN_PROGRESS
>> err=CANCELLED actlen=0 len=65536 idx=42
>> xhci0: xhci_cmd_stop_ep dev 1 dci 5
>> xhci_event_xfer: stopped xfer=0xffffff044e6aed20
>> xhci0: xhci_cmd_set_tr_deq_async dev 1 dci 5
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff800000790000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 5 (epAddr=0x82)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff800000791000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 6 (epAddr=0x3)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: txerr? code 4
>> axen0: usb errors on rx: IOERROR
>> xhci_abort_xfer: xfer=0xffffff044e6aee10 status=NOT_STARTED
>> err=CANCELLED actlen=0 len=65536 idx=-1
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff8000007a9000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 5 (epAddr=0x82)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff8000007aa000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 6 (epAddr=0x3)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: txerr? code 4
>> axen0: usb errors on rx: IOERROR
>> xhci0: txerr? code 4
>> axen0: usb error on tx: IOERROR
>> axen0: watchdog timeout
>> axen0: usb error on tx: IOERROR
>> xhci_abort_xfer: xfer=0xffffff044e6aed20 status=NOT_STARTED
>> err=CANCELLED actlen=0 len=65536 idx=-1
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff800000865000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 5 (epAddr=0x82)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff800000866000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 6 (epAddr=0x3)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: txerr? code 4
>> axen0: usb errors on rx: IOERROR
>> xhci0: txerr? code 4
>> axen0: usb error on tx: IOERROR
>> xhci_abort_xfer: xfer=0xffffff044e6aee10 status=NOT_STARTED
>> err=CANCELLED actlen=0 len=65536 idx=-1
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff80000087e000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 5 (epAddr=0x82)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci_pipe_init: pipe=0xffff80000087f000 addr=2 depth=1 port=2 speed=4
>> dev 1 dci 6 (epAddr=0x3)
>> xhci0: xhci_cmd_configure_ep dev 1
>> xhci0: txerr? code 4
>> axen0: usb errors on rx: IOERROR
>> xhci0: txerr? code 4
>> axen0: usb error on tx: IOERROR
>> axen0: watchdog timeout
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

sc.dying
Hi,

On 2018/08/17 07:40, Denis wrote:
> Hi,
>
> 24 hour full load testing shows positive results.

Good news.

>
> After axen3.diff has been implemented there is no TX/RX error present at
> all. But 'checksum err (pkt#1)' appears repeatedly like this:
>
> ...
> checksum err (pkt#1)
> checksum err (pkt#1)
> checksum err (pkt#1)
> ...
>
> You're right DHCP client is working for axen0:
>
> # cat /etc/hostname.axen0
> dhcp lladdr yy.yy.yy.yy.yy
>
> What can cause 'checksum err (pkt#1)' for axen?

It might be another bug of axen(4), or someone on your ethernet segment
really sends bogus packets.
In latter case I don't think axen should report each error to the console.

>
> Denis
>
> On 8/15/2018 2:29 AM, [hidden email] wrote:
>> Hi,
>>
>> On 2018/08/14 08:19, Denis wrote:
>>> I have 6.3 kernel compiled with option XHCI_debug and axen2.diff
>>> implemented.
>>>
>>> I'm using lladdr option for /etc/hostname.axen0 to have the same IP addr
>>> each session for different Ehternet adapters.
>>>
>>> Here is debug output when axen is connected:
>>
>> Thank you for sending report.
>>
>> It looks someone (maybe DHCP) makes the interface down and up repeatedly.
>> That causes TXERR (transaction error) on RX pipe.
>> I guess there is something inconsistent between the state of xhci and
>> the device. xhci spec 1.1 sec 4.3.5 requires the driver shall do
>> set_config and configure endpoint.
>>
>> I added set_config part to axen2.diff and attached as axen3.diff.
>> Can you try attached axen3.diff?
>>
>> Thanks.
>>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Denis Lapshin-2
Hi,

checksum err (pkt#1) appears in dmesg output only.

Right now (after 43 hours of testing) there are 15 rows with checksum
err (pkt#1) message.

Previously, that network segment was connected by em(4), fxp(4), xl(4)
drivers w/o any issues. So the error appears for axen(4) driver
exclusively. It seems axen(4) related issue.

Denis

On 8/17/2018 6:26 PM, sc dying wrote:

> Hi,
>
> On 2018/08/17 07:40, Denis wrote:
>> Hi,
>>
>> 24 hour full load testing shows positive results.
>
> Good news.
>
>>
>> After axen3.diff has been implemented there is no TX/RX error present at
>> all. But 'checksum err (pkt#1)' appears repeatedly like this:
>>
>> ...
>> checksum err (pkt#1)
>> checksum err (pkt#1)
>> checksum err (pkt#1)
>> ...
>>
>> You're right DHCP client is working for axen0:
>>
>> # cat /etc/hostname.axen0
>> dhcp lladdr yy.yy.yy.yy.yy
>>
>> What can cause 'checksum err (pkt#1)' for axen?
>
> It might be another bug of axen(4), or someone on your ethernet segment
> really sends bogus packets.
> In latter case I don't think axen should report each error to the console.
>
>>
>> Denis
>>
>> On 8/15/2018 2:29 AM, [hidden email] wrote:
>>> Hi,
>>>
>>> On 2018/08/14 08:19, Denis wrote:
>>>> I have 6.3 kernel compiled with option XHCI_debug and axen2.diff
>>>> implemented.
>>>>
>>>> I'm using lladdr option for /etc/hostname.axen0 to have the same IP addr
>>>> each session for different Ehternet adapters.
>>>>
>>>> Here is debug output when axen is connected:
>>>
>>> Thank you for sending report.
>>>
>>> It looks someone (maybe DHCP) makes the interface down and up repeatedly.
>>> That causes TXERR (transaction error) on RX pipe.
>>> I guess there is something inconsistent between the state of xhci and
>>> the device. xhci spec 1.1 sec 4.3.5 requires the driver shall do
>>> set_config and configure endpoint.
>>>
>>> I added set_config part to axen2.diff and attached as axen3.diff.
>>> Can you try attached axen3.diff?
>>>
>>> Thanks.
>>>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

Stefan Sperling-5
In reply to this post by sc.dying
Thank you for taking care of axen(4).
The problems with this driver have been known for some time.

On Tue, Aug 07, 2018 at 02:04:24PM +0000, [hidden email] wrote:
>  - header: fix comments
>  - header: fix unused L3 type mask definition
>  - rxeof: Avoid allocating mbuf if checksum errors are detected.
>  - rxeof: Avoid loop to extract packets if pkt_count is 0.
>  - rxeof: Add more sanity checks.
>  - rxeof: Increament if_ierror in some error paths.
>  - qctrl: Apply queuing control parameters from FreeBSD axge(4).
>  - qctrl: Set qctrl in miireg_statchg dynamically, not statically.
>  - Use DMA buffer aligned at 64KB boundary to avoid xhci bug.

You're actually switching to a 64KB buffer size as well, not only to
64KB alignment. That is a relatively large size. The previous code
was using 8KB, 16KB, and 24KB buffers. Do I understand correctly
that the qctrl configuration allows hardware to provide only up
to 0x18*1024 = 24KB bytes of packet data per Rx interrupt?

Regardless, in my opinion your diff improves this driver which
has not seen any regular maintainance in a long time.
If another developer (remi? mlarkin?) provides an OK I will commit it.

> --- sys/dev/usb/if_axenreg.h Fri Sep 16 22:17:07 2016
> +++ sys/dev/usb/if_axenreg.h Mon Jun 19 10:54:28 2017
> @@ -26,8 +26,8 @@
>   *                     |    |     ++-----L3_type (1:ipv4, 0/2:ipv6)
>   *        pkt_len(13)  |    |     ||+ ++-L4_type(0: icmp, 1: UDP, 4: TCP)
>   * |765|43210 76543210|7654 3210 7654 3210|
> - *  ||+-crc_err              |+-L4_err |+-L4_CSUM_ERR
> - *  |+-mii_err               +--L3_err +--L3_CSUM_ERR
> + *  ||+-crc_err               |+-L4_err |+-L4_CSUM_ERR
> + *  |+-mii_err                +--L3_err +--L3_CSUM_ERR
>   *  +-drop_err
>   *
>   * ex) pkt_hdr 0x00680820
> @@ -70,7 +70,7 @@
>  #define   AXEN_RXHDR_L4_TYPE_TCP 0x4
>  
>  /* L3 packet type (2bit) */
> -#define AXEN_RXHDR_L3_TYPE_MASK 0x00000600
> +#define AXEN_RXHDR_L3_TYPE_MASK 0x00000060
>  #define AXEN_RXHDR_L3_TYPE_OFFSET 5
>  #define   AXEN_RXHDR_L3_TYPE_UNDEF 0x0
>  #define   AXEN_RXHDR_L3_TYPE_IPV4 0x1
> --- sys/dev/usb/if_axen.c.orig Tue Jun 12 15:36:59 2018
> +++ sys/dev/usb/if_axen.c Sun Jul 29 01:53:43 2018
> @@ -53,6 +53,7 @@
>  #include <dev/usb/usbdi_util.h>
>  #include <dev/usb/usbdivar.h>
>  #include <dev/usb/usbdevs.h>
> +#include <dev/usb/usb_mem.h>
>  
>  #include <dev/usb/if_axenreg.h>
>  
> @@ -121,6 +122,13 @@ void axen_unlock_mii(struct axen_softc *sc);
>  
>  void axen_ax88179_init(struct axen_softc *);
>  
> +struct axen_qctrl axen_bulk_size[] = {
> + { 7, 0x4f, 0x00, 0x12, 0xff },
> + { 7, 0x20, 0x03, 0x16, 0xff },
> + { 7, 0xae, 0x07, 0x18, 0xff },
> + { 7, 0xcc, 0x4c, 0x18, 0x08 }
> +};
> +
>  /* Get exclusive access to the MII registers */
>  void
>  axen_lock_mii(struct axen_softc *sc)
> @@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev)
>   int err;
>   uint16_t val;
>   uWord wval;
> + uint8_t linkstat = 0;
> + int qctrl;
>  
>   ifp = GET_IFP(sc);
>   if (mii == NULL || ifp == NULL ||
> @@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev)
>   return;
>  
>   val = 0;
> - if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
> + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
>   val |= AXEN_MEDIUM_FDX;
> + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
> + val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
> + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
> + val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
> + }
>  
> - val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE);
> - val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN);
> + val |= AXEN_MEDIUM_RECV_EN;
>  
> + /* bulkin queue setting */
> + axen_lock_mii(sc);
> + axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat);
> + axen_unlock_mii(sc);
> +
>   switch (IFM_SUBTYPE(mii->mii_media_active)) {
>   case IFM_1000_T:
>   val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
> + if (linkstat & AXEN_USB_SS)
> + qctrl = 0;
> + else if (linkstat & AXEN_USB_HS)
> + qctrl = 1;
> + else
> + qctrl = 3;
>   break;
>   case IFM_100_TX:
>   val |= AXEN_MEDIUM_PS;
> + if (linkstat & (AXEN_USB_SS | AXEN_USB_HS))
> + qctrl = 2;
> + else
> + qctrl = 3;
>   break;
>   case IFM_10_T:
> - /* doesn't need to be handled */
> + default:
> + qctrl = 3;
>   break;
>   }
>  
>   DPRINTF(("axen_miibus_statchg: val=0x%x\n", val));
>   USETW(wval, val);
>   axen_lock_mii(sc);
> + axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
> +    &axen_bulk_size[qctrl]);
>   err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
>   axen_unlock_mii(sc);
>   if (err) {
> @@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc)
>   uWord wval;
>   uByte val;
>   u_int16_t ctl, temp;
> - struct axen_qctrl qctrl;
>  
>   axen_lock_mii(sc);
>  
> @@ -471,27 +502,12 @@ axen_ax88179_init(struct axen_softc *sc)
>   switch (val) {
>   case AXEN_USB_FS:
>   DPRINTF(("uplink: USB1.1\n"));
> - qctrl.ctrl = 0x07;
> - qctrl.timer_low = 0xcc;
> - qctrl.timer_high= 0x4c;
> - qctrl.bufsize = AXEN_BUFSZ_LS - 1;
> - qctrl.ifg = 0x08;
>   break;
>   case AXEN_USB_HS:
>   DPRINTF(("uplink: USB2.0\n"));
> - qctrl.ctrl = 0x07;
> - qctrl.timer_low = 0x02;
> - qctrl.timer_high= 0xa0;
> - qctrl.bufsize = AXEN_BUFSZ_HS - 1;
> - qctrl.ifg = 0xff;
>   break;
>   case AXEN_USB_SS:
>   DPRINTF(("uplink: USB3.0\n"));
> - qctrl.ctrl = 0x07;
> - qctrl.timer_low = 0x4f;
> - qctrl.timer_high= 0x00;
> - qctrl.bufsize = AXEN_BUFSZ_SS - 1;
> - qctrl.ifg = 0xff;
>   break;
>   default:
>   printf("%s: unknown uplink bus:0x%02x\n",
> @@ -499,7 +515,6 @@ axen_ax88179_init(struct axen_softc *sc)
>   axen_unlock_mii(sc);
>   return;
>   }
> - axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
>  
>   /* Set MAC address. */
>   axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN,
> @@ -622,22 +637,8 @@ axen_attach(struct device *parent, struct device *self
>  
>   id = usbd_get_interface_descriptor(sc->axen_iface);
>  
> - /* decide on what our bufsize will be */
> - switch (sc->axen_udev->speed) {
> - case USB_SPEED_FULL:
> -     sc->axen_bufsz = AXEN_BUFSZ_LS * 1024;
> - break;
> - case USB_SPEED_HIGH:
> -     sc->axen_bufsz = AXEN_BUFSZ_HS * 1024;
> - break;
> - case USB_SPEED_SUPER:
> -     sc->axen_bufsz = AXEN_BUFSZ_SS * 1024;
> - break;
> - default:
> - printf("%s: not supported usb bus type", sc->axen_dev.dv_xname);
> - return;
> - }
> -
> + sc->axen_bufsz = 64 * 1024;
> +
>   /* Find endpoints. */
>   for (i = 0; i < id->bNumEndpoints; i++) {
>   ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i);
> @@ -710,7 +711,8 @@ axen_attach(struct device *parent, struct device *self
>   mii->mii_flags = MIIF_AUTOTSLEEP;
>  
>   ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts);
> - mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
> + mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
> +    MIIF_DOPAUSE);
>  
>   if (LIST_FIRST(&mii->mii_phys) == NULL) {
>   ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
> @@ -808,6 +810,23 @@ axen_newbuf(void)
>   return m;
>  }
>  
> +static void *
> +axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
> +{
> + struct usbd_bus *bus = xfer->device->bus;
> + usbd_status err;
> +
> +#ifdef DIAGNOSTIC
> + if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
> + printf("axen_alloc_buffer: xfer already has a buffer\n");
> +#endif
> + err = usb_allocmem(bus, size, 65536, &xfer->dmabuf);
> + if (err)
> + return (NULL);
> + xfer->rqflags |= URQ_DEV_DMABUF;
> + return (KERNADDR(&xfer->dmabuf, 0));
> +}
> +
>  int
>  axen_rx_list_init(struct axen_softc *sc)
>  {
> @@ -827,7 +846,7 @@ axen_rx_list_init(struct axen_softc *sc)
>   c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>   if (c->axen_xfer == NULL)
>   return ENOBUFS;
> - c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> + c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>      sc->axen_bufsz);
>   if (c->axen_buf == NULL) {
>   usbd_free_xfer(c->axen_xfer);
> @@ -858,7 +877,7 @@ axen_tx_list_init(struct axen_softc *sc)
>   c->axen_xfer = usbd_alloc_xfer(sc->axen_udev);
>   if (c->axen_xfer == NULL)
>   return ENOBUFS;
> - c->axen_buf = usbd_alloc_buffer(c->axen_xfer,
> + c->axen_buf = axen_alloc_buffer(c->axen_xfer,
>      sc->axen_bufsz);
>   if (c->axen_buf == NULL) {
>   usbd_free_xfer(c->axen_xfer);
> @@ -888,7 +907,6 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>   u_int32_t *hdr_p;
>   u_int16_t hdr_offset, pkt_count;
>   size_t pkt_len;
> - size_t temp;
>   int s;
>  
>   DPRINTFN(10,("%s: %s: enter\n", sc->axen_dev.dv_xname,__func__));
> @@ -914,10 +932,19 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>   usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
>  
>   if (total_len < sizeof(pkt_hdr)) {
> + printf("%s: rxeof: too short transfer\n",
> +    sc->axen_dev.dv_xname);
>   ifp->if_ierrors++;
>   goto done;
>   }
>  
> + if (total_len > sc->axen_bufsz) {
> + printf("%s: rxeof: too large transfer\n",
> +    sc->axen_dev.dv_xname);
> + ifp->if_ierrors++;
> + goto done;
> + }
> +
>   /*
>   * buffer map
>   * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr]
> @@ -928,16 +955,10 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>   hdr_offset = (u_int16_t)(rx_hdr >> 16);
>   pkt_count  = (u_int16_t)(rx_hdr & 0xffff);
>  
> - if (total_len > sc->axen_bufsz) {
> - printf("%s: rxeof: too large transfer\n",
> -    sc->axen_dev.dv_xname);
> - goto done;
> - }
> -
>   /* sanity check */
>   if (hdr_offset > total_len) {
> - ifp->if_ierrors++;
>   usbd_delay_ms(sc->axen_udev, 100);
> + ifp->if_ierrors++;
>   goto done;
>   }
>  
> @@ -954,11 +975,14 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>   if (pkt_count > AXEN_MAX_PACKED_PACKET) {
>   DPRINTF(("Too many packets (%d) in a transaction, discard.\n",
>      pkt_count));
> + ifp->if_ierrors++;
>   goto done;
>   }
>  #endif
>  
> - do {
> + for (; pkt_count > 0; pkt_count--) {
> + uint16_t csum_flags = 0;
> +
>   if ((buf[0] != 0xee) || (buf[1] != 0xee)){
>   printf("%s: invalid buffer(pkt#%d), continue\n",
>      sc->axen_dev.dv_xname, pkt_count);
> @@ -972,34 +996,31 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>   DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
>     pkt_count, pkt_hdr, pkt_len));
>  
> + if (pkt_len > MCLBYTES || pkt_len < ETHER_MIN_LEN) {
> + printf("%s: invalid pkt_len %zu\n",
> +    sc->axen_dev.dv_xname,pkt_len);
> + ifp->if_ierrors++;
> + goto nextpkt;
> + }
> +
>   if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) ||
>          (pkt_hdr & AXEN_RXHDR_DROP_ERR)) {
> -     ifp->if_ierrors++;
>   /* move to next pkt header */
>   DPRINTF(("crc err(pkt#%d)\n", pkt_count));
> +     ifp->if_ierrors++;
>   goto nextpkt;
>   }
>  
> - /* process each packet */
> - /* allocate mbuf */
> - m = axen_newbuf();
> - if (m == NULL) {
> - ifp->if_ierrors++;
> - goto nextpkt;
> - }
> -
> - /* skip pseudo header (2byte) and trailer padding (4Byte) */
> - m->m_pkthdr.len = m->m_len = pkt_len - 6;
> -
>  #ifdef AXEN_TOE
>   /* cheksum err */
>   if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) ||
>      (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) {
>   printf("%s: checksum err (pkt#%d)\n",
>      sc->axen_dev.dv_xname, pkt_count);
> + ifp->if_ierrors++;
>   goto nextpkt;
>   } else {
> - m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
> + csum_flags |= M_IPV4_CSUM_IN_OK;
>   }
>  
>   int l4_type;
> @@ -1008,12 +1029,23 @@ axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_st
>  
>   if ((l4_type == AXEN_RXHDR_L4_TYPE_TCP) ||
>      (l4_type == AXEN_RXHDR_L4_TYPE_UDP))
> - m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
> -    M_UDP_CSUM_IN_OK;
> + csum_flags |= M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
>  #endif
>  
> - memcpy(mtod(m, char *), buf + 2, pkt_len - 6);
> + /* process each packet */
> + /* allocate mbuf */
> + m = axen_newbuf();
> + if (m == NULL) {
> + ifp->if_ierrors++;
> + goto nextpkt;
> + }
>  
> + /* skip pseudo header (2byte) and trailer padding (4Byte) */
> + m->m_pkthdr.len = m->m_len = pkt_len - 6;
> + m->m_pkthdr.csum_flags |= csum_flags;
> +
> + memcpy(mtod(m, char *), buf + 2, m->m_len);
> +
>   ml_enqueue(&ml, m);
>  
>  nextpkt:
> @@ -1022,11 +1054,9 @@ nextpkt:
>   * as each packet will be aligned 8byte boundary,
>   * need to fix up the start point of the buffer.
>   */
> - temp = ((pkt_len + 7) & 0xfff8);
> - buf = buf + temp;
> + buf += roundup(pkt_len, 8);
>   hdr_p++;
> - pkt_count--;
> - } while( pkt_count > 0);
> + }
>  
>  done:
>   /* push the packet up */
> @@ -1260,6 +1290,14 @@ axen_init(void *xsc)
>   * Cancel pending I/O and free all RX/TX buffers.
>   */
>   axen_reset(sc);
> +
> +#define AXEN_CONFIG_NO 1
> +#define AXEN_IFACE_IDX 0
> + if (usbd_set_config_no(sc->axen_udev, AXEN_CONFIG_NO, 1) ||
> +    usbd_device2interface_handle(sc->axen_udev, AXEN_IFACE_IDX,
> + &sc->axen_iface))
> + printf("%s: set_config failed\n", sc->axen_dev.dv_xname);
> + usbd_delay_ms(sc->axen_udev, 10);
>  
>   /* XXX: ? */
>   bval = 0x01;
>

Reply | Threaded
Open this post in threaded view
|

Re: axen Ethernet device errors on both USB3.0 and USB2.0 ports

sc.dying
In reply to this post by Denis Lapshin-2
Hi,

On 2018/08/18 07:37, Denis wrote:

> Hi,
>
> checksum err (pkt#1) appears in dmesg output only.
>
> Right now (after 43 hours of testing) there are 15 rows with checksum
> err (pkt#1) message.
>
> Previously, that network segment was connected by em(4), fxp(4), xl(4)
> drivers w/o any issues. So the error appears for axen(4) driver
> exclusively. It seems axen(4) related issue.
ierrs of netstat -in of these interfaces are 0?

I added printf more informations about checksum error,
and attached as axen4.diff.
If you are interested in the packet body, you can see hexdump of
the error packet by changing #if 0 to #if 1 in axen_rxeof().
Note that the hexdump includes MAC addresses and IP addresses.

BTW original axen code leaks mbuf if checksum errors occurs.
You can see mbuf usage is increasing when cksum error occur.
This patch will fix that bug, too.

>
> Denis
>
> On 8/17/2018 6:26 PM, sc dying wrote:
>> Hi,
>>
>> On 2018/08/17 07:40, Denis wrote:
>>> Hi,
>>>
>>> 24 hour full load testing shows positive results.
>>
>> Good news.
>>
>>>
>>> After axen3.diff has been implemented there is no TX/RX error present at
>>> all. But 'checksum err (pkt#1)' appears repeatedly like this:
>>>
>>> ...
>>> checksum err (pkt#1)
>>> checksum err (pkt#1)
>>> checksum err (pkt#1)
>>> ...
>>>
>>> You're right DHCP client is working for axen0:
>>>
>>> # cat /etc/hostname.axen0
>>> dhcp lladdr yy.yy.yy.yy.yy
>>>
>>> What can cause 'checksum err (pkt#1)' for axen?
>>
>> It might be another bug of axen(4), or someone on your ethernet segment
>> really sends bogus packets.
>> In latter case I don't think axen should report each error to the console.
>>
>>>
>>> Denis
>>>
>>> On 8/15/2018 2:29 AM, [hidden email] wrote:
>>>> Hi,
>>>>
>>>> On 2018/08/14 08:19, Denis wrote:
>>>>> I have 6.3 kernel compiled with option XHCI_debug and axen2.diff
>>>>> implemented.
>>>>>
>>>>> I'm using lladdr option for /etc/hostname.axen0 to have the same IP addr
>>>>> each session for different Ehternet adapters.
>>>>>
>>>>> Here is debug output when axen is connected:
>>>>
>>>> Thank you for sending report.
>>>>
>>>> It looks someone (maybe DHCP) makes the interface down and up repeatedly.
>>>> That causes TXERR (transaction error) on RX pipe.
>>>> I guess there is something inconsistent between the state of xhci and
>>>> the device. xhci spec 1.1 sec 4.3.5 requires the driver shall do
>>>> set_config and configure endpoint.
>>>>
>>>> I added set_config part to axen2.diff and attached as axen3.diff.
>>>> Can you try attached axen3.diff?
>>>>
>>>> Thanks.
>>>>
>


axen4.diff (10K) Download Attachment
12