Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Решение проблем связванных с работой железа. Проблемы программно-аппаратной совместимости.
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
minimatronik
проходил мимо

Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение minimatronik » 2014-11-16 15:25:42

Здравствуйте.
Не могу заставить работать wifi адаптер Trendnet TEW-646UBH. Чипсет судя по https://wikidevi.com/wiki/TRENDnet_TEW-646UBH Realtek RTL8188SU, который поддерживается драйвером rsu. В файлах драйвера от производителя - драйвер для чипсета RTL8192SU, который тоже поддерживается. Драйвер RSU загружен:

Код: Выделить всё

Id Refs Address            Size     Name
 1   32 0xffffffff80200000 1755658  kernel
 2    1 0xffffffff81956000 11010    if_rsu.ko
 3    1 0xffffffff81968000 1f520    rsu-rtl8712fw.ko
 4    1 0xffffffff81a11000 357f     ums.ko
 5    1 0xffffffff81a15000 2b58     uhid.ko
 6    2 0xffffffff81a18000 e792     if_ndis.ko
 7    2 0xffffffff81a27000 147b2    ndis.ko
 8    1 0xffffffff81a3c000 190011   athur_sys.ko
После подключения адаптера в ifconfig соединеня нету, в dmesg ugen0.3: <vendor 0x20f4> at usbus0 :

Код: Выделить всё

Copyright (c) 1992-2014 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
	The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 10.1-RELEASE #0 r274401: Tue Nov 11 21:02:49 UTC 2014
    root@releng1.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64
FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512
module ath_pci already present!
CPU: Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz (3292.60-MHz K8-class CPU)
  Origin = "GenuineIntel"  Id = 0x306a9  Family = 0x6  Model = 0x3a  Stepping = 9
  Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
  Features2=0x3d9ae3bf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,POPCNT,TSCDLT,XSAVE,OSXSAVE,AVX,F16C>
  AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
  AMD Features2=0x1<LAHF>
  Structured Extended Features=0x281<FSGSBASE,SMEP,ERMS>
  VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID
  TSC: P-state invariant, performance statistics
real memory  = 8589934592 (8192 MB)
avail memory = 8225656832 (7844 MB)
Event timer "LAPIC" quality 600
ACPI APIC Table: <ALASKA A M I>
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
FreeBSD/SMP: 1 package(s) x 2 core(s) x 2 SMT threads
 cpu0 (BSP): APIC ID:  0
 cpu1 (AP): APIC ID:  1
 cpu2 (AP): APIC ID:  2
 cpu3 (AP): APIC ID:  3
ioapic0 <Version 2.0> irqs 0-23 on motherboard
kbd1 at kbdmux0
random: <Software, Yarrow> initialized
acpi0: <ALASKA A M I> on motherboard
acpi0: Power Button (fixed)
acpi0: reservation of 67, 1 (4) failed
cpu0: <ACPI CPU> on acpi0
cpu1: <ACPI CPU> on acpi0
cpu2: <ACPI CPU> on acpi0
cpu3: <ACPI CPU> on acpi0
hpet0: <High Precision Event Timer> iomem 0xfed00000-0xfed003ff on acpi0
Timecounter "HPET" frequency 14318180 Hz quality 950
Event timer "HPET" frequency 14318180 Hz quality 550
Event timer "HPET1" frequency 14318180 Hz quality 440
Event timer "HPET2" frequency 14318180 Hz quality 440
Event timer "HPET3" frequency 14318180 Hz quality 440
Event timer "HPET4" frequency 14318180 Hz quality 440
atrtc0: <AT realtime clock> port 0x70-0x77 irq 8 on acpi0
atrtc0: Warning: Couldn't map I/O.
Event timer "RTC" frequency 32768 Hz quality 0
attimer0: <AT timer> port 0x40-0x43,0x50-0x53 irq 0 on acpi0
Timecounter "i8254" frequency 1193182 Hz quality 0
Event timer "i8254" frequency 1193182 Hz quality 100
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
acpi_timer0: <24-bit timer at 3.579545MHz> port 0x408-0x40b on acpi0
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
pci0: <ACPI PCI bus> on pcib0
pcib1: <ACPI PCI-PCI bridge> irq 16 at device 1.0 on pci0
pci1: <ACPI PCI bus> on pcib1
vgapci0: <VGA-compatible display> port 0xe000-0xe07f mem 0xf6000000-0xf6ffffff,0xe8000000-0xefffffff,0xf0000000-0xf1ffffff irq 16 at device 0.0 on pci1
vgapci0: Boot video device
hdac0: <NVIDIA GT108 HDA Controller> mem 0xf7080000-0xf7083fff irq 17 at device 0.1 on pci1
xhci0: <Intel Panther Point USB 3.0 controller> mem 0xf7200000-0xf720ffff irq 16 at device 20.0 on pci0
xhci0: 32 byte context size.
xhci0: Port routing mask set to 0xffffffff
usbus0 on xhci0
pci0: <simple comms> at device 22.0 (no driver attached)
ehci0: <Intel Panther Point USB 2.0 controller> mem 0xf7218000-0xf72183ff irq 16 at device 26.0 on pci0
usbus1: EHCI version 1.0
usbus1 on ehci0
hdac1: <Intel Panther Point HDA Controller> mem 0xf7210000-0xf7213fff irq 22 at device 27.0 on pci0
pcib2: <ACPI PCI-PCI bridge> irq 16 at device 28.0 on pci0
pci2: <ACPI PCI bus> on pcib2
pcib3: <PCI-PCI bridge> at device 0.0 on pci2
pci3: <PCI bus> on pcib3
hdac2: <Generic (0x00091102) HDA Controller> mem 0xf7100000-0xf7103fff irq 16 at device 0.0 on pci3
pcib4: <ACPI PCI-PCI bridge> irq 17 at device 28.5 on pci0
pci4: <ACPI PCI bus> on pcib4
re0: <RealTek 8168/8111 B/C/CP/D/DP/E/F/G PCIe Gigabit Ethernet> port 0xd000-0xd0ff mem 0xf2104000-0xf2104fff,0xf2100000-0xf2103fff irq 17 at device 0.0 on pci4
re0: Using 1 MSI-X message
re0: Chip rev. 0x2c800000
re0: MAC rev. 0x00100000
miibus0: <MII bus> on re0
rgephy0: <RTL8169S/8110S/8211 1000BASE-T media interface> PHY 1 on miibus0
rgephy0:  none, 10baseT, 10baseT-FDX, 10baseT-FDX-flow, 100baseTX, 100baseTX-FDX, 100baseTX-FDX-flow, 1000baseT, 1000baseT-master, 1000baseT-FDX, 1000baseT-FDX-master, 1000baseT-FDX-flow, 1000baseT-FDX-flow-master, auto, auto-flow
re0: Ethernet address: bc:5f:f4:68:4a:e6
ehci1: <Intel Panther Point USB 2.0 controller> mem 0xf7217000-0xf72173ff irq 23 at device 29.0 on pci0
usbus2: EHCI version 1.0
usbus2 on ehci1
isab0: <PCI-ISA bridge> at device 31.0 on pci0
isa0: <ISA bus> on isab0
ahci0: <Intel Panther Point AHCI SATA controller> port 0xf070-0xf077,0xf060-0xf063,0xf050-0xf057,0xf040-0xf043,0xf020-0xf03f mem 0xf7216000-0xf72167ff irq 19 at device 31.2 on pci0
ahci0: AHCI v1.30 with 6 6Gbps ports, Port Multiplier not supported
ahcich0: <AHCI channel> at channel 0 on ahci0
ahcich1: <AHCI channel> at channel 1 on ahci0
ahcich2: <AHCI channel> at channel 2 on ahci0
ahcich3: <AHCI channel> at channel 3 on ahci0
ahcich4: <AHCI channel> at channel 4 on ahci0
ahcich5: <AHCI channel> at channel 5 on ahci0
ahciem0: <AHCI enclosure management bridge> on ahci0
acpi_button0: <Power Button> on acpi0
ppc1: <Parallel port> port 0x378-0x37f,0x778-0x77f irq 5 drq 3 on acpi0
ppc1: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
ppc1: FIFO with 16/16/9 bytes threshold
ppbus0: <Parallel port bus> on ppc1
lpt0: <Printer> on ppbus0
lpt0: Interrupt-driven port
ppi0: <Parallel I/O> on ppbus0
uart0: <16550 or compatible> port 0x3f8-0x3ff irq 4 flags 0x10 on acpi0
sc0: <System console> at flags 0x100 on isa0
sc0: VGA <16 virtual consoles, flags=0x300>
vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
atkbdc0: <Keyboard controller (i8042)> at port 0x60,0x64 on isa0
atkbd0: <AT Keyboard> irq 1 on atkbdc0
kbd0 at atkbd0
atkbd0: [GIANT-LOCKED]
ppc0: cannot reserve I/O port range
est0: <Enhanced SpeedStep Frequency Control> on cpu0
p4tcc0: <CPU Frequency Thermal Control> on cpu0
est1: <Enhanced SpeedStep Frequency Control> on cpu1
p4tcc1: <CPU Frequency Thermal Control> on cpu1
est2: <Enhanced SpeedStep Frequency Control> on cpu2
p4tcc2: <CPU Frequency Thermal Control> on cpu2
est3: <Enhanced SpeedStep Frequency Control> on cpu3
p4tcc3: <CPU Frequency Thermal Control> on cpu3
random: unblocking device.
usbus0: 5.0Gbps Super Speed USB v3.0
Timecounters tick every 1.000 msec
hdacc0: <NVIDIA GT440 HDA CODEC> at cad 0 on hdac0
hdaa0: <NVIDIA GT440 Audio Function Group> at nid 1 on hdacc0
pcm0: <NVIDIA GT440 (HDMI/DP 8ch)> at nid 5 on hdaa0
hdacc1: <NVIDIA GT440 HDA CODEC> at cad 1 on hdac0
hdaa1: <NVIDIA GT440 Audio Function Group> at nid 1 on hdacc1
pcm1: <NVIDIA GT440 (HDMI/DP 8ch)> at nid 5 on hdaa1
hdacc2: <NVIDIA GT440 HDA CODEC> at cad 2 on hdac0
hdaa2: <NVIDIA GT440 Audio Function Group> at nid 1 on hdacc2
pcm2: <NVIDIA GT440 (HDMI/DP 8ch)> at nid 5 on hdaa2
hdacc3: <NVIDIA GT440 HDA CODEC> at cad 3 on hdac0
hdaa3: <NVIDIA GT440 Audio Function Group> at nid 1 on hdacc3
pcm3: <NVIDIA GT440 (HDMI/DP 8ch)> at nid 5 on hdaa3
hdacc4: <Realtek ALC662 HDA CODEC> at cad 0 on hdac1
hdaa4: <Realtek ALC662 Audio Function Group> at nid 1 on hdacc4
pcm4: <Realtek ALC662 (Rear Analog)> at nid 20 and 24,26 on hdaa4
pcm5: <Realtek ALC662 (Front Analog)> at nid 27 and 25 on hdaa4
hdacc5: <Creative CA0110-IBG HDA CODEC> at cad 1 on hdac2
hdaa5: <Creative CA0110-IBG Audio Function Group> at nid 1 on hdacc5
pcm6: <Creative CA0110-IBG (Rear Analog 7.1/2.0)> at nid 11,12,13,14 and 16 on hdaa5
pcm7: <Creative CA0110-IBG (Front Analog)> at nid 15 and 17 on hdaa5
pcm8: <Creative CA0110-IBG (Rear Digital)> at nid 18 and 19 on hdaa5
usbus1: 480Mbps High Speed USB v2.0
usbus2: 480Mbps High Speed USB v2.0
ugen0.1: <0x8086> at usbus0
uhub0: <0x8086 XHCI root HUB, class 9/0, rev 3.00/1.00, addr 1> on usbus0
ugen2.1: <Intel> at usbus2
uhub1: <Intel EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus2
ugen1.1: <Intel> at usbus1
uhub2: <Intel EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus1
ada0 at ahcich1 bus 0 scbus1 target 0 lun 0
ada0: <WDC WD5000AAKX-00ERMA0 15.01H15> ATA-8 SATA 3.x device
ada0: Serial Number WD-WMC2E5040869
ada0: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada0: Command Queueing enabled
ada0: 476940MB (976773168 512 byte sectors: 16H 63S/T 16383C)
ada0: Previously was known as ad6
ses0 at ahciem0 bus 0 scbus6 target 0 lun 0
ses0: <AHCI SGPIO Enclosure 1.00 0001> SEMB S-E-S 2.00 device
ses0: SEMB SES Device
SMP: AP CPU #1 Launched!
SMP: AP CPU #3 Launched!
SMP: AP CPU #2 Launched!
Timecounter "TSC-low" frequency 1646298216 Hz quality 1000
uhub0: 8 ports with 8 removable, self powered
Root mount waiting for: usbus2 usbus1 usbus0
uhub2: 2 ports with 2 removable, self powered
uhub1: 2 ports with 2 removable, self powered
ugen0.2: <Genius> at usbus0
Root mount waiting for: usbus2 usbus1 usbus0
ugen2.2: <vendor 0x8087> at usbus2
uhub3: <vendor 0x8087 product 0x0024, class 9/0, rev 2.00/0.00, addr 2> on usbus2
ugen1.2: <vendor 0x8087> at usbus1
uhub4: <vendor 0x8087 product 0x0024, class 9/0, rev 2.00/0.00, addr 2> on usbus1
ugen0.3: <ATHEROS> at usbus0
uhub4: 6 ports with 6 removable, self powered
uhub3: 6 ports with 6 removable, self powered
Root mount waiting for: usbus2
ugen2.3: <vendor 0x09da> at usbus2
ukbd0: <vendor 0x09da USB Keyboard, class 0/0, rev 1.10/2.50, addr 3> on usbus2
kbd2 at ukbd0
Trying to mount root from ufs:/dev/ada0s1a [rw]...
ums0: <Genius Optical Mouse, class 0/0, rev 1.10/1.00, addr 1> on usbus0
ums0: 3 buttons and [XYZ] coordinates ID=0
uhid0: <vendor 0x09da USB Keyboard, class 0/0, rev 1.10/2.50, addr 3> on usbus2
ugen1.3: <vendor 0x20f4> at usbus1
ugen0.3: <ATHEROS> at usbus0 (disconnected)
ugen1.3: <vendor 0x20f4> at usbus1 (disconnected)
ugen0.3: <vendor 0x20f4> at usbus0
ugen0.3: <vendor 0x20f4> at usbus0 (disconnected)
ugen0.3: <vendor 0x20f4> at usbus0
ifconfig:

Код: Выделить всё

re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:5f:f4:68:4a:e6
	inet 192.168.0.102 netmask 0xffffff00 broadcast 192.168.0.255 
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (none)
	status: no carrier
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
	inet 127.0.0.1 netmask 0xff000000 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
pciconfig -lv

Код: Выделить всё

hostb0@pci0:0:0:0:	class=0x060000 card=0x01501849 chip=0x01508086 rev=0x09 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = 'Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller'
    class      = bridge
    subclass   = HOST-PCI
pcib1@pci0:0:1:0:	class=0x060400 card=0x01511849 chip=0x01518086 rev=0x09 hdr=0x01
    vendor     = 'Intel Corporation'
    device     = 'Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port'
    class      = bridge
    subclass   = PCI-PCI
xhci0@pci0:0:20:0:	class=0x0c0330 card=0x1e311849 chip=0x1e318086 rev=0x04 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family USB xHCI Host Controller'
    class      = serial bus
    subclass   = USB
none0@pci0:0:22:0:	class=0x078000 card=0x1e3a1849 chip=0x1e3a8086 rev=0x04 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family MEI Controller'
    class      = simple comms
ehci0@pci0:0:26:0:	class=0x0c0320 card=0x1e2d1849 chip=0x1e2d8086 rev=0x04 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family USB Enhanced Host Controller'
    class      = serial bus
    subclass   = USB
hdac1@pci0:0:27:0:	class=0x040300 card=0x36621849 chip=0x1e208086 rev=0x04 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family High Definition Audio Controller'
    class      = multimedia
    subclass   = HDA
pcib2@pci0:0:28:0:	class=0x060400 card=0x1e101849 chip=0x1e108086 rev=0xc4 hdr=0x01
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family PCI Express Root Port 1'
    class      = bridge
    subclass   = PCI-PCI
pcib4@pci0:0:28:5:	class=0x060400 card=0x1e1a1849 chip=0x1e1a8086 rev=0xc4 hdr=0x01
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family PCI Express Root Port 6'
    class      = bridge
    subclass   = PCI-PCI
ehci1@pci0:0:29:0:	class=0x0c0320 card=0x1e261849 chip=0x1e268086 rev=0x04 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family USB Enhanced Host Controller'
    class      = serial bus
    subclass   = USB
isab0@pci0:0:31:0:	class=0x060100 card=0x1e491849 chip=0x1e498086 rev=0x04 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = 'B75 Express Chipset LPC Controller'
    class      = bridge
    subclass   = PCI-ISA
ahci0@pci0:0:31:2:	class=0x010601 card=0x1e021849 chip=0x1e028086 rev=0x04 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family 6-port SATA Controller [AHCI mode]'
    class      = mass storage
    subclass   = SATA
none1@pci0:0:31:3:	class=0x0c0500 card=0x1e221849 chip=0x1e228086 rev=0x04 hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '7 Series/C210 Series Chipset Family SMBus Controller'
    class      = serial bus
    subclass   = SMBus
vgapci0@pci0:1:0:0:	class=0x030000 card=0x082810de chip=0x0de010de rev=0xa1 hdr=0x00
    vendor     = 'NVIDIA Corporation'
    device     = 'GF108 [GeForce GT 440]'
    class      = display
    subclass   = VGA
hdac0@pci0:1:0:1:	class=0x040300 card=0x082810de chip=0x0bea10de rev=0xa1 hdr=0x00
    vendor     = 'NVIDIA Corporation'
    device     = 'GF108 High Definition Audio Controller'
    class      = multimedia
    subclass   = HDA
pcib3@pci0:2:0:0:	class=0x060400 card=0x00101102 chip=0x70061102 rev=0x00 hdr=0x01
    vendor     = 'Creative Labs'
    device     = '[SB X-Fi Xtreme Audio] CA0110-IBG PCI to PCIe Bridge'
    class      = bridge
    subclass   = PCI-PCI
hdac2@pci0:3:0:0:	class=0x040300 card=0x00181102 chip=0x00091102 rev=0x00 hdr=0x00
    vendor     = 'Creative Labs'
    device     = '[SB X-Fi Xtreme Audio] CA0110-IBG'
    class      = multimedia
    subclass   = HDA
re0@pci0:4:0:0:	class=0x020000 card=0x81681849 chip=0x816810ec rev=0x06 hdr=0x00
    vendor     = 'Realtek Semiconductor Co., Ltd.'
    device     = 'RTL8111/8168B PCI Express Gigabit Ethernet controller'
    class      = network
    subclass   = ethernet
usbconfig

Код: Выделить всё

ugen0.1: <XHCI root HUB 0x8086> at usbus0, cfg=0 md=HOST spd=SUPER (5.0Gbps) pwr=SAVE (0mA)
ugen2.1: <EHCI root HUB Intel> at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen1.1: <EHCI root HUB Intel> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.2: <Optical Mouse Genius> at usbus0, cfg=0 md=HOST spd=LOW (1.5Mbps) pwr=ON (100mA)
ugen2.2: <product 0x0024 vendor 0x8087> at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen1.2: <product 0x0024 vendor 0x8087> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen2.3: <USB Keyboard vendor 0x09da> at usbus2, cfg=0 md=HOST spd=LOW (1.5Mbps) pwr=ON (100mA)
ugen0.3: <product 0x646b vendor 0x20f4> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (500mA)
uname -a

Код: Выделить всё

FreeBSD localhost 10.1-RELEASE FreeBSD 10.1-RELEASE #0 r274401: Tue Nov 11 21:02:49 UTC 2014     root@releng1.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
P.S. Есть звуковая карточка creative sound blaster x-fi xtreme audio, http://ru.creative.com/p/sound-blaster/ ... ci-express. В списке поддерживаемого оборудования 10 фряхи, все серия x-fi xtreme значится как неподдерживаемая. Запустить никак?

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35437
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение Alex Keda » 2014-11-16 23:18:28

ничё не понял...
у вас звуковушка с WiFi чтоле?
Убей их всех! Бог потом рассортирует...

PYO
сержант
Сообщения: 185
Зарегистрирован: 2011-08-18 12:46:45

Re: Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение PYO » 2014-11-16 23:51:41

creative - никак
TRENDnet - можно попробовать прописать 0x646b в /sys/dev/usb/usbdev, т.е.

Код: Выделить всё

product TRENDNET TEW_646UBH	0x646b	TEW_646UBH
А в /sys/dev/usb/wlan/if_rsu.c добавить

Код: Выделить всё

RSU_DEV_HT(TRENDNET,		TEW_646UBH)
пересобрать модуль и надеяться что заработает

minimatronik
проходил мимо

Re: Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение minimatronik » 2014-11-18 14:50:57

Alex Keda, есть wifi адаптер trendnet и звуковая карта creative

PYO, добавил в /sys/dev/usb/usbdev то что нужно, добавляю в /sys/dev/usb/wlan/if_rsu.c - при выполнение make в директории /sys/modules/usb/rsu выдает ошибки:

Код: Выделить всё

root@localhost:/sys/modules/usb/rsu # make
Warning: Object directory not changed from original /usr/src/sys/modules/usb/rsu
cc -O2 -pipe  -fno-strict-aliasing -Werror -D_KERNEL -DKLD_MODULE -nostdinc   -I. -I@ -I@/contrib/altq -fno-common  -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer  -mno-aes -mno-avx -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -msoft-float  -fno-asynchronous-unwind-tables -ffreestanding -fstack-protector -std=iso9899:1999 -Qunused-arguments  -fstack-protector -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  -Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option  -Wno-error-tautological-compare -Wno-error-empty-body  -Wno-error-parentheses-equality -Wno-error-unused-function   -c /usr/src/sys/modules/usb/rsu/../../../dev/usb/wlan/if_rsu.c
/usr/src/sys/modules/usb/rsu/../../../dev/usb/wlan/if_rsu.c:123:2: error: use of
      undeclared identifier 'USB_PRODUCT_TRENDNET_TEW_646UBH'
        RSU_DEV_HT(TRENDNET,            TEW_646UBH),
        ^
/usr/src/sys/modules/usb/rsu/../../../dev/usb/wlan/if_rsu.c:81:52: note: 
      expanded from macro 'RSU_DEV_HT'
#define RSU_DEV_HT(v,p)  { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, \
                                                   ^
<scratch space>:158:1: note: expanded from here
USB_PRODUCT_TRENDNET_TEW_646UBH
^
@/dev/usb/usbdi.h:330:33: note: expanded from macro 'USB_VPI'
  USB_VENDOR(vend), USB_PRODUCT(prod), USB_DRIVER_INFO(info)
                                ^
@/dev/usb/usbdi.h:324:42: note: expanded from macro 'USB_PRODUCT'
  .match_flag_product = 1, .idProduct = (prod)
                                         ^
/usr/src/sys/modules/usb/rsu/../../../dev/usb/wlan/if_rsu.c:279:48: error: 
      invalid application of 'sizeof' to an incomplete type 'const struct
      usb_device_id []'
        return (usbd_lookup_id_by_uaa(rsu_devs, sizeof(rsu_devs), uaa));
                                                      ^~~~~~~~~~
2 errors generated.
*** Error code 1

Stop.
make: stopped in /usr/src/sys/modules/usb/rsu
root@localhost:/sys/modules/usb/rsu # 
Добавлял в конец файла и в static const STRUCT_USB_HOST_ID rsu_devs[] = { сюда };
Весь файл:

Код: Выделить всё

/*	$OpenBSD: if_rsu.c,v 1.17 2013/04/15 09:23:01 mglocker Exp $	*/

/*-
 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: releng/10.1/sys/dev/usb/wlan/if_rsu.c 267349 2014-06-11 05:50:04Z hselasky $");

/*
 * Driver for Realtek RTL8188SU/RTL8191SU/RTL8192SU.
 *
 * TODO:
 *   o 11n support
 *   o h/w crypto
 *   o hostap / ibss / mesh
 */
#include <sys/param.h>
#include <sys/endian.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/firmware.h>
#include <sys/module.h>

#include <machine/bus.h>
#include <machine/resource.h>

#include <net/bpf.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>

#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>

#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_radiotap.h>

#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include "usbdevs.h"

#define USB_DEBUG_VAR rsu_debug
#include <dev/usb/usb_debug.h>

#include <dev/usb/wlan/if_rsureg.h>

#ifdef USB_DEBUG
static int rsu_debug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, rsu, CTLFLAG_RW, 0, "USB rsu");
SYSCTL_INT(_hw_usb_rsu, OID_AUTO, debug, CTLFLAG_RW, &rsu_debug, 0,
    "Debug level");
#endif

static const STRUCT_USB_HOST_ID rsu_devs[] = {
#define	RSU_HT_NOT_SUPPORTED 0
#define	RSU_HT_SUPPORTED 1
#define RSU_DEV_HT(v,p)  { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, \
				   RSU_HT_SUPPORTED) }
#define RSU_DEV(v,p)     { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, \
				   RSU_HT_NOT_SUPPORTED) }
	RSU_DEV(ASUS,			RTL8192SU),
	RSU_DEV(AZUREWAVE,		RTL8192SU_4),
	RSU_DEV_HT(ACCTON,		RTL8192SU),
	RSU_DEV_HT(ASUS,		USBN10),
	RSU_DEV_HT(AZUREWAVE,		RTL8192SU_1),
	RSU_DEV_HT(AZUREWAVE,		RTL8192SU_2),
	RSU_DEV_HT(AZUREWAVE,		RTL8192SU_3),
	RSU_DEV_HT(AZUREWAVE,		RTL8192SU_5),
	RSU_DEV_HT(BELKIN,		RTL8192SU_1),
	RSU_DEV_HT(BELKIN,		RTL8192SU_2),
	RSU_DEV_HT(BELKIN,		RTL8192SU_3),
	RSU_DEV_HT(CONCEPTRONIC2,	RTL8192SU_1),
	RSU_DEV_HT(CONCEPTRONIC2,	RTL8192SU_2),
	RSU_DEV_HT(CONCEPTRONIC2,	RTL8192SU_3),
	RSU_DEV_HT(COREGA,		RTL8192SU),
	RSU_DEV_HT(DLINK2,		DWA131A1),
	RSU_DEV_HT(DLINK2,		RTL8192SU_1),
	RSU_DEV_HT(DLINK2,		RTL8192SU_2),
	RSU_DEV_HT(EDIMAX,		RTL8192SU_1),
	RSU_DEV_HT(EDIMAX,		RTL8192SU_2),
	RSU_DEV_HT(EDIMAX,		RTL8192SU_3),
	RSU_DEV_HT(GUILLEMOT,		HWGUN54),
	RSU_DEV_HT(GUILLEMOT,		HWNUM300),
	RSU_DEV_HT(HAWKING,		RTL8192SU_1),
	RSU_DEV_HT(HAWKING,		RTL8192SU_2),
	RSU_DEV_HT(PLANEX2,		GWUSNANO),
	RSU_DEV_HT(REALTEK,		RTL8171),
	RSU_DEV_HT(REALTEK,		RTL8172),
	RSU_DEV_HT(REALTEK,		RTL8173),
	RSU_DEV_HT(REALTEK,		RTL8174),
	RSU_DEV_HT(REALTEK,		RTL8192SU),
	RSU_DEV_HT(REALTEK,		RTL8712),
	RSU_DEV_HT(REALTEK,		RTL8713),
	RSU_DEV_HT(SENAO,		RTL8192SU_1),
	RSU_DEV_HT(SENAO,		RTL8192SU_2),
	RSU_DEV_HT(SITECOMEU,		WL349V1),
	RSU_DEV_HT(SITECOMEU,		WL353),
	RSU_DEV_HT(SWEEX2,		LW154),
#undef RSU_DEV_HT
#undef RSU_DEV
};

static device_probe_t   rsu_match;
static device_attach_t  rsu_attach;
static device_detach_t  rsu_detach;
static usb_callback_t   rsu_bulk_tx_callback_be_bk;
static usb_callback_t   rsu_bulk_tx_callback_vi_vo;
static usb_callback_t   rsu_bulk_rx_callback;
static usb_error_t	rsu_do_request(struct rsu_softc *,
			    struct usb_device_request *, void *);
static struct ieee80211vap *
		rsu_vap_create(struct ieee80211com *, const char name[],
		    int, enum ieee80211_opmode, int, const uint8_t bssid[],
		    const uint8_t mac[]);
static void	rsu_vap_delete(struct ieee80211vap *);
static void	rsu_scan_start(struct ieee80211com *);
static void	rsu_scan_end(struct ieee80211com *);
static void	rsu_set_channel(struct ieee80211com *);
static void	rsu_update_mcast(struct ifnet *);
static int	rsu_alloc_rx_list(struct rsu_softc *);
static void	rsu_free_rx_list(struct rsu_softc *);
static int	rsu_alloc_tx_list(struct rsu_softc *);
static void	rsu_free_tx_list(struct rsu_softc *);
static void	rsu_free_list(struct rsu_softc *, struct rsu_data [], int);
static struct rsu_data *_rsu_getbuf(struct rsu_softc *);
static struct rsu_data *rsu_getbuf(struct rsu_softc *);
static int	rsu_write_region_1(struct rsu_softc *, uint16_t, uint8_t *,
		    int);
static void	rsu_write_1(struct rsu_softc *, uint16_t, uint8_t);
static void	rsu_write_2(struct rsu_softc *, uint16_t, uint16_t);
static void	rsu_write_4(struct rsu_softc *, uint16_t, uint32_t);
static int	rsu_read_region_1(struct rsu_softc *, uint16_t, uint8_t *,
		    int);
static uint8_t	rsu_read_1(struct rsu_softc *, uint16_t);
static uint16_t	rsu_read_2(struct rsu_softc *, uint16_t);
static uint32_t	rsu_read_4(struct rsu_softc *, uint16_t);
static int	rsu_fw_iocmd(struct rsu_softc *, uint32_t);
static uint8_t	rsu_efuse_read_1(struct rsu_softc *, uint16_t);
static int	rsu_read_rom(struct rsu_softc *);
static int	rsu_fw_cmd(struct rsu_softc *, uint8_t, void *, int);
static void	rsu_calib_task(void *, int);
static int	rsu_newstate(struct ieee80211vap *, enum ieee80211_state, int);
#ifdef notyet
static void	rsu_set_key(struct rsu_softc *, const struct ieee80211_key *);
static void	rsu_delete_key(struct rsu_softc *, const struct ieee80211_key *);
#endif
static int	rsu_site_survey(struct rsu_softc *, struct ieee80211vap *);
static int	rsu_join_bss(struct rsu_softc *, struct ieee80211_node *);
static int	rsu_disconnect(struct rsu_softc *);
static void	rsu_event_survey(struct rsu_softc *, uint8_t *, int);
static void	rsu_event_join_bss(struct rsu_softc *, uint8_t *, int);
static void	rsu_rx_event(struct rsu_softc *, uint8_t, uint8_t *, int);
static void	rsu_rx_multi_event(struct rsu_softc *, uint8_t *, int);
static int8_t	rsu_get_rssi(struct rsu_softc *, int, void *);
static struct mbuf *
		rsu_rx_frame(struct rsu_softc *, uint8_t *, int, int *);
static struct mbuf *
		rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int, int *);
static struct mbuf *
		rsu_rxeof(struct usb_xfer *, struct rsu_data *, int *);
static void	rsu_txeof(struct usb_xfer *, struct rsu_data *);
static int	rsu_raw_xmit(struct ieee80211_node *, struct mbuf *, 
		    const struct ieee80211_bpf_params *);
static void	rsu_init(void *);
static void	rsu_init_locked(struct rsu_softc *);
static int	rsu_tx_start(struct rsu_softc *, struct ieee80211_node *, 
		    struct mbuf *, struct rsu_data *);
static void	rsu_start(struct ifnet *);
static void	rsu_start_locked(struct ifnet *);
static int	rsu_ioctl(struct ifnet *, u_long, caddr_t);
static void	rsu_stop(struct ifnet *, int);
static void	rsu_stop_locked(struct ifnet *, int);
static void	rsu_ms_delay(struct rsu_softc *);

static device_method_t rsu_methods[] = {
	DEVMETHOD(device_probe,		rsu_match),
	DEVMETHOD(device_attach,	rsu_attach),
	DEVMETHOD(device_detach,	rsu_detach),

	DEVMETHOD_END
};

static driver_t rsu_driver = {
	.name = "rsu",
	.methods = rsu_methods,
	.size = sizeof(struct rsu_softc)
};

static devclass_t rsu_devclass;

DRIVER_MODULE(rsu, uhub, rsu_driver, rsu_devclass, NULL, 0);
MODULE_DEPEND(rsu, wlan, 1, 1, 1);
MODULE_DEPEND(rsu, usb, 1, 1, 1);
MODULE_DEPEND(rsu, firmware, 1, 1, 1);
MODULE_VERSION(rsu, 1);

static uint8_t rsu_wme_ac_xfer_map[4] = {
	[WME_AC_BE] = RSU_BULK_TX_BE_BK,
	[WME_AC_BK] = RSU_BULK_TX_BE_BK,
	[WME_AC_VI] = RSU_BULK_TX_VI_VO,
	[WME_AC_VO] = RSU_BULK_TX_VI_VO,
};

static const struct usb_config rsu_config[RSU_N_TRANSFER] = {
	[RSU_BULK_RX] = {
		.type = UE_BULK,
		.endpoint = UE_ADDR_ANY,
		.direction = UE_DIR_IN,
		.bufsize = RSU_RXBUFSZ,
		.flags = {
			.pipe_bof = 1,
			.short_xfer_ok = 1
		},
		.callback = rsu_bulk_rx_callback
	},
	[RSU_BULK_TX_BE_BK] = {
		.type = UE_BULK,
		.endpoint = 0x06,
		.direction = UE_DIR_OUT,
		.bufsize = RSU_TXBUFSZ,
		.flags = {
			.ext_buffer = 1,
			.pipe_bof = 1,
			.force_short_xfer = 1
		},
		.callback = rsu_bulk_tx_callback_be_bk,
		.timeout = RSU_TX_TIMEOUT
	},
	[RSU_BULK_TX_VI_VO] = {
		.type = UE_BULK,
		.endpoint = 0x04,
		.direction = UE_DIR_OUT,
		.bufsize = RSU_TXBUFSZ,
		.flags = {
			.ext_buffer = 1,
			.pipe_bof = 1,
			.force_short_xfer = 1
		},
		.callback = rsu_bulk_tx_callback_vi_vo,
		.timeout = RSU_TX_TIMEOUT
	},
};

static int
rsu_match(device_t self)
{
	struct usb_attach_arg *uaa = device_get_ivars(self);

	if (uaa->usb_mode != USB_MODE_HOST ||
	    uaa->info.bIfaceIndex != 0 ||
	    uaa->info.bConfigIndex != 0)
		return (ENXIO);

	return (usbd_lookup_id_by_uaa(rsu_devs, sizeof(rsu_devs), uaa));
}

static int
rsu_attach(device_t self)
{
	struct usb_attach_arg *uaa = device_get_ivars(self);
	struct rsu_softc *sc = device_get_softc(self);
	struct ifnet *ifp;
	struct ieee80211com *ic;
	int error;
	uint8_t iface_index, bands;

	device_set_usb_desc(self);
	sc->sc_udev = uaa->device;
	sc->sc_dev = self;

	mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
	    MTX_DEF);
	TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0, 
	    rsu_calib_task, sc);

	/* Allocate Tx/Rx buffers. */
	error = rsu_alloc_rx_list(sc);
	if (error != 0) {
		device_printf(sc->sc_dev, "could not allocate Rx buffers\n");
		goto fail_usb;
	}

	error = rsu_alloc_tx_list(sc);
	if (error != 0) {
		device_printf(sc->sc_dev, "could not allocate Tx buffers\n");
		rsu_free_rx_list(sc);
		goto fail_usb;
	}

	iface_index = 0;
	error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
	    rsu_config, RSU_N_TRANSFER, sc, &sc->sc_mtx);
	if (error) {
		device_printf(sc->sc_dev,
		    "could not allocate USB transfers, err=%s\n", 
		    usbd_errstr(error));
		goto fail_usb;
	}
	RSU_LOCK(sc);
	/* Read chip revision. */
	sc->cut = MS(rsu_read_4(sc, R92S_PMC_FSM), R92S_PMC_FSM_CUT);
	if (sc->cut != 3)
		sc->cut = (sc->cut >> 1) + 1;
	error = rsu_read_rom(sc);
	if (error != 0) {
		device_printf(self, "could not read ROM\n");
		goto fail_rom;
	}
	RSU_UNLOCK(sc);
	IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->rom[0x12]);
	device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut);
	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
	if (ifp == NULL) {
		device_printf(self, "cannot allocate interface\n");
		goto fail_ifalloc;
	}
	ic = ifp->if_l2com;
	ifp->if_softc = sc;
	if_initname(ifp, "rsu", device_get_unit(self));
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_init = rsu_init;
	ifp->if_ioctl = rsu_ioctl;
	ifp->if_start = rsu_start;
	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
	IFQ_SET_READY(&ifp->if_snd);
	ifp->if_capabilities |= IFCAP_RXCSUM;
	ifp->if_capenable |= IFCAP_RXCSUM;
	ifp->if_hwassist = CSUM_TCP;

	ic->ic_ifp = ifp;
	ic->ic_phytype = IEEE80211_T_OFDM;	/* Not only, but not used. */
	ic->ic_opmode = IEEE80211_M_STA;	/* Default to BSS mode. */

	/* Set device capabilities. */
	ic->ic_caps =
	    IEEE80211_C_STA |		/* station mode */
	    IEEE80211_C_BGSCAN |	/* Background scan. */
	    IEEE80211_C_SHPREAMBLE |	/* Short preamble supported. */
	    IEEE80211_C_SHSLOT |	/* Short slot time supported. */
	    IEEE80211_C_WPA;		/* WPA/RSN. */

#if 0
	/* Check if HT support is present. */
	if (usb_lookup(rsu_devs_noht, uaa->vendor, uaa->product) == NULL) {
		/* Set HT capabilities. */
		ic->ic_htcaps =
		    IEEE80211_HTCAP_CBW20_40 |
		    IEEE80211_HTCAP_DSSSCCK40;
		/* Set supported HT rates. */
		for (i = 0; i < 2; i++)
			ic->ic_sup_mcs[i] = 0xff;
	}
#endif

	/* Set supported .11b and .11g rates. */
	bands = 0;
	setbit(&bands, IEEE80211_MODE_11B);
	setbit(&bands, IEEE80211_MODE_11G);
	ieee80211_init_channels(ic, NULL, &bands);

	ieee80211_ifattach(ic, sc->sc_bssid);
	ic->ic_raw_xmit = rsu_raw_xmit;
	ic->ic_scan_start = rsu_scan_start;
	ic->ic_scan_end = rsu_scan_end;
	ic->ic_set_channel = rsu_set_channel;
	ic->ic_vap_create = rsu_vap_create;
	ic->ic_vap_delete = rsu_vap_delete;
	ic->ic_update_mcast = rsu_update_mcast;

	ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
	    sizeof(sc->sc_txtap), RSU_TX_RADIOTAP_PRESENT, 
	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
	    RSU_RX_RADIOTAP_PRESENT);

	if (bootverbose)
		ieee80211_announce(ic);

	return (0);

fail_ifalloc:
fail_rom:
	usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
fail_usb:
	mtx_destroy(&sc->sc_mtx);
	return (ENXIO);
}

static int
rsu_detach(device_t self)
{
	struct rsu_softc *sc = device_get_softc(self);
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;

	rsu_stop(ifp, 1);
	usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
	ieee80211_ifdetach(ic);

	taskqueue_drain_timeout(taskqueue_thread, &sc->calib_task);

	/* Free Tx/Rx buffers. */
	rsu_free_tx_list(sc);
	rsu_free_rx_list(sc);

	if_free(ifp);
	mtx_destroy(&sc->sc_mtx);

	return (0);
}

static usb_error_t
rsu_do_request(struct rsu_softc *sc, struct usb_device_request *req,
    void *data)
{
	usb_error_t err;
	int ntries = 10;
	
	RSU_ASSERT_LOCKED(sc);

	while (ntries--) {
		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
		    req, data, 0, NULL, 250 /* ms */);
		if (err == 0 || err == USB_ERR_NOT_CONFIGURED)
			break;
		DPRINTFN(1, "Control request failed, %s (retrying)\n",
		    usbd_errstr(err));
		usb_pause_mtx(&sc->sc_mtx, hz / 100);
        }

        return (err);
}

static struct ieee80211vap *
rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
    enum ieee80211_opmode opmode, int flags,
    const uint8_t bssid[IEEE80211_ADDR_LEN],
    const uint8_t mac[IEEE80211_ADDR_LEN])
{
	struct rsu_vap *uvp;
	struct ieee80211vap *vap;

	if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
		return (NULL);

	uvp = (struct rsu_vap *) malloc(sizeof(struct rsu_vap),
	    M_80211_VAP, M_NOWAIT | M_ZERO);
	if (uvp == NULL)
		return (NULL);
	vap = &uvp->vap;

	if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
	    flags, bssid, mac) != 0) {
		/* out of memory */
		free(uvp, M_80211_VAP);
		return (NULL);
	}

	/* override state transition machine */
	uvp->newstate = vap->iv_newstate;
	vap->iv_newstate = rsu_newstate;

	/* complete setup */
	ieee80211_vap_attach(vap, ieee80211_media_change,
	    ieee80211_media_status);
	ic->ic_opmode = opmode;

	return (vap);
}

static void
rsu_vap_delete(struct ieee80211vap *vap)
{
	struct rsu_vap *uvp = RSU_VAP(vap);

	ieee80211_vap_detach(vap);
	free(uvp, M_80211_VAP);
}

static void
rsu_scan_start(struct ieee80211com *ic)
{
	int error;
	struct ifnet *ifp = ic->ic_ifp;
	struct rsu_softc *sc = ifp->if_softc;

	/* Scanning is done by the firmware. */
	RSU_LOCK(sc);
	error = rsu_site_survey(sc, TAILQ_FIRST(&ic->ic_vaps));
	RSU_UNLOCK(sc);
	if (error != 0)
		device_printf(sc->sc_dev,
		    "could not send site survey command\n");
}

static void
rsu_scan_end(struct ieee80211com *ic)
{
	/* Nothing to do here. */
}

static void
rsu_set_channel(struct ieee80211com *ic __unused)
{
	/* We are unable to switch channels, yet. */
}

static void
rsu_update_mcast(struct ifnet *ifp)
{
        /* XXX do nothing?  */
}

static int
rsu_alloc_list(struct rsu_softc *sc, struct rsu_data data[],
    int ndata, int maxsz)
{
	int i, error;

	for (i = 0; i < ndata; i++) {
		struct rsu_data *dp = &data[i];
		dp->sc = sc;
		dp->m = NULL;
		dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT);
		if (dp->buf == NULL) {
			device_printf(sc->sc_dev,
			    "could not allocate buffer\n");
			error = ENOMEM;
			goto fail;
		}
		dp->ni = NULL;
	}

	return (0);
fail:
	rsu_free_list(sc, data, ndata);
	return (error);
}

static int
rsu_alloc_rx_list(struct rsu_softc *sc)
{
        int error, i;

	error = rsu_alloc_list(sc, sc->sc_rx, RSU_RX_LIST_COUNT,
	    RSU_RXBUFSZ);
	if (error != 0)
		return (error);

	STAILQ_INIT(&sc->sc_rx_active);
	STAILQ_INIT(&sc->sc_rx_inactive);

	for (i = 0; i < RSU_RX_LIST_COUNT; i++)
		STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next);

	return (0);
}

static int
rsu_alloc_tx_list(struct rsu_softc *sc)
{
	int error, i;

	error = rsu_alloc_list(sc, sc->sc_tx, RSU_TX_LIST_COUNT,
	    RSU_TXBUFSZ);
	if (error != 0)
		return (error);

	STAILQ_INIT(&sc->sc_tx_inactive);

	for (i = 0; i != RSU_N_TRANSFER; i++) {
		STAILQ_INIT(&sc->sc_tx_active[i]);
		STAILQ_INIT(&sc->sc_tx_pending[i]);
	}

	for (i = 0; i < RSU_TX_LIST_COUNT; i++) {
		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next);
	}

	return (0);
}

static void
rsu_free_tx_list(struct rsu_softc *sc)
{
	int i;

	/* prevent further allocations from TX list(s) */
	STAILQ_INIT(&sc->sc_tx_inactive);

	for (i = 0; i != RSU_N_TRANSFER; i++) {
		STAILQ_INIT(&sc->sc_tx_active[i]);
		STAILQ_INIT(&sc->sc_tx_pending[i]);
	}

	rsu_free_list(sc, sc->sc_tx, RSU_TX_LIST_COUNT);
}

static void
rsu_free_rx_list(struct rsu_softc *sc)
{
	/* prevent further allocations from RX list(s) */
	STAILQ_INIT(&sc->sc_rx_inactive);
	STAILQ_INIT(&sc->sc_rx_active);

	rsu_free_list(sc, sc->sc_rx, RSU_RX_LIST_COUNT);
}

static void
rsu_free_list(struct rsu_softc *sc, struct rsu_data data[], int ndata)
{
	int i;

	for (i = 0; i < ndata; i++) {
		struct rsu_data *dp = &data[i];

		if (dp->buf != NULL) {
			free(dp->buf, M_USBDEV);
			dp->buf = NULL;
		}
		if (dp->ni != NULL) {
			ieee80211_free_node(dp->ni);
			dp->ni = NULL;
		}
	}
}

static struct rsu_data *
_rsu_getbuf(struct rsu_softc *sc)
{
	struct rsu_data *bf;

	bf = STAILQ_FIRST(&sc->sc_tx_inactive);
	if (bf != NULL)
		STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next);
	else
		bf = NULL;
	if (bf == NULL)
		DPRINTF("out of xmit buffers\n");
        return (bf);
}

static struct rsu_data *
rsu_getbuf(struct rsu_softc *sc)
{
	struct rsu_data *bf;

	RSU_ASSERT_LOCKED(sc);

	bf = _rsu_getbuf(sc);
	if (bf == NULL) {
		struct ifnet *ifp = sc->sc_ifp;
		DPRINTF("stop queue\n");
		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
	}
	return (bf);
}

static int
rsu_write_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf,
    int len)
{
	usb_device_request_t req;

	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
	req.bRequest = R92S_REQ_REGS;
	USETW(req.wValue, addr);
	USETW(req.wIndex, 0);
	USETW(req.wLength, len);

	return (rsu_do_request(sc, &req, buf));
}

static void
rsu_write_1(struct rsu_softc *sc, uint16_t addr, uint8_t val)
{
	rsu_write_region_1(sc, addr, &val, 1);
}

static void
rsu_write_2(struct rsu_softc *sc, uint16_t addr, uint16_t val)
{
	val = htole16(val);
	rsu_write_region_1(sc, addr, (uint8_t *)&val, 2);
}

static void
rsu_write_4(struct rsu_softc *sc, uint16_t addr, uint32_t val)
{
	val = htole32(val);
	rsu_write_region_1(sc, addr, (uint8_t *)&val, 4);
}

static int
rsu_read_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf,
    int len)
{
	usb_device_request_t req;

	req.bmRequestType = UT_READ_VENDOR_DEVICE;
	req.bRequest = R92S_REQ_REGS;
	USETW(req.wValue, addr);
	USETW(req.wIndex, 0);
	USETW(req.wLength, len);

	return (rsu_do_request(sc, &req, buf));
}

static uint8_t
rsu_read_1(struct rsu_softc *sc, uint16_t addr)
{
	uint8_t val;

	if (rsu_read_region_1(sc, addr, &val, 1) != 0)
		return (0xff);
	return (val);
}

static uint16_t
rsu_read_2(struct rsu_softc *sc, uint16_t addr)
{
	uint16_t val;

	if (rsu_read_region_1(sc, addr, (uint8_t *)&val, 2) != 0)
		return (0xffff);
	return (le16toh(val));
}

static uint32_t
rsu_read_4(struct rsu_softc *sc, uint16_t addr)
{
	uint32_t val;

	if (rsu_read_region_1(sc, addr, (uint8_t *)&val, 4) != 0)
		return (0xffffffff);
	return (le32toh(val));
}

static int
rsu_fw_iocmd(struct rsu_softc *sc, uint32_t iocmd)
{
	int ntries;

	rsu_write_4(sc, R92S_IOCMD_CTRL, iocmd);
	rsu_ms_delay(sc);
	for (ntries = 0; ntries < 50; ntries++) {
		if (rsu_read_4(sc, R92S_IOCMD_CTRL) == 0)
			return (0);
		rsu_ms_delay(sc);
	}
	return (ETIMEDOUT);
}

static uint8_t
rsu_efuse_read_1(struct rsu_softc *sc, uint16_t addr)
{
	uint32_t reg;
	int ntries;

	reg = rsu_read_4(sc, R92S_EFUSE_CTRL);
	reg = RW(reg, R92S_EFUSE_CTRL_ADDR, addr);
	reg &= ~R92S_EFUSE_CTRL_VALID;
	rsu_write_4(sc, R92S_EFUSE_CTRL, reg);
	/* Wait for read operation to complete. */
	for (ntries = 0; ntries < 100; ntries++) {
		reg = rsu_read_4(sc, R92S_EFUSE_CTRL);
		if (reg & R92S_EFUSE_CTRL_VALID)
			return (MS(reg, R92S_EFUSE_CTRL_DATA));
		rsu_ms_delay(sc);
	}
	device_printf(sc->sc_dev,
	    "could not read efuse byte at address 0x%x\n", addr);
	return (0xff);
}

static int
rsu_read_rom(struct rsu_softc *sc)
{
	uint8_t *rom = sc->rom;
	uint16_t addr = 0;
	uint32_t reg;
	uint8_t off, msk;
	int i;

	/* Make sure that ROM type is eFuse and that autoload succeeded. */
	reg = rsu_read_1(sc, R92S_EE_9346CR);
	if ((reg & (R92S_9356SEL | R92S_EEPROM_EN)) != R92S_EEPROM_EN)
		return (EIO);

	/* Turn on 2.5V to prevent eFuse leakage. */
	reg = rsu_read_1(sc, R92S_EFUSE_TEST + 3);
	rsu_write_1(sc, R92S_EFUSE_TEST + 3, reg | 0x80);
	rsu_ms_delay(sc);
	rsu_write_1(sc, R92S_EFUSE_TEST + 3, reg & ~0x80);

	/* Read full ROM image. */
	memset(&sc->rom, 0xff, sizeof(sc->rom));
	while (addr < 512) {
		reg = rsu_efuse_read_1(sc, addr);
		if (reg == 0xff)
			break;
		addr++;
		off = reg >> 4;
		msk = reg & 0xf;
		for (i = 0; i < 4; i++) {
			if (msk & (1 << i))
				continue;
			rom[off * 8 + i * 2 + 0] =
			    rsu_efuse_read_1(sc, addr);
			addr++;
			rom[off * 8 + i * 2 + 1] =
			    rsu_efuse_read_1(sc, addr);
			addr++;
		}
	}
#ifdef USB_DEBUG
	if (rsu_debug >= 5) {
		/* Dump ROM content. */
		printf("\n");
		for (i = 0; i < sizeof(sc->rom); i++)
			printf("%02x:", rom[i]);
		printf("\n");
	}
#endif
	return (0);
}

static int
rsu_fw_cmd(struct rsu_softc *sc, uint8_t code, void *buf, int len)
{
	const uint8_t which = rsu_wme_ac_xfer_map[WME_AC_VO];
	struct rsu_data *data;
	struct r92s_tx_desc *txd;
	struct r92s_fw_cmd_hdr *cmd;
	int cmdsz;
	int xferlen;

	data = rsu_getbuf(sc);
	if (data == NULL)
		return (ENOMEM);

	/* Round-up command length to a multiple of 8 bytes. */
	cmdsz = (len + 7) & ~7;

	xferlen = sizeof(*txd) + sizeof(*cmd) + cmdsz;
	KASSERT(xferlen <= RSU_TXBUFSZ, ("%s: invalid length", __func__));
	memset(data->buf, 0, xferlen);

	/* Setup Tx descriptor. */
	txd = (struct r92s_tx_desc *)data->buf;
	txd->txdw0 = htole32(
	    SM(R92S_TXDW0_OFFSET, sizeof(*txd)) |
	    SM(R92S_TXDW0_PKTLEN, sizeof(*cmd) + cmdsz) |
	    R92S_TXDW0_OWN | R92S_TXDW0_FSG | R92S_TXDW0_LSG);
	txd->txdw1 = htole32(SM(R92S_TXDW1_QSEL, R92S_TXDW1_QSEL_H2C));

	/* Setup command header. */
	cmd = (struct r92s_fw_cmd_hdr *)&txd[1];
	cmd->len = htole16(cmdsz);
	cmd->code = code;
	cmd->seq = sc->cmd_seq;
	sc->cmd_seq = (sc->cmd_seq + 1) & 0x7f;

	/* Copy command payload. */
	memcpy(&cmd[1], buf, len);

	DPRINTFN(2, "Tx cmd code=0x%x len=0x%x\n", code, cmdsz);
	data->buflen = xferlen;
	STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
	usbd_transfer_start(sc->sc_xfer[which]);

	return (0);
}

/* ARGSUSED */
static void
rsu_calib_task(void *arg, int pending __unused)
{
	struct rsu_softc *sc = arg;
	uint32_t reg;

	DPRINTFN(6, "running calibration task\n");

	RSU_LOCK(sc);
#ifdef notyet
	/* Read WPS PBC status. */
	rsu_write_1(sc, R92S_MAC_PINMUX_CTRL,
	    R92S_GPIOMUX_EN | SM(R92S_GPIOSEL_GPIO, R92S_GPIOSEL_GPIO_JTAG));
	rsu_write_1(sc, R92S_GPIO_IO_SEL,
	    rsu_read_1(sc, R92S_GPIO_IO_SEL) & ~R92S_GPIO_WPS);
	reg = rsu_read_1(sc, R92S_GPIO_CTRL);
	if (reg != 0xff && (reg & R92S_GPIO_WPS))
		DPRINTF(("WPS PBC is pushed\n"));
#endif
	/* Read current signal level. */
	if (rsu_fw_iocmd(sc, 0xf4000001) == 0) {
		reg = rsu_read_4(sc, R92S_IOCMD_DATA);
		DPRINTFN(8, "RSSI=%d%%\n", reg >> 4);
	}
	if (sc->sc_calibrating)
		taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz);
	RSU_UNLOCK(sc);
}

static int
rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
	struct rsu_vap *uvp = RSU_VAP(vap);
	struct ieee80211com *ic = vap->iv_ic;
	struct rsu_softc *sc = ic->ic_ifp->if_softc;
	struct ieee80211_node *ni;
	struct ieee80211_rateset *rs;
	enum ieee80211_state ostate;
	int error, startcal = 0;

	ostate = vap->iv_state;
	DPRINTF("%s -> %s\n", ieee80211_state_name[ostate],
	    ieee80211_state_name[nstate]);

	IEEE80211_UNLOCK(ic);
	if (ostate == IEEE80211_S_RUN) {
		RSU_LOCK(sc);
		/* Stop calibration. */
		sc->sc_calibrating = 0;
		RSU_UNLOCK(sc);
		taskqueue_drain_timeout(taskqueue_thread, &sc->calib_task);
		/* Disassociate from our current BSS. */
		RSU_LOCK(sc);
		rsu_disconnect(sc);
	} else
		RSU_LOCK(sc);
	switch (nstate) {
	case IEEE80211_S_INIT:
		break;
	case IEEE80211_S_AUTH:
		ni = ieee80211_ref_node(vap->iv_bss);
		error = rsu_join_bss(sc, ni);
		ieee80211_free_node(ni);
		if (error != 0) {
			device_printf(sc->sc_dev,
			    "could not send join command\n");
		}
		break;
	case IEEE80211_S_RUN:
		ni = ieee80211_ref_node(vap->iv_bss);
		rs = &ni->ni_rates;
		/* Indicate highest supported rate. */
		ni->ni_txrate = rs->rs_rates[rs->rs_nrates - 1];
		ieee80211_free_node(ni);
		startcal = 1;
		break;
	default:
		break;
	}
	sc->sc_calibrating = 1;
	/* Start periodic calibration. */
	taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz);
	RSU_UNLOCK(sc);
	IEEE80211_LOCK(ic);
	return (uvp->newstate(vap, nstate, arg));
}

#ifdef notyet
static void
rsu_set_key(struct rsu_softc *sc, const struct ieee80211_key *k)
{
	struct r92s_fw_cmd_set_key key;

	memset(&key, 0, sizeof(key));
	/* Map net80211 cipher to HW crypto algorithm. */
	switch (k->wk_cipher->ic_cipher) {
	case IEEE80211_CIPHER_WEP:
		if (k->wk_keylen < 8)
			key.algo = R92S_KEY_ALGO_WEP40;
		else
			key.algo = R92S_KEY_ALGO_WEP104;
		break;
	case IEEE80211_CIPHER_TKIP:
		key.algo = R92S_KEY_ALGO_TKIP;
		break;
	case IEEE80211_CIPHER_AES_CCM:
		key.algo = R92S_KEY_ALGO_AES;
		break;
	default:
		return;
	}
	key.id = k->wk_keyix;
	key.grpkey = (k->wk_flags & IEEE80211_KEY_GROUP) != 0;
	memcpy(key.key, k->wk_key, MIN(k->wk_keylen, sizeof(key.key)));
	(void)rsu_fw_cmd(sc, R92S_CMD_SET_KEY, &key, sizeof(key));
}

static void
rsu_delete_key(struct rsu_softc *sc, const struct ieee80211_key *k)
{
	struct r92s_fw_cmd_set_key key;

	memset(&key, 0, sizeof(key));
	key.id = k->wk_keyix;
	(void)rsu_fw_cmd(sc, R92S_CMD_SET_KEY, &key, sizeof(key));
}
#endif

static int
rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap)
{
	struct r92s_fw_cmd_sitesurvey cmd;
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;

	memset(&cmd, 0, sizeof(cmd));
	if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1)
		cmd.active = htole32(1);
	cmd.limit = htole32(48);
	if (sc->scan_pass == 1 && vap->iv_des_nssid > 0) {
		/* Do a directed scan for second pass. */
		cmd.ssidlen = htole32(vap->iv_des_ssid[0].len);
		memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid,
		    vap->iv_des_ssid[0].len);

	}
	DPRINTF("sending site survey command, pass=%d\n", sc->scan_pass);
	return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd)));
}

static int
rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni)
{
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;
	struct ieee80211vap *vap = ni->ni_vap;
	struct ndis_wlan_bssid_ex *bss;
	struct ndis_802_11_fixed_ies *fixed;
	struct r92s_fw_cmd_auth auth;
	uint8_t buf[sizeof(*bss) + 128] __aligned(4);
	uint8_t *frm;
	uint8_t opmode;
	int error;

	/* Let the FW decide the opmode based on the capinfo field. */
	opmode = NDIS802_11AUTOUNKNOWN;
	DPRINTF("setting operating mode to %d\n", opmode);
	error = rsu_fw_cmd(sc, R92S_CMD_SET_OPMODE, &opmode, sizeof(opmode));
	if (error != 0)
		return (error);

	memset(&auth, 0, sizeof(auth));
	if (vap->iv_flags & IEEE80211_F_WPA) {
		auth.mode = R92S_AUTHMODE_WPA;
		auth.dot1x = (ni->ni_authmode == IEEE80211_AUTH_8021X);
	} else
		auth.mode = R92S_AUTHMODE_OPEN;
	DPRINTF("setting auth mode to %d\n", auth.mode);
	error = rsu_fw_cmd(sc, R92S_CMD_SET_AUTH, &auth, sizeof(auth));
	if (error != 0)
		return (error);

	memset(buf, 0, sizeof(buf));
	bss = (struct ndis_wlan_bssid_ex *)buf;
	IEEE80211_ADDR_COPY(bss->macaddr, ni->ni_bssid);
	bss->ssid.ssidlen = htole32(ni->ni_esslen);
	memcpy(bss->ssid.ssid, ni->ni_essid, ni->ni_esslen);
	if (vap->iv_flags & (IEEE80211_F_PRIVACY | IEEE80211_F_WPA))
		bss->privacy = htole32(1);
	bss->rssi = htole32(ni->ni_avgrssi);
	if (ic->ic_curmode == IEEE80211_MODE_11B)
		bss->networktype = htole32(NDIS802_11DS);
	else
		bss->networktype = htole32(NDIS802_11OFDM24);
	bss->config.len = htole32(sizeof(bss->config));
	bss->config.bintval = htole32(ni->ni_intval);
	bss->config.dsconfig = htole32(ieee80211_chan2ieee(ic, ni->ni_chan));
	bss->inframode = htole32(NDIS802_11INFRASTRUCTURE);
	memcpy(bss->supprates, ni->ni_rates.rs_rates,
	    ni->ni_rates.rs_nrates);
	/* Write the fixed fields of the beacon frame. */
	fixed = (struct ndis_802_11_fixed_ies *)&bss[1];
	memcpy(&fixed->tstamp, ni->ni_tstamp.data, 8);
	fixed->bintval = htole16(ni->ni_intval);
	fixed->capabilities = htole16(ni->ni_capinfo);
	/* Write IEs to be included in the association request. */
	frm = (uint8_t *)&fixed[1];
	frm = ieee80211_add_rsn(frm, vap);
	frm = ieee80211_add_wpa(frm, vap);
	frm = ieee80211_add_qos(frm, ni);
	if (ni->ni_flags & IEEE80211_NODE_HT)
		frm = ieee80211_add_htcap(frm, ni);
	bss->ieslen = htole32(frm - (uint8_t *)fixed);
	bss->len = htole32(((frm - buf) + 3) & ~3);
	DPRINTF("sending join bss command to %s chan %d\n",
	    ether_sprintf(bss->macaddr), le32toh(bss->config.dsconfig));
	return (rsu_fw_cmd(sc, R92S_CMD_JOIN_BSS, buf, sizeof(buf)));
}

static int
rsu_disconnect(struct rsu_softc *sc)
{
	uint32_t zero = 0;	/* :-) */

	/* Disassociate from our current BSS. */
	DPRINTF("sending disconnect command\n");
	return (rsu_fw_cmd(sc, R92S_CMD_DISCONNECT, &zero, sizeof(zero)));
}

static void
rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
{
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;
	struct ieee80211_frame *wh;
	struct ieee80211_channel *c;
	struct ndis_wlan_bssid_ex *bss;
	struct mbuf *m;
	int pktlen;

	if (__predict_false(len < sizeof(*bss)))
		return;
	bss = (struct ndis_wlan_bssid_ex *)buf;
	if (__predict_false(len < sizeof(*bss) + le32toh(bss->ieslen)))
		return;

	DPRINTFN(2, "found BSS %s: len=%d chan=%d inframode=%d "
	    "networktype=%d privacy=%d\n",
	    ether_sprintf(bss->macaddr), le32toh(bss->len),
	    le32toh(bss->config.dsconfig), le32toh(bss->inframode),
	    le32toh(bss->networktype), le32toh(bss->privacy));

	/* Build a fake beacon frame to let net80211 do all the parsing. */
	pktlen = sizeof(*wh) + le32toh(bss->ieslen);
	if (__predict_false(pktlen > MCLBYTES))
		return;
	MGETHDR(m, M_NOWAIT, MT_DATA);
	if (__predict_false(m == NULL))
		return;
	if (pktlen > MHLEN) {
		MCLGET(m, M_NOWAIT);
		if (!(m->m_flags & M_EXT)) {
			m_free(m);
			return;
		}
	}
	wh = mtod(m, struct ieee80211_frame *);
	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
	    IEEE80211_FC0_SUBTYPE_BEACON;
	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
	USETW(wh->i_dur, 0);
	IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
	IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr);
	IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr);
	*(uint16_t *)wh->i_seq = 0;
	memcpy(&wh[1], (uint8_t *)&bss[1], le32toh(bss->ieslen));

	/* Finalize mbuf. */
	m->m_pkthdr.len = m->m_len = pktlen;
	m->m_pkthdr.rcvif = ifp;
	/* Fix the channel. */
	c = ieee80211_find_channel_byieee(ic, 
	    le32toh(bss->config.dsconfig), 
	    IEEE80211_CHAN_G);
	if (c) {
		ic->ic_curchan = c;
		ieee80211_radiotap_chan_change(ic);
	}
	/* XXX avoid a LOR */
	RSU_UNLOCK(sc);
	ieee80211_input_all(ic, m, le32toh(bss->rssi), 0);
	RSU_LOCK(sc);
}

static void
rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len)
{
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;
	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
	struct ieee80211_node *ni = vap->iv_bss;
	struct r92s_event_join_bss *rsp;
	uint32_t tmp;
	int res;

	if (__predict_false(len < sizeof(*rsp)))
		return;
	rsp = (struct r92s_event_join_bss *)buf;
	res = (int)le32toh(rsp->join_res);

	DPRINTF("Rx join BSS event len=%d res=%d\n", len, res);
	if (res <= 0) {
		RSU_UNLOCK(sc);
		ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
		RSU_LOCK(sc);
		return;
	}
	tmp = le32toh(rsp->associd);
	if (tmp >= vap->iv_max_aid) {
		DPRINTF("Assoc ID overflow\n");
		tmp = 1;
	}
	DPRINTF("associated with %s associd=%d\n",
	    ether_sprintf(rsp->bss.macaddr), tmp);
	ni->ni_associd = tmp | 0xc000;
	RSU_UNLOCK(sc);
	ieee80211_new_state(vap, IEEE80211_S_RUN,
	    IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
	RSU_LOCK(sc);
}

static void
rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
{
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;
	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);

	DPRINTFN(4, "Rx event code=%d len=%d\n", code, len);
	switch (code) {
	case R92S_EVT_SURVEY:
		if (vap->iv_state == IEEE80211_S_SCAN)
			rsu_event_survey(sc, buf, len);
		break;
	case R92S_EVT_SURVEY_DONE:
		DPRINTF("site survey pass %d done, found %d BSS\n",
		    sc->scan_pass, le32toh(*(uint32_t *)buf));
		if (vap->iv_state != IEEE80211_S_SCAN)
			break;	/* Ignore if not scanning. */
		if (sc->scan_pass == 0 && vap->iv_des_nssid != 0) {
			/* Schedule a directed scan for hidden APs. */
			sc->scan_pass = 1;
			RSU_UNLOCK(sc);
			ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
			RSU_LOCK(sc);
			break;
		}
		sc->scan_pass = 0;
		break;
	case R92S_EVT_JOIN_BSS:
		if (vap->iv_state == IEEE80211_S_AUTH)
			rsu_event_join_bss(sc, buf, len);
		break;
#if 0
XXX This event is occurring regularly, possibly due to some power saving event
XXX and disrupts the WLAN traffic. Disable for now.
	case R92S_EVT_DEL_STA:
		DPRINTF("disassociated from %s\n", ether_sprintf(buf));
		if (vap->iv_state == IEEE80211_S_RUN &&
		    IEEE80211_ADDR_EQ(vap->iv_bss->ni_bssid, buf)) {
			RSU_UNLOCK(sc);
			ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
			RSU_LOCK(sc);
		}
		break;
#endif
	case R92S_EVT_WPS_PBC:
		DPRINTF("WPS PBC pushed.\n");
		break;
	case R92S_EVT_FWDBG:
		if (ifp->if_flags & IFF_DEBUG) {
			buf[60] = '\0';
			printf("FWDBG: %s\n", (char *)buf);
		}
		break;
	default:
		break;
	}
}

static void
rsu_rx_multi_event(struct rsu_softc *sc, uint8_t *buf, int len)
{
	struct r92s_fw_cmd_hdr *cmd;
	int cmdsz;

	DPRINTFN(6, "Rx events len=%d\n", len);

	/* Skip Rx status. */
	buf += sizeof(struct r92s_rx_stat);
	len -= sizeof(struct r92s_rx_stat);

	/* Process all events. */
	for (;;) {
		/* Check that command header fits. */
		if (__predict_false(len < sizeof(*cmd)))
			break;
		cmd = (struct r92s_fw_cmd_hdr *)buf;
		/* Check that command payload fits. */
		cmdsz = le16toh(cmd->len);
		if (__predict_false(len < sizeof(*cmd) + cmdsz))
			break;

		/* Process firmware event. */
		rsu_rx_event(sc, cmd->code, (uint8_t *)&cmd[1], cmdsz);

		if (!(cmd->seq & R92S_FW_CMD_MORE))
			break;
		buf += sizeof(*cmd) + cmdsz;
		len -= sizeof(*cmd) + cmdsz;
	}
}

static int8_t
rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt)
{
	static const int8_t cckoff[] = { 14, -2, -20, -40 };
	struct r92s_rx_phystat *phy;
	struct r92s_rx_cck *cck;
	uint8_t rpt;
	int8_t rssi;

	if (rate <= 3) {
		cck = (struct r92s_rx_cck *)physt;
		rpt = (cck->agc_rpt >> 6) & 0x3;
		rssi = cck->agc_rpt & 0x3e;
		rssi = cckoff[rpt] - rssi;
	} else {	/* OFDM/HT. */
		phy = (struct r92s_rx_phystat *)physt;
		rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 106;
	}
	return (rssi);
}

static struct mbuf *
rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
{
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;
	struct ieee80211_frame *wh;
	struct r92s_rx_stat *stat;
	uint32_t rxdw0, rxdw3;
	struct mbuf *m;
	uint8_t rate;
	int infosz;

	stat = (struct r92s_rx_stat *)buf;
	rxdw0 = le32toh(stat->rxdw0);
	rxdw3 = le32toh(stat->rxdw3);

	if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) {
		ifp->if_ierrors++;
		return NULL;
	}
	if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) {
		ifp->if_ierrors++;
		return NULL;
	}

	rate = MS(rxdw3, R92S_RXDW3_RATE);
	infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8;

	/* Get RSSI from PHY status descriptor if present. */
	if (infosz != 0)
		*rssi = rsu_get_rssi(sc, rate, &stat[1]);
	else
		*rssi = 0;

	DPRINTFN(5, "Rx frame len=%d rate=%d infosz=%d rssi=%d\n",
	    pktlen, rate, infosz, *rssi);

	MGETHDR(m, M_NOWAIT, MT_DATA);
	if (__predict_false(m == NULL)) {
		ifp->if_ierrors++;
		return NULL;
	}
	if (pktlen > MHLEN) {
		MCLGET(m, M_NOWAIT);
		if (__predict_false(!(m->m_flags & M_EXT))) {
			ifp->if_ierrors++;
			m_freem(m);
			return NULL;
		}
	}
	/* Finalize mbuf. */
	m->m_pkthdr.rcvif = ifp;
	/* Hardware does Rx TCP checksum offload. */
	if (rxdw3 & R92S_RXDW3_TCPCHKVALID) {
		if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT))
			m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
	}
	wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
	memcpy(mtod(m, uint8_t *), wh, pktlen);
	m->m_pkthdr.len = m->m_len = pktlen;

	if (ieee80211_radiotap_active(ic)) {
		struct rsu_rx_radiotap_header *tap = &sc->sc_rxtap;

		/* Map HW rate index to 802.11 rate. */
		tap->wr_flags = 2;
		if (!(rxdw3 & R92S_RXDW3_HTC)) {
			switch (rate) {
			/* CCK. */
			case  0: tap->wr_rate =   2; break;
			case  1: tap->wr_rate =   4; break;
			case  2: tap->wr_rate =  11; break;
			case  3: tap->wr_rate =  22; break;
			/* OFDM. */
			case  4: tap->wr_rate =  12; break;
			case  5: tap->wr_rate =  18; break;
			case  6: tap->wr_rate =  24; break;
			case  7: tap->wr_rate =  36; break;
			case  8: tap->wr_rate =  48; break;
			case  9: tap->wr_rate =  72; break;
			case 10: tap->wr_rate =  96; break;
			case 11: tap->wr_rate = 108; break;
			}
		} else if (rate >= 12) {	/* MCS0~15. */
			/* Bit 7 set means HT MCS instead of rate. */
			tap->wr_rate = 0x80 | (rate - 12);
		}
		tap->wr_dbm_antsignal = *rssi;
		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
	}

	return (m);
}

static struct mbuf *
rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len, int *rssi)
{
	struct r92s_rx_stat *stat;
	uint32_t rxdw0;
	int totlen, pktlen, infosz, npkts;
	struct mbuf *m, *m0 = NULL, *prevm = NULL;

	/* Get the number of encapsulated frames. */
	stat = (struct r92s_rx_stat *)buf;
	npkts = MS(le32toh(stat->rxdw2), R92S_RXDW2_PKTCNT);
	DPRINTFN(6, "Rx %d frames in one chunk\n", npkts);

	/* Process all of them. */
	while (npkts-- > 0) {
		if (__predict_false(len < sizeof(*stat)))
			break;
		stat = (struct r92s_rx_stat *)buf;
		rxdw0 = le32toh(stat->rxdw0);

		pktlen = MS(rxdw0, R92S_RXDW0_PKTLEN);
		if (__predict_false(pktlen == 0))
			break;

		infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8;

		/* Make sure everything fits in xfer. */
		totlen = sizeof(*stat) + infosz + pktlen;
		if (__predict_false(totlen > len))
			break;

		/* Process 802.11 frame. */
		m = rsu_rx_frame(sc, buf, pktlen, rssi);
		if (m0 == NULL)
			m0 = m;
		if (prevm == NULL)
			prevm = m;
		else {
			prevm->m_next = m;
			prevm = m;
		}
		/* Next chunk is 128-byte aligned. */
		totlen = (totlen + 127) & ~127;
		buf += totlen;
		len -= totlen;
	}

	return (m0);
}

static struct mbuf *
rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi)
{
	struct rsu_softc *sc = data->sc;
	struct r92s_rx_stat *stat;
	int len;

	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);

	if (__predict_false(len < sizeof(*stat))) {
		DPRINTF("xfer too short %d\n", len);
		sc->sc_ifp->if_ierrors++;
		return (NULL);
	}
	/* Determine if it is a firmware C2H event or an 802.11 frame. */
	stat = (struct r92s_rx_stat *)data->buf;
	if ((le32toh(stat->rxdw1) & 0x1ff) == 0x1ff) {
		rsu_rx_multi_event(sc, data->buf, len);
		/* No packets to process. */
		return (NULL);
	} else
		return (rsu_rx_multi_frame(sc, data->buf, len, rssi));
}

static void
rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
	struct rsu_softc *sc = usbd_xfer_softc(xfer);
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;
	struct ieee80211_frame *wh;
	struct ieee80211_node *ni;
	struct mbuf *m = NULL, *next;
	struct rsu_data *data;
	int rssi = 1;

	RSU_ASSERT_LOCKED(sc);

	switch (USB_GET_STATE(xfer)) {
	case USB_ST_TRANSFERRED:
		data = STAILQ_FIRST(&sc->sc_rx_active);
		if (data == NULL)
			goto tr_setup;
		STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
		m = rsu_rxeof(xfer, data, &rssi);
		STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
		/* FALLTHROUGH */
	case USB_ST_SETUP:
tr_setup:
		data = STAILQ_FIRST(&sc->sc_rx_inactive);
		if (data == NULL) {
			KASSERT(m == NULL, ("mbuf isn't NULL"));
			return;
		}
		STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next);
		STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next);
		usbd_xfer_set_frame_data(xfer, 0, data->buf,
		    usbd_xfer_max_len(xfer));
		usbd_transfer_submit(xfer);
		/*
		 * To avoid LOR we should unlock our private mutex here to call
		 * ieee80211_input() because here is at the end of a USB
		 * callback and safe to unlock.
		 */
		RSU_UNLOCK(sc);
		while (m != NULL) {
			next = m->m_next;
			m->m_next = NULL;
			wh = mtod(m, struct ieee80211_frame *);
			ni = ieee80211_find_rxnode(ic,
			    (struct ieee80211_frame_min *)wh);
			if (ni != NULL) {
				(void)ieee80211_input(ni, m, rssi, 0);
				ieee80211_free_node(ni);
			} else
				(void)ieee80211_input_all(ic, m, rssi, 0);
			m = next;
		}
		RSU_LOCK(sc);
		break;
	default:
		/* needs it to the inactive queue due to a error. */
		data = STAILQ_FIRST(&sc->sc_rx_active);
		if (data != NULL) {
			STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next);
			STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next);
		}
		if (error != USB_ERR_CANCELLED) {
			usbd_xfer_set_stall(xfer);
			ifp->if_ierrors++;
			goto tr_setup;
		}
		break;
	}

}


static void
rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data)
{
	struct rsu_softc *sc = usbd_xfer_softc(xfer);
	struct ifnet *ifp = sc->sc_ifp;
	struct mbuf *m;

	RSU_ASSERT_LOCKED(sc);

	/*
	 * Do any tx complete callback.  Note this must be done before releasing
	 * the node reference.
	 */
	if (data->m) {
		m = data->m;
		if (m->m_flags & M_TXCB) {
			/* XXX status? */
			ieee80211_process_callback(data->ni, m, 0);
		}
		m_freem(m);
		data->m = NULL;
	}
	if (data->ni) {
		ieee80211_free_node(data->ni);
		data->ni = NULL;
	}
	ifp->if_opackets++;
	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}

static void
rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error,
    uint8_t which)
{
	struct rsu_softc *sc = usbd_xfer_softc(xfer);
	struct ifnet *ifp = sc->sc_ifp;
	struct rsu_data *data;

	RSU_ASSERT_LOCKED(sc);

	switch (USB_GET_STATE(xfer)) {
	case USB_ST_TRANSFERRED:
		data = STAILQ_FIRST(&sc->sc_tx_active[which]);
		if (data == NULL)
			goto tr_setup;
		DPRINTF("transfer done %p\n", data);
		STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
		rsu_txeof(xfer, data);
		STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
		/* FALLTHROUGH */
	case USB_ST_SETUP:
tr_setup:
		data = STAILQ_FIRST(&sc->sc_tx_pending[which]);
		if (data == NULL) {
			DPRINTF("empty pending queue sc %p\n", sc);
			return;
		}
		STAILQ_REMOVE_HEAD(&sc->sc_tx_pending[which], next);
		STAILQ_INSERT_TAIL(&sc->sc_tx_active[which], data, next);
		usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
		DPRINTF("submitting transfer %p\n", data);
		usbd_transfer_submit(xfer);
		break;
	default:
		data = STAILQ_FIRST(&sc->sc_tx_active[which]);
		if (data != NULL) {
			STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next);
			rsu_txeof(xfer, data);
			STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
		}
		ifp->if_oerrors++;

		if (error != USB_ERR_CANCELLED) {
			usbd_xfer_set_stall(xfer);
			goto tr_setup;
		}
		break;
	}
}

static void
rsu_bulk_tx_callback_be_bk(struct usb_xfer *xfer, usb_error_t error)
{
	rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_BE_BK);
}

static void
rsu_bulk_tx_callback_vi_vo(struct usb_xfer *xfer, usb_error_t error)
{
	rsu_bulk_tx_callback_sub(xfer, error, RSU_BULK_TX_VI_VO);
}

static int
rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, 
    struct mbuf *m0, struct rsu_data *data)
{
	struct ifnet *ifp = sc->sc_ifp;
	struct ieee80211com *ic = ifp->if_l2com;
        struct ieee80211vap *vap = ni->ni_vap;
	struct ieee80211_frame *wh;
	struct ieee80211_key *k = NULL;
	struct r92s_tx_desc *txd;
	uint8_t type;
	uint8_t tid = 0;
	uint8_t which;
	int hasqos;
	int xferlen;

	RSU_ASSERT_LOCKED(sc);

	wh = mtod(m0, struct ieee80211_frame *);
	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;

	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
		k = ieee80211_crypto_encap(ni, m0);
		if (k == NULL) {
			device_printf(sc->sc_dev,
			    "ieee80211_crypto_encap returns NULL.\n");
			/* XXX we don't expect the fragmented frames */
			m_freem(m0);
			return (ENOBUFS);
		}
		wh = mtod(m0, struct ieee80211_frame *);
	}
	switch (type) {
	case IEEE80211_FC0_TYPE_CTL:
	case IEEE80211_FC0_TYPE_MGT:
		which = rsu_wme_ac_xfer_map[WME_AC_VO];
		break;
	default:
		which = rsu_wme_ac_xfer_map[M_WME_GETAC(m0)];
		break;
	}
	hasqos = 0;

	/* Fill Tx descriptor. */
	txd = (struct r92s_tx_desc *)data->buf;
	memset(txd, 0, sizeof(*txd));

	txd->txdw0 |= htole32(
	    SM(R92S_TXDW0_PKTLEN, m0->m_pkthdr.len) |
	    SM(R92S_TXDW0_OFFSET, sizeof(*txd)) |
	    R92S_TXDW0_OWN | R92S_TXDW0_FSG | R92S_TXDW0_LSG);

	txd->txdw1 |= htole32(
	    SM(R92S_TXDW1_MACID, R92S_MACID_BSS) |
	    SM(R92S_TXDW1_QSEL, R92S_TXDW1_QSEL_BE));
	if (!hasqos)
		txd->txdw1 |= htole32(R92S_TXDW1_NONQOS);
#ifdef notyet
	if (k != NULL) {
		switch (k->wk_cipher->ic_cipher) {
		case IEEE80211_CIPHER_WEP:
			cipher = R92S_TXDW1_CIPHER_WEP;
			break;
		case IEEE80211_CIPHER_TKIP:
			cipher = R92S_TXDW1_CIPHER_TKIP;
			break;
		case IEEE80211_CIPHER_AES_CCM:
			cipher = R92S_TXDW1_CIPHER_AES;
			break;
		default:
			cipher = R92S_TXDW1_CIPHER_NONE;
		}
		txd->txdw1 |= htole32(
		    SM(R92S_TXDW1_CIPHER, cipher) |
		    SM(R92S_TXDW1_KEYIDX, k->k_id));
	}
#endif
	txd->txdw2 |= htole32(R92S_TXDW2_BK);
	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
		txd->txdw2 |= htole32(R92S_TXDW2_BMCAST);
	/*
	 * Firmware will use and increment the sequence number for the
	 * specified TID.
	 */
	txd->txdw3 |= htole32(SM(R92S_TXDW3_SEQ, tid));

	if (ieee80211_radiotap_active_vap(vap)) {
		struct rsu_tx_radiotap_header *tap = &sc->sc_txtap;

		tap->wt_flags = 0;
		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
		ieee80211_radiotap_tx(vap, m0);
	}
	xferlen = sizeof(*txd) + m0->m_pkthdr.len;
	m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&txd[1]);

	data->buflen = xferlen;
	data->ni = ni;
	data->m = m0;
	STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);

	/* start transfer, if any */
	usbd_transfer_start(sc->sc_xfer[which]);
	return (0);
}

static void
rsu_start(struct ifnet *ifp)
{
	struct rsu_softc *sc = ifp->if_softc;

	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
		return;

	RSU_LOCK(sc);
	rsu_start_locked(ifp);
	RSU_UNLOCK(sc);
}

static void
rsu_start_locked(struct ifnet *ifp)
{
	struct rsu_softc *sc = ifp->if_softc;
	struct ieee80211_node *ni;
	struct rsu_data *bf;
	struct mbuf *m;

	RSU_ASSERT_LOCKED(sc);

	for (;;) {
		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
		if (m == NULL)
			break;
		ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
		m->m_pkthdr.rcvif = NULL;

		bf = rsu_getbuf(sc);
		if (bf == NULL) {
			ifp->if_iqdrops++;
			m_freem(m);
			ieee80211_free_node(ni);
		} else if (rsu_tx_start(sc, ni, m, bf) != 0) {
			ifp->if_oerrors++;
			STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
			ieee80211_free_node(ni);
		}
	}
}

static int
rsu_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
	struct ieee80211com *ic = ifp->if_l2com;
	struct ifreq *ifr = (struct ifreq *) data;
	int error = 0, startall = 0;

	switch (cmd) {
	case SIOCSIFFLAGS:
		if (ifp->if_flags & IFF_UP) {
			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
				rsu_init(ifp->if_softc);
				startall = 1;
			}
		} else {
			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
				rsu_stop(ifp, 1);
		}
		if (startall)
			ieee80211_start_all(ic);
		break;
	case SIOCGIFMEDIA:
		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
		break;
	case SIOCGIFADDR:
		error = ether_ioctl(ifp, cmd, data);
		break;
	default:
		error = EINVAL;
		break;
	}

	return (error);
}

/*
 * Power on sequence for A-cut adapters.
 */
static void
rsu_power_on_acut(struct rsu_softc *sc)
{
	uint32_t reg;

	rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x53);
	rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x57);

	/* Enable AFE macro block's bandgap and Mbias. */
	rsu_write_1(sc, R92S_AFE_MISC,
	    rsu_read_1(sc, R92S_AFE_MISC) |
	    R92S_AFE_MISC_BGEN | R92S_AFE_MISC_MBEN);
	/* Enable LDOA15 block. */
	rsu_write_1(sc, R92S_LDOA15_CTRL,
	    rsu_read_1(sc, R92S_LDOA15_CTRL) | R92S_LDA15_EN);

	rsu_write_1(sc, R92S_SPS1_CTRL,
	    rsu_read_1(sc, R92S_SPS1_CTRL) | R92S_SPS1_LDEN);
	usb_pause_mtx(&sc->sc_mtx, 2 * hz);
	/* Enable switch regulator block. */
	rsu_write_1(sc, R92S_SPS1_CTRL,
	    rsu_read_1(sc, R92S_SPS1_CTRL) | R92S_SPS1_SWEN);

	rsu_write_4(sc, R92S_SPS1_CTRL, 0x00a7b267);

	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1,
	    rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) | 0x08);

	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x20);

	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1,
	    rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) & ~0x90);

	/* Enable AFE clock. */
	rsu_write_1(sc, R92S_AFE_XTAL_CTRL + 1,
	    rsu_read_1(sc, R92S_AFE_XTAL_CTRL + 1) & ~0x04);
	/* Enable AFE PLL macro block. */
	rsu_write_1(sc, R92S_AFE_PLL_CTRL,
	    rsu_read_1(sc, R92S_AFE_PLL_CTRL) | 0x11);
	/* Attach AFE PLL to MACTOP/BB. */
	rsu_write_1(sc, R92S_SYS_ISO_CTRL,
	    rsu_read_1(sc, R92S_SYS_ISO_CTRL) & ~0x11);

	/* Switch to 40MHz clock instead of 80MHz. */
	rsu_write_2(sc, R92S_SYS_CLKR,
	    rsu_read_2(sc, R92S_SYS_CLKR) & ~R92S_SYS_CLKSEL);

	/* Enable MAC clock. */
	rsu_write_2(sc, R92S_SYS_CLKR,
	    rsu_read_2(sc, R92S_SYS_CLKR) |
	    R92S_MAC_CLK_EN | R92S_SYS_CLK_EN);

	rsu_write_1(sc, R92S_PMC_FSM, 0x02);

	/* Enable digital core and IOREG R/W. */
	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x08);

	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x80);

	/* Switch the control path to firmware. */
	reg = rsu_read_2(sc, R92S_SYS_CLKR);
	reg = (reg & ~R92S_SWHW_SEL) | R92S_FWHW_SEL;
	rsu_write_2(sc, R92S_SYS_CLKR, reg);

	rsu_write_2(sc, R92S_CR, 0x37fc);

	/* Fix USB RX FIFO issue. */
	rsu_write_1(sc, 0xfe5c,
	    rsu_read_1(sc, 0xfe5c) | 0x80);
	rsu_write_1(sc, 0x00ab,
	    rsu_read_1(sc, 0x00ab) | 0xc0);

	rsu_write_1(sc, R92S_SYS_CLKR,
	    rsu_read_1(sc, R92S_SYS_CLKR) & ~R92S_SYS_CPU_CLKSEL);
}

/*
 * Power on sequence for B-cut and C-cut adapters.
 */
static void
rsu_power_on_bcut(struct rsu_softc *sc)
{
	uint32_t reg;
	int ntries;

	/* Prevent eFuse leakage. */
	rsu_write_1(sc, 0x37, 0xb0);
	usb_pause_mtx(&sc->sc_mtx, hz / 100);
	rsu_write_1(sc, 0x37, 0x30);

	/* Switch the control path to hardware. */
	reg = rsu_read_2(sc, R92S_SYS_CLKR);
	if (reg & R92S_FWHW_SEL) {
		rsu_write_2(sc, R92S_SYS_CLKR,
		    reg & ~(R92S_SWHW_SEL | R92S_FWHW_SEL));
	}
	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) & ~0x8c);
	rsu_ms_delay(sc);

	rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x53);
	rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x57);

	reg = rsu_read_1(sc, R92S_AFE_MISC);
	rsu_write_1(sc, R92S_AFE_MISC, reg | R92S_AFE_MISC_BGEN);
	rsu_write_1(sc, R92S_AFE_MISC, reg | R92S_AFE_MISC_BGEN |
	    R92S_AFE_MISC_MBEN | R92S_AFE_MISC_I32_EN);

	/* Enable PLL. */
	rsu_write_1(sc, R92S_LDOA15_CTRL,
	    rsu_read_1(sc, R92S_LDOA15_CTRL) | R92S_LDA15_EN);

	rsu_write_1(sc, R92S_LDOV12D_CTRL,
	    rsu_read_1(sc, R92S_LDOV12D_CTRL) | R92S_LDV12_EN);

	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1,
	    rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) | 0x08);

	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x20);

	/* Support 64KB IMEM. */
	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1,
	    rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) & ~0x97);

	/* Enable AFE clock. */
	rsu_write_1(sc, R92S_AFE_XTAL_CTRL + 1,
	    rsu_read_1(sc, R92S_AFE_XTAL_CTRL + 1) & ~0x04);
	/* Enable AFE PLL macro block. */
	reg = rsu_read_1(sc, R92S_AFE_PLL_CTRL);
	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x11);
	rsu_ms_delay(sc);
	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x51);
	rsu_ms_delay(sc);
	rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x11);
	rsu_ms_delay(sc);

	/* Attach AFE PLL to MACTOP/BB. */
	rsu_write_1(sc, R92S_SYS_ISO_CTRL,
	    rsu_read_1(sc, R92S_SYS_ISO_CTRL) & ~0x11);

	/* Switch to 40MHz clock. */
	rsu_write_1(sc, R92S_SYS_CLKR, 0x00);
	/* Disable CPU clock and 80MHz SSC. */
	rsu_write_1(sc, R92S_SYS_CLKR,
	    rsu_read_1(sc, R92S_SYS_CLKR) | 0xa0);
	/* Enable MAC clock. */
	rsu_write_2(sc, R92S_SYS_CLKR,
	    rsu_read_2(sc, R92S_SYS_CLKR) |
	    R92S_MAC_CLK_EN | R92S_SYS_CLK_EN);

	rsu_write_1(sc, R92S_PMC_FSM, 0x02);

	/* Enable digital core and IOREG R/W. */
	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x08);

	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1,
	    rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x80);

	/* Switch the control path to firmware. */
	reg = rsu_read_2(sc, R92S_SYS_CLKR);
	reg = (reg & ~R92S_SWHW_SEL) | R92S_FWHW_SEL;
	rsu_write_2(sc, R92S_SYS_CLKR, reg);

	rsu_write_2(sc, R92S_CR, 0x37fc);

	/* Fix USB RX FIFO issue. */
	rsu_write_1(sc, 0xfe5c,
	    rsu_read_1(sc, 0xfe5c) | 0x80);

	rsu_write_1(sc, R92S_SYS_CLKR,
	    rsu_read_1(sc, R92S_SYS_CLKR) & ~R92S_SYS_CPU_CLKSEL);

	rsu_write_1(sc, 0xfe1c, 0x80);

	/* Make sure TxDMA is ready to download firmware. */
	for (ntries = 0; ntries < 20; ntries++) {
		reg = rsu_read_1(sc, R92S_TCR);
		if ((reg & (R92S_TCR_IMEM_CHK_RPT | R92S_TCR_EMEM_CHK_RPT)) ==
		    (R92S_TCR_IMEM_CHK_RPT | R92S_TCR_EMEM_CHK_RPT))
			break;
		rsu_ms_delay(sc);
	}
	if (ntries == 20) {
		DPRINTF("TxDMA is not ready\n");
		/* Reset TxDMA. */
		reg = rsu_read_1(sc, R92S_CR);
		rsu_write_1(sc, R92S_CR, reg & ~R92S_CR_TXDMA_EN);
		rsu_ms_delay(sc);
		rsu_write_1(sc, R92S_CR, reg | R92S_CR_TXDMA_EN);
	}
}

static void
rsu_power_off(struct rsu_softc *sc)
{
	/* Turn RF off. */
	rsu_write_1(sc, R92S_RF_CTRL, 0x00);
	usb_pause_mtx(&sc->sc_mtx, hz / 200);

	/* Turn MAC off. */
	/* Switch control path. */
	rsu_write_1(sc, R92S_SYS_CLKR + 1, 0x38);
	/* Reset MACTOP. */
	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 0x70);
	rsu_write_1(sc, R92S_PMC_FSM, 0x06);
	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 0, 0xf9);
	rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1, 0xe8);

	/* Disable AFE PLL. */
	rsu_write_1(sc, R92S_AFE_PLL_CTRL, 0x00);
	/* Disable A15V. */
	rsu_write_1(sc, R92S_LDOA15_CTRL, 0x54);
	/* Disable eFuse 1.2V. */
	rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 0x50);
	rsu_write_1(sc, R92S_LDOV12D_CTRL, 0x24);
	/* Enable AFE macro block's bandgap and Mbias. */
	rsu_write_1(sc, R92S_AFE_MISC, 0x30);
	/* Disable 1.6V LDO. */
	rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x56);
	rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x43);
}

static int
rsu_fw_loadsection(struct rsu_softc *sc, const uint8_t *buf, int len)
{
	const uint8_t which = rsu_wme_ac_xfer_map[WME_AC_VO];
	struct rsu_data *data;
	struct r92s_tx_desc *txd;
	int mlen;

	while (len > 0) {
		data = rsu_getbuf(sc);
		if (data == NULL)
			return (ENOMEM);
		txd = (struct r92s_tx_desc *)data->buf;
		memset(txd, 0, sizeof(*txd));
		if (len <= RSU_TXBUFSZ - sizeof(*txd)) {
			/* Last chunk. */
			txd->txdw0 |= htole32(R92S_TXDW0_LINIP);
			mlen = len;
		} else
			mlen = RSU_TXBUFSZ - sizeof(*txd);
		txd->txdw0 |= htole32(SM(R92S_TXDW0_PKTLEN, mlen));
		memcpy(&txd[1], buf, mlen);
		data->buflen = sizeof(*txd) + mlen;
		DPRINTF("starting transfer %p\n", data);
		STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next);
		buf += mlen;
		len -= mlen;
	}
	usbd_transfer_start(sc->sc_xfer[which]);
	return (0);
}

static int
rsu_load_firmware(struct rsu_softc *sc)
{
	const struct r92s_fw_hdr *hdr;
	struct r92s_fw_priv *dmem;
	const uint8_t *imem, *emem;
	int imemsz, ememsz;
	const struct firmware *fw;
	size_t size;
	uint32_t reg;
	int ntries, error;

	if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_FWRDY) {
		DPRINTF("Firmware already loaded\n");
		return (0);
	}

	RSU_UNLOCK(sc);
	/* Read firmware image from the filesystem. */
	if ((fw = firmware_get("rsu-rtl8712fw")) == NULL) {
		device_printf(sc->sc_dev, 
		    "%s: failed load firmware of file rsu-rtl8712fw\n",
		    __func__);
		RSU_LOCK(sc);
		return (ENXIO);
	}
	RSU_LOCK(sc);
	size = fw->datasize;
	if (size < sizeof(*hdr)) {
		device_printf(sc->sc_dev, "firmware too short\n");
		error = EINVAL;
		goto fail;
	}
	hdr = (const struct r92s_fw_hdr *)fw->data;
	if (hdr->signature != htole16(0x8712) &&
	    hdr->signature != htole16(0x8192)) {
		device_printf(sc->sc_dev,
		    "invalid firmware signature 0x%x\n",
		    le16toh(hdr->signature));
		error = EINVAL;
		goto fail;
	}
	DPRINTF("FW V%d %02x-%02x %02x:%02x\n", le16toh(hdr->version),
	    hdr->month, hdr->day, hdr->hour, hdr->minute);

	/* Make sure that driver and firmware are in sync. */
	if (hdr->privsz != htole32(sizeof(*dmem))) {
		device_printf(sc->sc_dev, "unsupported firmware image\n");
		error = EINVAL;
		goto fail;
	}
	/* Get FW sections sizes. */
	imemsz = le32toh(hdr->imemsz);
	ememsz = le32toh(hdr->sramsz);
	/* Check that all FW sections fit in image. */
	if (size < sizeof(*hdr) + imemsz + ememsz) {
		device_printf(sc->sc_dev, "firmware too short\n");
		error = EINVAL;
		goto fail;
	}
	imem = (const uint8_t *)&hdr[1];
	emem = imem + imemsz;

	/* Load IMEM section. */
	error = rsu_fw_loadsection(sc, imem, imemsz);
	if (error != 0) {
		device_printf(sc->sc_dev,
		    "could not load firmware section %s\n", "IMEM");
		goto fail;
	}
	/* Wait for load to complete. */
	for (ntries = 0; ntries != 50; ntries++) {
		usb_pause_mtx(&sc->sc_mtx, hz / 100);
		reg = rsu_read_1(sc, R92S_TCR);
		if (reg & R92S_TCR_IMEM_CODE_DONE)
			break;
	}
	if (ntries == 50) {
		device_printf(sc->sc_dev, "timeout waiting for IMEM transfer\n");
		error = ETIMEDOUT;
		goto fail;
	}
	/* Load EMEM section. */
	error = rsu_fw_loadsection(sc, emem, ememsz);
	if (error != 0) {
		device_printf(sc->sc_dev,
		    "could not load firmware section %s\n", "EMEM");
		goto fail;
	}
	/* Wait for load to complete. */
	for (ntries = 0; ntries != 50; ntries++) {
		usb_pause_mtx(&sc->sc_mtx, hz / 100);
		reg = rsu_read_2(sc, R92S_TCR);
		if (reg & R92S_TCR_EMEM_CODE_DONE)
			break;
	}
	if (ntries == 50) {
		device_printf(sc->sc_dev, "timeout waiting for EMEM transfer\n");
		error = ETIMEDOUT;
		goto fail;
	}
	/* Enable CPU. */
	rsu_write_1(sc, R92S_SYS_CLKR,
	    rsu_read_1(sc, R92S_SYS_CLKR) | R92S_SYS_CPU_CLKSEL);
	if (!(rsu_read_1(sc, R92S_SYS_CLKR) & R92S_SYS_CPU_CLKSEL)) {
		device_printf(sc->sc_dev, "could not enable system clock\n");
		error = EIO;
		goto fail;
	}
	rsu_write_2(sc, R92S_SYS_FUNC_EN,
	    rsu_read_2(sc, R92S_SYS_FUNC_EN) | R92S_FEN_CPUEN);
	if (!(rsu_read_2(sc, R92S_SYS_FUNC_EN) & R92S_FEN_CPUEN)) {
		device_printf(sc->sc_dev, 
		    "could not enable microcontroller\n");
		error = EIO;
		goto fail;
	}
	/* Wait for CPU to initialize. */
	for (ntries = 0; ntries < 100; ntries++) {
		if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_IMEM_RDY)
			break;
		rsu_ms_delay(sc);
	}
	if (ntries == 100) {
		device_printf(sc->sc_dev,
		    "timeout waiting for microcontroller\n");
		error = ETIMEDOUT;
		goto fail;
	}

	/* Update DMEM section before loading. */
	dmem = __DECONST(struct r92s_fw_priv *, &hdr->priv);
	memset(dmem, 0, sizeof(*dmem));
	dmem->hci_sel = R92S_HCI_SEL_USB | R92S_HCI_SEL_8172;
	dmem->nendpoints = 0;
	dmem->rf_config = 0x12;	/* 1T2R */
	dmem->vcs_type = R92S_VCS_TYPE_AUTO;
	dmem->vcs_mode = R92S_VCS_MODE_RTS_CTS;
#ifdef notyet
	dmem->bw40_en = (ic->ic_htcaps & IEEE80211_HTCAP_CBW20_40) != 0;
#endif
	dmem->turbo_mode = 1;
	/* Load DMEM section. */
	error = rsu_fw_loadsection(sc, (uint8_t *)dmem, sizeof(*dmem));
	if (error != 0) {
		device_printf(sc->sc_dev,
		    "could not load firmware section %s\n", "DMEM");
		goto fail;
	}
	/* Wait for load to complete. */
	for (ntries = 0; ntries < 100; ntries++) {
		if (rsu_read_1(sc, R92S_TCR) & R92S_TCR_DMEM_CODE_DONE)
			break;
		rsu_ms_delay(sc);
	}
	if (ntries == 100) {
		device_printf(sc->sc_dev, "timeout waiting for %s transfer\n",
		    "DMEM");
		error = ETIMEDOUT;
		goto fail;
	}
	/* Wait for firmware readiness. */
	for (ntries = 0; ntries < 60; ntries++) {
		if (!(rsu_read_1(sc, R92S_TCR) & R92S_TCR_FWRDY))
			break;
		rsu_ms_delay(sc);
	}
	if (ntries == 60) {
		device_printf(sc->sc_dev, 
		    "timeout waiting for firmware readiness\n");
		error = ETIMEDOUT;
		goto fail;
	}
 fail:
	firmware_put(fw, FIRMWARE_UNLOAD);
	return (error);
}


static int	
rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 
    const struct ieee80211_bpf_params *params)
{
	struct ieee80211com *ic = ni->ni_ic;
	struct ifnet *ifp = ic->ic_ifp;
	struct rsu_softc *sc = ifp->if_softc;
	struct rsu_data *bf;

	/* prevent management frames from being sent if we're not ready */
	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
		m_freem(m);
		ieee80211_free_node(ni);
		return (ENETDOWN);
	}
	RSU_LOCK(sc);
	bf = rsu_getbuf(sc);
	if (bf == NULL) {
		ieee80211_free_node(ni);
		m_freem(m);
		RSU_UNLOCK(sc);
		return (ENOBUFS);
	}
	ifp->if_opackets++;
	if (rsu_tx_start(sc, ni, m, bf) != 0) {
		ieee80211_free_node(ni);
		ifp->if_oerrors++;
		STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
		RSU_UNLOCK(sc);
		return (EIO);
	}
	RSU_UNLOCK(sc);

	return (0);
}

static void
rsu_init(void *arg)
{
	struct rsu_softc *sc = arg;

	RSU_LOCK(sc);
	rsu_init_locked(arg);
	RSU_UNLOCK(sc);
}

static void
rsu_init_locked(struct rsu_softc *sc)
{
	struct ifnet *ifp = sc->sc_ifp;
	struct r92s_set_pwr_mode cmd;
	int error;
	int i;

	/* Init host async commands ring. */
	sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0;

	/* Power on adapter. */
	if (sc->cut == 1)
		rsu_power_on_acut(sc);
	else
		rsu_power_on_bcut(sc);

	/* Load firmware. */
	error = rsu_load_firmware(sc);
	if (error != 0)
		goto fail;

	/* Enable Rx TCP checksum offload. */
	rsu_write_4(sc, R92S_RCR,
	    rsu_read_4(sc, R92S_RCR) | 0x04000000);
	/* Append PHY status. */
	rsu_write_4(sc, R92S_RCR,
	    rsu_read_4(sc, R92S_RCR) | 0x02000000);

	rsu_write_4(sc, R92S_CR,
	    rsu_read_4(sc, R92S_CR) & ~0xff000000);

	/* Use 128 bytes pages. */
	rsu_write_1(sc, 0x00b5,
	    rsu_read_1(sc, 0x00b5) | 0x01);
	/* Enable USB Rx aggregation. */
	rsu_write_1(sc, 0x00bd,
	    rsu_read_1(sc, 0x00bd) | 0x80);
	/* Set USB Rx aggregation threshold. */
	rsu_write_1(sc, 0x00d9, 0x01);
	/* Set USB Rx aggregation timeout (1.7ms/4). */
	rsu_write_1(sc, 0xfe5b, 0x04);
	/* Fix USB Rx FIFO issue. */
	rsu_write_1(sc, 0xfe5c,
	    rsu_read_1(sc, 0xfe5c) | 0x80);

	/* Set MAC address. */
	rsu_write_region_1(sc, R92S_MACID, IF_LLADDR(ifp), 
	    IEEE80211_ADDR_LEN);

	/* It really takes 1.5 seconds for the firmware to boot: */
	usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2);

	DPRINTF("setting MAC address to %s\n", ether_sprintf(IF_LLADDR(ifp)));
	error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp),
	    IEEE80211_ADDR_LEN);
	if (error != 0) {
		device_printf(sc->sc_dev, "could not set MAC address\n");
		goto fail;
	}

	rsu_write_1(sc, R92S_USB_HRPWM,
	    R92S_USB_HRPWM_PS_ST_ACTIVE | R92S_USB_HRPWM_PS_ALL_ON);

	memset(&cmd, 0, sizeof(cmd));
	cmd.mode = R92S_PS_MODE_ACTIVE;
	DPRINTF("setting ps mode to %d\n", cmd.mode);
	error = rsu_fw_cmd(sc, R92S_CMD_SET_PWR_MODE, &cmd, sizeof(cmd));
	if (error != 0) {
		device_printf(sc->sc_dev, "could not set PS mode\n");
		goto fail;
	}

#if 0
	if (ic->ic_htcaps & IEEE80211_HTCAP_CBW20_40) {
		/* Enable 40MHz mode. */
		error = rsu_fw_iocmd(sc,
		    SM(R92S_IOCMD_CLASS, 0xf4) |
		    SM(R92S_IOCMD_INDEX, 0x00) |
		    SM(R92S_IOCMD_VALUE, 0x0007));
		if (error != 0) {
			device_printf(sc->sc_dev,
			    "could not enable 40MHz mode\n");
			goto fail;
		}
	}

	/* Set default channel. */
	ic->ic_bss->ni_chan = ic->ic_ibss_chan;
#endif
	sc->scan_pass = 0;
	usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]);

	/* We're ready to go. */
	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
	ifp->if_drv_flags |= IFF_DRV_RUNNING;
	return;
fail:
	/* Need to stop all failed transfers, if any */
	for (i = 0; i != RSU_N_TRANSFER; i++)
		usbd_transfer_stop(sc->sc_xfer[i]);
}

static void
rsu_stop(struct ifnet *ifp, int disable)
{
	struct rsu_softc *sc = ifp->if_softc;

	RSU_LOCK(sc);
	rsu_stop_locked(ifp, disable);
	RSU_UNLOCK(sc);
}

static void
rsu_stop_locked(struct ifnet *ifp, int disable __unused)
{
	struct rsu_softc *sc = ifp->if_softc;
	int i;

	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
	sc->sc_calibrating = 0;
	taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL);

	/* Power off adapter. */
	rsu_power_off(sc);

	for (i = 0; i < RSU_N_TRANSFER; i++)
		usbd_transfer_stop(sc->sc_xfer[i]);
}

static void
rsu_ms_delay(struct rsu_softc *sc)
{
	usb_pause_mtx(&sc->sc_mtx, hz / 1000);
}
cat /sys/dev/usb/usbdev

Код: Выделить всё

root@localhost:/sys/modules/usb/rsu # cat /sys/dev/usb/usbdev
product TRENDNET TEW_646UBH   0x646b   TEW_646UBH

root@localhost:/sys/modules/usb/rsu # 

PYO
сержант
Сообщения: 185
Зарегистрирован: 2011-08-18 12:46:45

Re: Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение PYO » 2014-11-18 15:30:27

/sys/dev/usb/usbdev должен быть /sys/dev/usb/usbdevs
s пропустил я

minimatronik
рядовой
Сообщения: 13
Зарегистрирован: 2014-11-18 16:29:23

Re: Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение minimatronik » 2014-11-18 16:32:24

PYO писал(а):/sys/dev/usb/usbdev должен быть /sys/dev/usb/usbdevs
s пропустил я
пересобрал модуль, сделал ребут, все определилось, wifi настроен. Спасибо!

Аватара пользователя
f_andrey
майор
Сообщения: 2651
Зарегистрирован: 2007-12-26 1:22:58
Откуда: СПб
Контактная информация:

Re: Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение f_andrey » 2014-11-18 16:44:03

Недурно бы об этом в профильную рассылку отписаться, например @freebsd-wireless, либо в https://bugs.freebsd.org/bugzilla/, возможно внесут в основное дерево и всем будет красота ;)
Если ваша тема перенесена, то смотри http://forum.lissyara.su/viewtopic.php?f=1&t=32308

minimatronik
рядовой
Сообщения: 13
Зарегистрирован: 2014-11-18 16:29:23

Re: Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение minimatronik » 2014-11-20 21:58:14

f_andrey писал(а):Недурно бы об этом в профильную рассылку отписаться, например @freebsd-wireless, либо в https://bugs.freebsd.org/bugzilla/, возможно внесут в основное дерево и всем будет красота ;)
Написал в @freebsd-wireless, сказали закоммитят.

Код: Выделить всё

Committed as r274684, thanks.
Но начались проблемы. Все работало нормально, пока вечерем не глюканул если не ошибаюсь машрутизатор, который раздает wifi - сеть сдохла у меня и барахлила вроде на ноуте с виндой, потом востановилась, точно незнаю. service netif restart результатов не давало, сделал ребут, времени небыло, сеть не появилась. Потом поразбирался - вобщем через dhclient не выдается ip адрес моему компьютеру. В процесе настройки несколько раз комп сам резко уходил в чистый ребут, так же такое случилось когда достал адптер, хотя команд в терминале активных небыло, но может работал в фоне dhclient. Итого:
dmesg после загрузки после ребута:

Код: Выделить всё

Copyright (c) 1992-2014 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
	The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 10.1-RELEASE #0: Sun Nov 16 21:10:32 FET 2014
    minimatronik@localhost:/usr/obj/usr/src/sys/NEWGENERIC amd64
FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512
module ath_pci already present!
CPU: Intel(R) Core(TM) i3-3220 CPU @ 3.30GHz (3292.59-MHz K8-class CPU)
  Origin = "GenuineIntel"  Id = 0x306a9  Family = 0x6  Model = 0x3a  Stepping = 9
  Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
  Features2=0x3d9ae3bf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,POPCNT,TSCDLT,XSAVE,OSXSAVE,AVX,F16C>
  AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
  AMD Features2=0x1<LAHF>
  Structured Extended Features=0x281<FSGSBASE,SMEP,ERMS>
  VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID
  TSC: P-state invariant, performance statistics
real memory  = 8589934592 (8192 MB)
avail memory = 8210751488 (7830 MB)
Event timer "LAPIC" quality 600
ACPI APIC Table: <ALASKA A M I>
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
FreeBSD/SMP: 1 package(s) x 2 core(s) x 2 SMT threads
 cpu0 (BSP): APIC ID:  0
 cpu1 (AP): APIC ID:  1
 cpu2 (AP): APIC ID:  2
 cpu3 (AP): APIC ID:  3
ioapic0 <Version 2.0> irqs 0-23 on motherboard
random: <Software, Yarrow> initialized
kbd1 at kbdmux0
acpi0: <ALASKA A M I> on motherboard
acpi0: Power Button (fixed)
acpi0: reservation of 67, 1 (4) failed
cpu0: <ACPI CPU> on acpi0
cpu1: <ACPI CPU> on acpi0
cpu2: <ACPI CPU> on acpi0
cpu3: <ACPI CPU> on acpi0
hpet0: <High Precision Event Timer> iomem 0xfed00000-0xfed003ff on acpi0
Timecounter "HPET" frequency 14318180 Hz quality 950
Event timer "HPET" frequency 14318180 Hz quality 550
Event timer "HPET1" frequency 14318180 Hz quality 440
Event timer "HPET2" frequency 14318180 Hz quality 440
Event timer "HPET3" frequency 14318180 Hz quality 440
Event timer "HPET4" frequency 14318180 Hz quality 440
atrtc0: <AT realtime clock> port 0x70-0x77 irq 8 on acpi0
atrtc0: Warning: Couldn't map I/O.
Event timer "RTC" frequency 32768 Hz quality 0
attimer0: <AT timer> port 0x40-0x43,0x50-0x53 irq 0 on acpi0
Timecounter "i8254" frequency 1193182 Hz quality 0
Event timer "i8254" frequency 1193182 Hz quality 100
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
acpi_timer0: <24-bit timer at 3.579545MHz> port 0x408-0x40b on acpi0
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
pci0: <ACPI PCI bus> on pcib0
pcib1: <ACPI PCI-PCI bridge> irq 16 at device 1.0 on pci0
pci1: <ACPI PCI bus> on pcib1
vgapci0: <VGA-compatible display> port 0xe000-0xe07f mem 0xf6000000-0xf6ffffff,0xe8000000-0xefffffff,0xf0000000-0xf1ffffff irq 16 at device 0.0 on pci1
nvidia0: <GeForce GT 440> on vgapci0
vgapci0: child nvidia0 requested pci_enable_io
vgapci0: child nvidia0 requested pci_enable_io
vgapci0: Boot video device
pci1: <multimedia, HDA> at device 0.1 (no driver attached)
xhci0: <Intel Panther Point USB 3.0 controller> mem 0xf7200000-0xf720ffff irq 16 at device 20.0 on pci0
xhci0: 32 byte context size.
xhci0: Port routing mask set to 0xffffffff
usbus0 on xhci0
pci0: <simple comms> at device 22.0 (no driver attached)
ehci0: <Intel Panther Point USB 2.0 controller> mem 0xf7218000-0xf72183ff irq 16 at device 26.0 on pci0
usbus1: EHCI version 1.0
usbus1 on ehci0
pci0: <multimedia, HDA> at device 27.0 (no driver attached)
pcib2: <ACPI PCI-PCI bridge> irq 16 at device 28.0 on pci0
pci2: <ACPI PCI bus> on pcib2
pcib3: <PCI-PCI bridge> at device 0.0 on pci2
pci3: <PCI bus> on pcib3
pci3: <multimedia, HDA> at device 0.0 (no driver attached)
pcib4: <ACPI PCI-PCI bridge> irq 17 at device 28.5 on pci0
pci4: <ACPI PCI bus> on pcib4
re0: <RealTek 8168/8111 B/C/CP/D/DP/E/F/G PCIe Gigabit Ethernet> port 0xd000-0xd0ff mem 0xf2104000-0xf2104fff,0xf2100000-0xf2103fff irq 17 at device 0.0 on pci4
re0: Using 1 MSI-X message
re0: Chip rev. 0x2c800000
re0: MAC rev. 0x00100000
miibus0: <MII bus> on re0
rgephy0: <RTL8169S/8110S/8211 1000BASE-T media interface> PHY 1 on miibus0
rgephy0:  none, 10baseT, 10baseT-FDX, 10baseT-FDX-flow, 100baseTX, 100baseTX-FDX, 100baseTX-FDX-flow, 1000baseT, 1000baseT-master, 1000baseT-FDX, 1000baseT-FDX-master, 1000baseT-FDX-flow, 1000baseT-FDX-flow-master, auto, auto-flow
re0: Ethernet address: bc:5f:f4:68:4a:e6
ehci1: <Intel Panther Point USB 2.0 controller> mem 0xf7217000-0xf72173ff irq 23 at device 29.0 on pci0
usbus2: EHCI version 1.0
usbus2 on ehci1
isab0: <PCI-ISA bridge> at device 31.0 on pci0
isa0: <ISA bus> on isab0
ahci0: <Intel Panther Point AHCI SATA controller> port 0xf070-0xf077,0xf060-0xf063,0xf050-0xf057,0xf040-0xf043,0xf020-0xf03f mem 0xf7216000-0xf72167ff irq 19 at device 31.2 on pci0
ahci0: AHCI v1.30 with 6 6Gbps ports, Port Multiplier not supported
ahcich0: <AHCI channel> at channel 0 on ahci0
ahcich1: <AHCI channel> at channel 1 on ahci0
ahcich2: <AHCI channel> at channel 2 on ahci0
ahcich3: <AHCI channel> at channel 3 on ahci0
ahcich4: <AHCI channel> at channel 4 on ahci0
ahcich5: <AHCI channel> at channel 5 on ahci0
ahciem0: <AHCI enclosure management bridge> on ahci0
acpi_button0: <Power Button> on acpi0
ppc1: <Parallel port> port 0x378-0x37f,0x778-0x77f irq 5 drq 3 on acpi0
ppc1: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
ppc1: FIFO with 16/16/9 bytes threshold
ppbus0: <Parallel port bus> on ppc1
lpt0: <Printer> on ppbus0
lpt0: Interrupt-driven port
ppi0: <Parallel I/O> on ppbus0
uart0: <16550 or compatible> port 0x3f8-0x3ff irq 4 flags 0x10 on acpi0
sc0: <System console> at flags 0x100 on isa0
sc0: VGA <16 virtual consoles, flags=0x300>
vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
atkbdc0: <Keyboard controller (i8042)> at port 0x60,0x64 on isa0
atkbd0: <AT Keyboard> irq 1 on atkbdc0
kbd0 at atkbd0
atkbd0: [GIANT-LOCKED]
ppc0: cannot reserve I/O port range
est0: <Enhanced SpeedStep Frequency Control> on cpu0
p4tcc0: <CPU Frequency Thermal Control> on cpu0
est1: <Enhanced SpeedStep Frequency Control> on cpu1
p4tcc1: <CPU Frequency Thermal Control> on cpu1
est2: <Enhanced SpeedStep Frequency Control> on cpu2
p4tcc2: <CPU Frequency Thermal Control> on cpu2
est3: <Enhanced SpeedStep Frequency Control> on cpu3
p4tcc3: <CPU Frequency Thermal Control> on cpu3
random: unblocking device.
usbus0: 5.0Gbps Super Speed USB v3.0
fuse-freebsd: version 0.4.4, FUSE ABI 7.8
Timecounters tick every 1.000 msec
usbus1: 480Mbps High Speed USB v2.0
usbus2: 480Mbps High Speed USB v2.0
ugen2.1: <Intel> at usbus2
uhub0: <Intel EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus2
ugen1.1: <Intel> at usbus1
uhub1: <Intel EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus1
ugen0.1: <0x8086> at usbus0
uhub2: <0x8086 XHCI root HUB, class 9/0, rev 3.00/1.00, addr 1> on usbus0
ada0 at ahcich1 bus 0 scbus1 target 0 lun 0
ada0: <WDC WD5000AAKX-00ERMA0 15.01H15> ATA-8 SATA 3.x device
ada0: Serial Number WD-WMC2E5040869
ada0: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada0: Command Queueing enabled
ada0: 476940MB (976773168 512 byte sectors: 16H 63S/T 16383C)
ada0: Previously was known as ad6
ses0 at ahciem0 bus 0 scbus6 target 0 lun 0
ses0: <AHCI SGPIO Enclosure 1.00 0001> SEMB S-E-S 2.00 device
ses0: SEMB SES Device
SMP: AP CPU #1 Launched!
SMP: AP CPU #2 Launched!
SMP: AP CPU #3 Launched!
Timecounter "TSC-low" frequency 1646297304 Hz quality 1000
uhub2: 8 ports with 8 removable, self powered
Root mount waiting for: usbus2 usbus1 usbus0
uhub1: 2 ports with 2 removable, self powered
uhub0: 2 ports with 2 removable, self powered
ugen0.2: <Genius> at usbus0
Root mount waiting for: usbus2 usbus1 usbus0
ugen1.2: <vendor 0x8087> at usbus1
uhub3: <vendor 0x8087 product 0x0024, class 9/0, rev 2.00/0.00, addr 2> on usbus1
ugen2.2: <vendor 0x8087> at usbus2
uhub4: <vendor 0x8087 product 0x0024, class 9/0, rev 2.00/0.00, addr 2> on usbus2
ugen0.3: <vendor 0x20f4> at usbus0
rsu0: <vendor 0x20f4 product 0x646b, class 0/0, rev 2.00/2.00, addr 2> on usbus0
rsu0: MAC/BB RTL8712 cut 3
uhub4: 6 ports with 6 removable, self powered
uhub3: 6 ports with 6 removable, self powered
Root mount waiting for: usbus2 usbus1
ugen1.3: <UFD 2.0> at usbus1
umass0: <UFD 2.0 Silicon-Power, class 0/0, rev 2.00/11.00, addr 3> on usbus1
umass0:  SCSI over Bulk-Only; quirks = 0x4000
umass0:7:0:-1: Attached to scbus7
da0 at umass-sim0 bus 0 scbus7 target 0 lun 0
da0: <UFD 2.0 Silicon-Power16G 1100> Removable Direct Access SCSI-4 device 
da0: Serial Number 1311371600800280
da0: 40.000MB/s transfers
da0: 15362MB (31461376 512 byte sectors: 255H 63S/T 1958C)
da0: quirks=0x2<NO_6_BYTE>
ugen2.3: <vendor 0x09da> at usbus2
ukbd0: <vendor 0x09da USB Keyboard, class 0/0, rev 1.10/2.50, addr 3> on usbus2
kbd2 at ukbd0
Trying to mount root from ufs:/dev/ada0s1a [rw]...
WARNING: / was not properly dismounted
wlan0: Ethernet address: 00:14:d1:d6:28:33
ums0: <Genius Optical Mouse, class 0/0, rev 1.10/1.00, addr 1> on usbus0
ums0: 3 buttons and [XYZ] coordinates ID=0
uhid0: <vendor 0x09da USB Keyboard, class 0/0, rev 1.10/2.50, addr 3> on usbus2
oss_hdaudio0: <Intel HD Audio> mem 0xf7210000-0xf7213fff irq 22 at device 27.0 on pci0
oss_hdaudio: oss_hdaudio_attach: Already attached
osscore: mmap() not possible with currently selected sample format.
osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: mmap() not possible with currently selected sample format.
osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6osscore: Couldn't retrieve private data from file handle!
WARNING: dev_pager_getpage: map function returns error 6
kernel trap 22 with interrupts disabled
kernel trap 22 with interrupts disabled
ifconfig после загрузки

Код: Выделить всё

re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:5f:f4:68:4a:e6
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (none)
	status: no carrier
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
	inet 127.0.0.1 netmask 0xff000000 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
rsu0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
	options=1<RXCSUM>
	ether 00:14:d1:d6:28:33
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
	status: associated
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 00:14:d1:d6:28:33
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet OFDM/54Mbps mode 11g
	status: associated
	ssid vaflya channel 1 (2412 MHz 11g) bssid 90:f6:52:7d:df:ec
	country US authmode WPA2/802.11i privacy ON deftxkey UNDEF
	TKIP 2:128-bit txpower 0 bmiss 7 scanvalid 60 bgscan bgscanintvl 300
	bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS roaming MANUAL
Недавно вставил адаптер + ifconfig:

Код: Выделить всё

root@localhost:/usr/home/minimatronik # ifconfig
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:5f:f4:68:4a:e6
	inet 192.168.0.102 netmask 0xffffff00 broadcast 192.168.0.255 
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (none)
	status: no carrier
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
	inet 127.0.0.1 netmask 0xff000000 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
rsu0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
	options=1<RXCSUM>
	ether 00:14:d1:d6:28:33
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
	status: associated
wlan0: flags=8803<UP,BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 00:14:d1:d6:28:33
	inet 0.0.0.0 netmask 0xff000000 broadcast 255.255.255.255 
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet OFDM/54Mbps mode 11g
	status: associated
	ssid vaflya channel 1 (2412 MHz 11g) bssid 90:f6:52:7d:df:ec
	country US authmode WPA2/802.11i privacy ON deftxkey UNDEF txpower 0
	bmiss 7 scanvalid 60 bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7
	roam:rate 5 protmode CTS roaming MANUAL
root@localhost:/usr/home/minimatronik # 
ifconfig через секунд 10:

Код: Выделить всё

root@localhost:/usr/home/minimatronik # ifconfig
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:5f:f4:68:4a:e6
	inet 192.168.0.102 netmask 0xffffff00 broadcast 192.168.0.255 
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (none)
	status: no carrier
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
	inet 127.0.0.1 netmask 0xff000000 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
rsu0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
	options=1<RXCSUM>
	ether 00:14:d1:d6:28:33
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
	status: associated
wlan0: flags=8803<UP,BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 00:14:d1:d6:28:33
	inet 0.0.0.0 netmask 0xff000000 broadcast 255.255.255.255 
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect (autoselect)
	status: no carrier
	ssid "" channel 1 (2412 MHz 11g)
	country US authmode WPA2/802.11i privacy ON deftxkey UNDEF txpower 0
	bmiss 7 scanvalid 60 bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7
	roam:rate 5 protmode CTS roaming MANUAL
root@localhost:/usr/home/minimatronik # 
Оставим мою сетку. Рядом есть некая открытая вайфай для телевизора, к ней мой планшет сам успешно подключается и даже есть интернет. Делаем:

Код: Выделить всё

root@localhost:/usr/home/minimatronik # nano /etc/rc.conf

  GNU nano 2.2.6                 File: /etc/rc.conf                                          

hostname=localhost.
ifconfig_re0="DHCP"
sshd_enable="YES"
moused_enable="YES"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"

hald_enable="YES"
dbus_enable="YES"

oss_enable="YES"
oss_mod_load="YES"

linux_enable="YES"

wlans_rsu0="wlan0"
ifconfig_wlan0="ssid DIR-300NRUB7 DHCP"


                                     [ Wrote 18 lines ]

root@localhost:/usr/home/minimatronik # service netif restart
dhclient not running? (check /var/run/dhclient.re0.pid).
/etc/rc.d/netif: WARNING: wlan0 does not exist.  Skipped.
Stopping Network: lo0 re0 rsu0.
lo0: flags=8048<LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
re0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:5f:f4:68:4a:e6
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (none)
	status: no carrier
rsu0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 2290
	options=1<RXCSUM>
	ether 00:14:d1:d6:28:33
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect (autoselect)
	status: no carrier
Starting Network: lo0 re0 rsu0.
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
	inet 127.0.0.1 netmask 0xff000000 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:5f:f4:68:4a:e6
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (none)
	status: no carrier
rsu0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
	options=1<RXCSUM>
	ether 00:14:d1:d6:28:33
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
	status: associated
root@localhost:/usr/home/minimatronik # ifconfig
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:5f:f4:68:4a:e6
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (none)
	status: no carrier
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
	inet 127.0.0.1 netmask 0xff000000 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
rsu0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
	options=1<RXCSUM>
	ether 00:14:d1:d6:28:33
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
	status: associated
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 00:14:d1:d6:28:33
	inet 0.0.0.0 netmask 0xff000000 broadcast 255.255.255.255 
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet OFDM/54Mbps mode 11g
	status: associated
	ssid DIR-300NRUB7 channel 7 (2442 MHz 11g) bssid c8:d3:a3:4a:5c:42
	country US authmode OPEN privacy OFF txpower 0 bmiss 7 scanvalid 60
	bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5
	protmode CTS
root@localhost:/usr/home/minimatronik # ifconfig
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:5f:f4:68:4a:e6
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: Ethernet autoselect (none)
	status: no carrier
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
	inet 127.0.0.1 netmask 0xff000000 
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
rsu0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
	options=1<RXCSUM>
	ether 00:14:d1:d6:28:33
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
	status: associated
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 00:14:d1:d6:28:33
	inet 192.168.0.63 netmask 0xffffff00 broadcast 192.168.0.255 
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet OFDM/54Mbps mode 11g
	status: associated
	ssid DIR-300NRUB7 channel 7 (2442 MHz 11g) bssid c8:d3:a3:4a:5c:42
	country US authmode OPEN privacy OFF txpower 0 bmiss 7 scanvalid 60
	bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5
	protmode CTS
root@localhost:/usr/home/minimatronik #
Потом tcpdump -i wlan0:

Код: Выделить всё

root@localhost:/usr/home/minimatronik # tcpdump -i wlan0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes
21:00:04.069401 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:04.889246 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:06.155482 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:07.157246 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:08.179600 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:09.205604 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:09.948859 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:11.242466 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:12.253625 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28
21:00:13.278844 ARP, Request who-has 192.168.0.1 tell 192.168.0.63, length 28

И ping:

Код: Выделить всё

$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: sendto: No route to host
ping: sendto: No route to host
ping: sendto: No route to host
ping: sendto: No route to host
ping: sendto: No route to host
^C
--- 8.8.8.8 ping statistics ---
10 packets transmitted, 0 packets received, 100.0% packet loss
$ 
Некоторые конфиги:

Код: Выделить всё

$ cat /etc/rc.conf
hostname=localhost.
ifconfig_re0="DHCP"
sshd_enable="YES"
moused_enable="YES"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"

hald_enable="YES"
dbus_enable="YES"

oss_enable="YES"
oss_mod_load="YES"

linux_enable="YES"

wlans_rsu0="wlan0"
ifconfig_wlan0="ssid DIR-300NRUB7 SYNCDHCP"

$ 

Код: Выделить всё

$ cat /etc/wpa_supplicant.conf 
network={
	ssid="vaflya"
	proto=WPA RSN
	key_mgmt=WPA-PSK
	#psk="pass"
	psk=pass_hash
}
$ 

Код: Выделить всё

$ cat /etc/dhclient.conf
$ 
В dhclient.conf были закомментированные строки, сменил файл когда думал редактировать:

Код: Выделить всё

$ cat /etc/dhclient.conf.old 
# $FreeBSD: releng/10.1/etc/dhclient.conf 85575 2001-10-27 03:14:37Z rwatson $
#
#	This file is required by the ISC DHCP client.
#	See ``man 5 dhclient.conf'' for details.
#
#	In most cases an empty file is sufficient for most people as the
#	defaults are usually fine.
#
$ 

Код: Выделить всё

root@localhost:/usr/home/minimatronik # ifconfig wlan0 up scan
SSID/MESH ID    BSSID              CHAN RATE   S:N     INT CAPS
сетки...
моя на перезагрузке..
сетки..
DIR-300NRUB7    c8:d3:a3:4a:5c:42    7   54M  50:0    100 E    HTCAP WME
root@localhost:/usr/home/minimatronik # 
Сейчас ребутнул сеть, к свободному вайфаю подключилось:

Код: Выделить всё

root@localhost:/usr/home/minimatronik # ifconfig wlan0
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 00:14:d1:d6:28:33
	inet 192.168.0.63 netmask 0xffffff00 broadcast 192.168.0.255 
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet OFDM/54Mbps mode 11g
	status: associated
	ssid DIR-300NRUB7 channel 7 (2442 MHz 11g) bssid c8:d3:a3:4a:5c:42
	country US authmode OPEN privacy OFF txpower 0 bmiss 7 scanvalid 60
	bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5
	protmode CTS
root@localhost:/usr/home/minimatronik # 
Делаю ping:

Код: Выделить всё

$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
и зависло.
На адаптере мигает индикатор и раздается тихое шипение при каждом моргании. Немного тепловат. Адаптер размером с 2/3 зажигалки. Потом:

Код: Выделить всё

^C
--- 8.8.8.8 ping statistics ---
843 packets transmitted, 0 packets received, 100.0% packet loss
$ 
Изредка мигает, шипения нет.

Подключаю кабель ethernet, который идет от маршрутизатора - интернет есть.
wpa_supplicant.conf менял до минимума, как в хендбуке написано, пробовал разные настройки. Ставил в rc.conf ifconfig_wlan0="WPA DHCP" . На минимальных настройках все работало.
Пинг не идет, страницы в браузере не грузятся. Что делать?


minimatronik
рядовой
Сообщения: 13
Зарегистрирован: 2014-11-18 16:29:23

Wifi адаптер Trendnet TEW-646UBH и FreeBSD

Непрочитанное сообщение minimatronik » 2015-02-26 21:41:25

На PC-BSD 11 Testing(Beta)(FreeBSD + Desktop) закоммитенно и адаптер обнаруживается, не шипит \ система не падает если адаптер достать и прочее, однако сети с начало не было. Решилось выставлением основного шлюза 192.168.0.255. Но все равно сеть не стабильна - не всегда \ сразу подключается, но это уже проблемы с провайдером \ маршрутизатором.