Add support for the Realtek RTL8192EU chipset.

Committed over the D-Link DWA-131 rev E1 on amd64 with WPA.

Reviewed by:	avos
This commit is contained in:
Kevin Lo 2017-01-24 02:35:38 +00:00
parent 83988d944b
commit 60b9567d16
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=312680
43 changed files with 3097 additions and 76 deletions

View File

@ -2737,7 +2737,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+"; match "bus" "uhub[0-9]+";
match "mode" "host"; match "mode" "host";
match "vendor" "0x0bda"; match "vendor" "0x0bda";
match "product" "(0x8176|0x8177|0x8178|0x8179|0x817a|0x817b|0x817c|0x817d|0x817e|0x817f)"; match "product" "(0x8176|0x8177|0x8178|0x8178|0x8179|0x817a|0x817b|0x817c|0x817d|0x817e|0x817f)";
action "kldload -n if_rtwn_usb"; action "kldload -n if_rtwn_usb";
}; };
@ -2753,7 +2753,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+"; match "bus" "uhub[0-9]+";
match "mode" "host"; match "mode" "host";
match "vendor" "0x0bda"; match "vendor" "0x0bda";
match "product" "(0x818a|0x8191)"; match "product" "(0x818a|0x818b|0x8191)";
action "kldload -n if_rtwn_usb"; action "kldload -n if_rtwn_usb";
}; };
@ -3793,7 +3793,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+"; match "bus" "uhub[0-9]+";
match "mode" "host"; match "mode" "host";
match "vendor" "0x1199"; match "vendor" "0x1199";
match "product" "(0x68aa|0x68c0|0x9041)"; match "product" "(0x68aa|0x68c0|0x9041|0x9071)";
action "kldload -n u3g"; action "kldload -n u3g";
}; };
@ -3905,7 +3905,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+"; match "bus" "uhub[0-9]+";
match "mode" "host"; match "mode" "host";
match "vendor" "0x12d1"; match "vendor" "0x12d1";
match "product" "(0x1573|0x1803|0x1c05|0x1c0b)"; match "product" "(0x1573|0x15c1|0x1803|0x1c05|0x1c0b)";
action "kldload -n u3g"; action "kldload -n u3g";
}; };
@ -5025,7 +5025,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+"; match "bus" "uhub[0-9]+";
match "mode" "host"; match "mode" "host";
match "vendor" "0x2001"; match "vendor" "0x2001";
match "product" "(0x3307|0x3308|0x3309|0x330a|0x330d|0x330f|0x3310|0x3314|0x3315|0x3316|0x3318)"; match "product" "(0x3307|0x3308|0x3309|0x330a|0x330d|0x330f|0x3310|0x3314|0x3315|0x3316|0x3318|0x3319)";
action "kldload -n if_rtwn_usb"; action "kldload -n if_rtwn_usb";
}; };
@ -5297,7 +5297,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+"; match "bus" "uhub[0-9]+";
match "mode" "host"; match "mode" "host";
match "vendor" "0x2357"; match "vendor" "0x2357";
match "product" "0x0101"; match "product" "(0x0101|0x0108|0x0109)";
action "kldload -n if_rtwn_usb"; action "kldload -n if_rtwn_usb";
}; };
@ -5889,5 +5889,5 @@ nomatch 32 {
action "kldload -n umass"; action "kldload -n umass";
}; };
# 2743 USB entries processed # 2751 USB entries processed

View File

@ -18,7 +18,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd October 17, 2016 .Dd January 24, 2017
.Dt RTWN 4 .Dt RTWN 4
.Os .Os
.Sh NAME .Sh NAME
@ -52,9 +52,9 @@ if_rtwn_usb_load="YES"
The The
.Nm .Nm
driver provides support for wireless network devices based on driver provides support for wireless network devices based on
the Realtek RTL8192C, RTL8188E, RTL8812A and RTL8821A programming APIs. the Realtek RTL8192C, RTL8188E, RTL8192E, RTL8812A and RTL8821A
These APIs are used by a wide variety of chips; most chips with USB programming APIs. These APIs are used by a wide variety of chips;
and some with PCI interface are supported. most chips with USB and some with PCI interface are supported.
.Pp .Pp
To enable use for PCI/PCIe systems, see the rtwn_pci(4) driver; To enable use for PCI/PCIe systems, see the rtwn_pci(4) driver;
for USB devices, use the rtwn_usb(4) driver. for USB devices, use the rtwn_usb(4) driver.
@ -98,6 +98,7 @@ when an interface is brought up:
.It Pa /boot/kernel/rtwn-rtl8192cfwE.ko .It Pa /boot/kernel/rtwn-rtl8192cfwE.ko
.It Pa /boot/kernel/rtwn-rtl8192cfwT.ko .It Pa /boot/kernel/rtwn-rtl8192cfwT.ko
.It Pa /boot/kernel/rtwn-rtl8192cfwU.ko .It Pa /boot/kernel/rtwn-rtl8192cfwU.ko
.It Pa /boot/kernel/rtwn-rtl8192eufw.ko
.It Pa /boot/kernel/rtwn-rtl8812aufw.ko .It Pa /boot/kernel/rtwn-rtl8812aufw.ko
.It Pa /boot/kernel/rtwn-rtl8821aufw.ko .It Pa /boot/kernel/rtwn-rtl8821aufw.ko
.El .El

View File

@ -29,7 +29,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\"/ .\"/
.Dd January 6, 2017 .Dd January 24, 2017
.Dt RTWN_USB 4 .Dt RTWN_USB 4
.Os .Os
.Sh NAME .Sh NAME
@ -56,7 +56,7 @@ driver.
.Sh HARDWARE .Sh HARDWARE
The The
.Nm .Nm
driver supports Realtek RTL8188CU/RTL8188RU/RTL8188EU/RTL8192CU/RTL8812AU/RTL8821AU driver supports Realtek RTL8188CU/RTL8188RU/RTL8188EU/RTL8192CU/RTL8192EU/RTL8812AU/RTL8821AU
based USB wireless network adapters, including: based USB wireless network adapters, including:
.Pp .Pp
.Bl -column -compact "Belkin F7D1102 Surf Wireless Micro" "Bus" .Bl -column -compact "Belkin F7D1102 Surf Wireless Micro" "Bus"
@ -70,6 +70,7 @@ based USB wireless network adapters, including:
.It "D-Link DWA-123 rev D1" Ta USB 2.0 .It "D-Link DWA-123 rev D1" Ta USB 2.0
.It "D-Link DWA-125 rev D1" Ta USB 2.0 .It "D-Link DWA-125 rev D1" Ta USB 2.0
.It "D-Link DWA-131" Ta USB 2.0 .It "D-Link DWA-131" Ta USB 2.0
.It "D-Link DWA-131 rev E1" Ta USB 2.0
.It "D-Link DWA-171 rev A1" Ta USB 2.0 .It "D-Link DWA-171 rev A1" Ta USB 2.0
.It "D-Link DWA-172 rev A1" Ta USB 2.0 .It "D-Link DWA-172 rev A1" Ta USB 2.0
.It "D-Link DWA-180 rev A1" Ta USB 2.0 .It "D-Link DWA-180 rev A1" Ta USB 2.0
@ -94,7 +95,10 @@ based USB wireless network adapters, including:
.It "TP-LINK TL-WN723N v3" Ta USB 2.0 .It "TP-LINK TL-WN723N v3" Ta USB 2.0
.It "TP-LINK TL-WN725N v2" Ta USB 2.0 .It "TP-LINK TL-WN725N v2" Ta USB 2.0
.It "TP-LINK TL-WN821N v4" Ta USB 2.0 .It "TP-LINK TL-WN821N v4" Ta USB 2.0
.It "TP-LINK TL-WN821N v5" Ta USB 2.0
.It "TP-LINK TL-WN822N v4" Ta USB 2.0
.It "TP-LINK TL-WN823N v1" Ta USB 2.0 .It "TP-LINK TL-WN823N v1" Ta USB 2.0
.It "TP-LINK TL-WN823N v2" Ta USB 2.0
.It "TRENDnet TEW-805UB" Ta USB 3.0 .It "TRENDnet TEW-805UB" Ta USB 3.0
.It "ZyXEL NWD6605" Ta USB 3.0 .It "ZyXEL NWD6605" Ta USB 3.0
.El .El

View File

@ -23,7 +23,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd October 28, 2015 .Dd January 24, 2017
.Dt RTWNFW 4 .Dt RTWNFW 4
.Os .Os
.Sh NAME .Sh NAME
@ -46,6 +46,7 @@ of the following:
.Cd "device rtwn-rtl8192cfwE" .Cd "device rtwn-rtl8192cfwE"
.Cd "device rtwn-rtl8192cfwT" .Cd "device rtwn-rtl8192cfwT"
.Cd "device rtwn-rtl8192cfwU" .Cd "device rtwn-rtl8192cfwU"
.Cd "device rtwn-rtl8192eufw"
.Cd "device rtwn-rtl8812aufw" .Cd "device rtwn-rtl8812aufw"
.Cd "device rtwn-rtl8821aufw" .Cd "device rtwn-rtl8821aufw"
.Ed .Ed
@ -59,6 +60,7 @@ rtwn-rtl8192cfwE_B_load="YES"
rtwn-rtl8192cfwE_load="YES" rtwn-rtl8192cfwE_load="YES"
rtwn-rtl8192cfwT_load="YES" rtwn-rtl8192cfwT_load="YES"
rtwn-rtl8192cfwU_load="YES" rtwn-rtl8192cfwU_load="YES"
rtwn-rtl8192eufw_load="YES"
rtwn-rtl8812aufw_load="YES" rtwn-rtl8812aufw_load="YES"
rtwn-rtl8821aufw_load="YES" rtwn-rtl8821aufw_load="YES"
.Ed .Ed
@ -66,8 +68,8 @@ rtwn-rtl8821aufw_load="YES"
rtwn-rtl8192cfwE and rtl8192cfwE_B modules provide access rtwn-rtl8192cfwE and rtl8192cfwE_B modules provide access
to firmware sets for the Realtek RTL8188CE chip based PCIe adapters. to firmware sets for the Realtek RTL8188CE chip based PCIe adapters.
Other modules provide access to firmware sets for the Realtek RTL8188CUS, Other modules provide access to firmware sets for the Realtek RTL8188CUS,
RTL8188CE-VAU, RTL8188EUS, RTL8188RU, RTL8192CU, RTL8812AU and RTL8821AU RTL8188CE-VAU, RTL8188EUS, RTL8188RU, RTL8192CU, RTL8192EU, RTL8812AU and
chip based USB WiFi adapters. RTL8821AU chip based USB WiFi adapters.
They may be They may be
statically linked into the kernel, or loaded as a modules. statically linked into the kernel, or loaded as a modules.
.Pp .Pp

View File

@ -2674,6 +2674,7 @@ dev/rtwn/rtl8192c/r92c_calib.c optional rtwn
dev/rtwn/rtl8192c/r92c_chan.c optional rtwn dev/rtwn/rtl8192c/r92c_chan.c optional rtwn
dev/rtwn/rtl8192c/r92c_fw.c optional rtwn dev/rtwn/rtl8192c/r92c_fw.c optional rtwn
dev/rtwn/rtl8192c/r92c_init.c optional rtwn dev/rtwn/rtl8192c/r92c_init.c optional rtwn
dev/rtwn/rtl8192c/r92c_llt.c optional rtwn
dev/rtwn/rtl8192c/r92c_rf.c optional rtwn dev/rtwn/rtl8192c/r92c_rf.c optional rtwn
dev/rtwn/rtl8192c/r92c_rom.c optional rtwn dev/rtwn/rtl8192c/r92c_rom.c optional rtwn
dev/rtwn/rtl8192c/r92c_rx.c optional rtwn dev/rtwn/rtl8192c/r92c_rx.c optional rtwn
@ -2690,6 +2691,16 @@ dev/rtwn/rtl8192c/usb/r92cu_init.c optional rtwn_usb
dev/rtwn/rtl8192c/usb/r92cu_led.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_led.c optional rtwn_usb
dev/rtwn/rtl8192c/usb/r92cu_rx.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_rx.c optional rtwn_usb
dev/rtwn/rtl8192c/usb/r92cu_tx.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_tx.c optional rtwn_usb
# RTL8192E
dev/rtwn/rtl8192e/r92e_chan.c optional rtwn
dev/rtwn/rtl8192e/r92e_fw.c optional rtwn
dev/rtwn/rtl8192e/r92e_init.c optional rtwn
dev/rtwn/rtl8192e/r92e_led.c optional rtwn
dev/rtwn/rtl8192e/r92e_rf.c optional rtwn
dev/rtwn/rtl8192e/r92e_rom.c optional rtwn
dev/rtwn/rtl8192e/r92e_rx.c optional rtwn
dev/rtwn/rtl8192e/usb/r92eu_attach.c optional rtwn_usb
dev/rtwn/rtl8192e/usb/r92eu_init.c optional rtwn_usb
# RTL8812A # RTL8812A
dev/rtwn/rtl8812a/r12a_beacon.c optional rtwn dev/rtwn/rtl8812a/r12a_beacon.c optional rtwn
dev/rtwn/rtl8812a/r12a_calib.c optional rtwn dev/rtwn/rtl8812a/r12a_calib.c optional rtwn
@ -2788,6 +2799,20 @@ rtwn-rtl8192cfwU.fw optional rtwn-rtl8192cfwU | rtwnfw \
compile-with "${NORMAL_FW}" \ compile-with "${NORMAL_FW}" \
no-obj no-implicit-rule \ no-obj no-implicit-rule \
clean "rtwn-rtl8192cfwU.fw" clean "rtwn-rtl8192cfwU.fw"
rtwn-rtl8192eufw.c optional rtwn-rtl8192eufw | rtwnfw \
compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192eufw.fw:rtwn-rtl8192eufw:111 -mrtwn-rtl8192eufw -c${.TARGET}" \
no-implicit-rule before-depend local \
clean "rtwn-rtl8192eufw.c"
rtwn-rtl8192eufw.fwo optional rtwn-rtl8192eufw | rtwnfw \
dependency "rtwn-rtl8192eufw.fw" \
compile-with "${NORMAL_FWO}" \
no-implicit-rule \
clean "rtwn-rtl8192eufw.fwo"
rtwn-rtl8192eufw.fw optional rtwn-rtl8192eufw | rtwnfw \
dependency "$S/contrib/dev/rtwn/rtwn-rtl8192eufw.fw.uu" \
compile-with "${NORMAL_FW}" \
no-obj no-implicit-rule \
clean "rtwn-rtl8192eufw.fw"
rtwn-rtl8812aufw.c optional rtwn-rtl8812aufw | rtwnfw \ rtwn-rtl8812aufw.c optional rtwn-rtl8812aufw | rtwnfw \
compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8812aufw.fw:rtwn-rtl8812aufw:111 -mrtwn-rtl8812aufw -c${.TARGET}" \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8812aufw.fw:rtwn-rtl8812aufw:111 -mrtwn-rtl8812aufw -c${.TARGET}" \
no-implicit-rule before-depend local \ no-implicit-rule before-depend local \

View File

@ -0,0 +1,711 @@
begin 644 rtwn-rtl8192eufw.fw.uu
MX9(0`!,````#,1%`*GP``+@0```````````````````"24T"7_4`````````
M`````````F`Y``````````````````)P*```````````````````````````
M`````````````E_V```````":$@```````)OZ@WP_P\````-\`\`````#?#_
M#P````WP#P`````0\/\/````$/`/`````/4/``````#P#P``````#0``````
M`!#P__\````0\#\`````"@@#`P`$"0<#`P`$"`8#`@`$"`4#`0`$#0H'!0`(
M#`H'!``("PH&!0`("PH%`P`("PH#`@`(%!(,!``0%!()!``0)"(<$@`@)"(8
M#``@)"(4!@`@)"(/!``@)"$*!``@(R$,!``@(Q\*!``@(A\/!``@(1\6#``@
M,2\@%``P,2\8$``P,2P8#``P,2H4#``P,2@4```P,204```P,1X4```P`@("
M!0($!0<'!P@*`0($!@<*"PT"`P0'"`L-#P4%!P<("PT/!04'!P@+#0\!`@,&
M!PH+#`T.`@,$!P@+#`T.$`4%!P<("PT/#P\%!0<'"`L-#P\/!`0$!0<'"0D,
M#A`2!`4&!PL-$1,$!08'"PT1$PD)"0D,#A$3"0D)"0P.$1,$"`D*#`X0$A,4
M!`@*#`X0$1,4%@D)"0D,#A$3$Q,)"0D)#`X1$Q,3````````````)"8J````
M'R$E)R@`````(R8H*@`````C)B@J`````",F*"H`````("4G*2DJ`````"`E
M)RDI*@`````C)B@J*BH````?(R8H*BHJ````!`````0````(````$````!@`
M```D````,````$@```!@````D````,````#8````/````&0```!X````H```
M`/````%````!D````>````"@````\````4````&0```"6````R````9````'
MT````,@```$8```!X````M````/H```$L```!D````?0````R````1@```'@
M```"T````^@```2P```&0```!]`````\````9````'@```"@````\````4``
M``&0```!X```!+````E@````R````1@```'@```"T````^@```?0```+N```
M$X@``!=P```?0````,@```$8```!X````M````/H```$L```!D````?0```'
MT```!]````#(```!&````>````+0```#Z```!+````9````'T```!]````?0
M``(``@`$``@`#``2`!@`)``P`$@`8`!L`!X`,@`\`%``>`"@`,@`\`!0`'@`
MH`#(`2P!D`.$!10`9`",`/`!:`'T`E@#(`/H`&0`C`#P`6@!]`)8`R`#Z``>
M`#(`/`!0`'@`H`#(`/`"6`2P`&0`C`#P`6@!]`/H!=P)Q`NX#Z``9`",`/`!
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
#`*FO
`
end

View File

@ -121,9 +121,6 @@ static int rtwn_run(struct rtwn_softc *,
static void rtwn_watchdog(void *); static void rtwn_watchdog(void *);
#endif #endif
static void rtwn_parent(struct ieee80211com *); static void rtwn_parent(struct ieee80211com *);
static int rtwn_llt_write(struct rtwn_softc *, uint32_t,
uint32_t);
static int rtwn_llt_init(struct rtwn_softc *);
static int rtwn_dma_init(struct rtwn_softc *); static int rtwn_dma_init(struct rtwn_softc *);
static int rtwn_mac_init(struct rtwn_softc *); static int rtwn_mac_init(struct rtwn_softc *);
static void rtwn_mrr_init(struct rtwn_softc *); static void rtwn_mrr_init(struct rtwn_softc *);
@ -1383,54 +1380,6 @@ rtwn_parent(struct ieee80211com *ic)
rtwn_stop(sc); rtwn_stop(sc);
} }
static int
rtwn_llt_write(struct rtwn_softc *sc, uint32_t addr, uint32_t data)
{
int ntries, error;
error = rtwn_write_4(sc, R92C_LLT_INIT,
SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
SM(R92C_LLT_INIT_ADDR, addr) |
SM(R92C_LLT_INIT_DATA, data));
if (error != 0)
return (error);
/* Wait for write operation to complete. */
for (ntries = 0; ntries < 20; ntries++) {
if (MS(rtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
R92C_LLT_INIT_OP_NO_ACTIVE)
return (0);
rtwn_delay(sc, 10);
}
return (ETIMEDOUT);
}
static int
rtwn_llt_init(struct rtwn_softc *sc)
{
int i, error;
/* Reserve pages [0; page_count]. */
for (i = 0; i < sc->page_count; i++) {
if ((error = rtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
/* NB: 0xff indicates end-of-list. */
if ((error = rtwn_llt_write(sc, i, 0xff)) != 0)
return (error);
/*
* Use pages [page_count + 1; pktbuf_count - 1]
* as ring buffer.
*/
for (++i; i < sc->pktbuf_count - 1; i++) {
if ((error = rtwn_llt_write(sc, i, i + 1)) != 0)
return (error);
}
/* Make the last page point to the beginning of the ring buffer. */
error = rtwn_llt_write(sc, i, sc->page_count + 1);
return (error);
}
static int static int
rtwn_dma_init(struct rtwn_softc *sc) rtwn_dma_init(struct rtwn_softc *sc)
{ {

View File

@ -308,6 +308,7 @@ struct rtwn_softc {
void (*sc_fw_reset)(struct rtwn_softc *, int); void (*sc_fw_reset)(struct rtwn_softc *, int);
void (*sc_fw_download_enable)(struct rtwn_softc *, int); void (*sc_fw_download_enable)(struct rtwn_softc *, int);
#endif #endif
int (*sc_llt_init)(struct rtwn_softc *);
int (*sc_set_page_size)(struct rtwn_softc *); int (*sc_set_page_size)(struct rtwn_softc *);
void (*sc_lc_calib)(struct rtwn_softc *); void (*sc_lc_calib)(struct rtwn_softc *);
void (*sc_iq_calib)(struct rtwn_softc *); void (*sc_iq_calib)(struct rtwn_softc *);
@ -472,8 +473,8 @@ void rtwn_suspend(struct rtwn_softc *);
/* Aliases. */ /* Aliases. */
#define rtwn_bb_write rtwn_write_4 #define rtwn_bb_write rtwn_write_4
#define rtwn_bb_read rtwn_read_4 #define rtwn_bb_read rtwn_read_4
#define rtwn_bb_setbits rtwn_setbits_4 #define rtwn_bb_setbits rtwn_setbits_4
/* Device-specific. */ /* Device-specific. */
#define rtwn_rf_read(_sc, _chain, _addr) \ #define rtwn_rf_read(_sc, _chain, _addr) \
@ -504,6 +505,8 @@ void rtwn_suspend(struct rtwn_softc *);
#define rtwn_fw_download_enable(_sc, _enable) \ #define rtwn_fw_download_enable(_sc, _enable) \
(((_sc)->sc_fw_download_enable)((_sc), (_enable))) (((_sc)->sc_fw_download_enable)((_sc), (_enable)))
#endif #endif
#define rtwn_llt_init(_sc) \
(((_sc)->sc_llt_init)((_sc)))
#define rtwn_set_page_size(_sc) \ #define rtwn_set_page_size(_sc) \
(((_sc)->sc_set_page_size)((_sc))) (((_sc)->sc_set_page_size)((_sc)))
#define rtwn_lc_calib(_sc) \ #define rtwn_lc_calib(_sc) \

View File

@ -146,6 +146,7 @@ r88eu_attach(struct rtwn_usb_softc *uc)
sc->sc_fw_reset = r88e_fw_reset; sc->sc_fw_reset = r88e_fw_reset;
sc->sc_fw_download_enable = r88e_fw_download_enable; sc->sc_fw_download_enable = r88e_fw_download_enable;
#endif #endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r92c_set_page_size; sc->sc_set_page_size = r92c_set_page_size;
sc->sc_lc_calib = r92c_lc_calib; sc->sc_lc_calib = r92c_lc_calib;
sc->sc_iq_calib = r88e_iq_calib; /* XXX TODO */ sc->sc_iq_calib = r88e_iq_calib; /* XXX TODO */

View File

@ -191,6 +191,7 @@ r92ce_attach(struct rtwn_pci_softc *pc)
sc->sc_fw_reset = r92ce_fw_reset; sc->sc_fw_reset = r92ce_fw_reset;
sc->sc_fw_download_enable = r92c_fw_download_enable; sc->sc_fw_download_enable = r92c_fw_download_enable;
#endif #endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r92c_set_page_size; sc->sc_set_page_size = r92c_set_page_size;
sc->sc_lc_calib = r92c_lc_calib; sc->sc_lc_calib = r92c_lc_calib;
sc->sc_iq_calib = r92ce_iq_calib; sc->sc_iq_calib = r92ce_iq_calib;

View File

@ -77,6 +77,7 @@ void r92c_handle_c2h_report(void *);
/* r92c_init.c */ /* r92c_init.c */
int r92c_check_condition(struct rtwn_softc *, const uint8_t[]); int r92c_check_condition(struct rtwn_softc *, const uint8_t[]);
int r92c_llt_init(struct rtwn_softc *);
int r92c_set_page_size(struct rtwn_softc *); int r92c_set_page_size(struct rtwn_softc *);
void r92c_init_bb_common(struct rtwn_softc *); void r92c_init_bb_common(struct rtwn_softc *);
int r92c_init_rf_chain(struct rtwn_softc *, int r92c_init_rf_chain(struct rtwn_softc *,
@ -87,6 +88,9 @@ void r92c_init_ampdu(struct rtwn_softc *);
void r92c_init_antsel(struct rtwn_softc *); void r92c_init_antsel(struct rtwn_softc *);
void r92c_pa_bias_init(struct rtwn_softc *); void r92c_pa_bias_init(struct rtwn_softc *);
/* r92c_llt.c */
int r92c_llt_write(struct rtwn_softc *, uint32_t, uint32_t);
/* r92c_rf.c */ /* r92c_rf.c */
uint32_t r92c_rf_read(struct rtwn_softc *, int, uint8_t); uint32_t r92c_rf_read(struct rtwn_softc *, int, uint8_t);
void r92c_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t); void r92c_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t);

View File

@ -89,6 +89,32 @@ r92c_check_condition(struct rtwn_softc *sc, const uint8_t cond[])
return (0); return (0);
} }
int
r92c_llt_init(struct rtwn_softc *sc)
{
int i, error;
/* Reserve pages [0; page_count]. */
for (i = 0; i < sc->page_count; i++) {
if ((error = r92c_llt_write(sc, i, i + 1)) != 0)
return (error);
}
/* NB: 0xff indicates end-of-list. */
if ((error = r92c_llt_write(sc, i, 0xff)) != 0)
return (error);
/*
* Use pages [page_count + 1; pktbuf_count - 1]
* as ring buffer.
*/
for (++i; i < sc->pktbuf_count - 1; i++) {
if ((error = r92c_llt_write(sc, i, i + 1)) != 0)
return (error);
}
/* Make the last page point to the beginning of the ring buffer. */
error = r92c_llt_write(sc, i, sc->page_count + 1);
return (error);
}
int int
r92c_set_page_size(struct rtwn_softc *sc) r92c_set_page_size(struct rtwn_softc *sc)
{ {

View File

@ -0,0 +1,73 @@
/* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
* Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org>
*
* 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$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
int
r92c_llt_write(struct rtwn_softc *sc, uint32_t addr, uint32_t data)
{
int ntries, error;
error = rtwn_write_4(sc, R92C_LLT_INIT,
SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
SM(R92C_LLT_INIT_ADDR, addr) |
SM(R92C_LLT_INIT_DATA, data));
if (error != 0)
return (error);
/* Wait for write operation to complete. */
for (ntries = 0; ntries < 20; ntries++) {
if (MS(rtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
R92C_LLT_INIT_OP_NO_ACTIVE)
return (0);
rtwn_delay(sc, 10);
}
return (ETIMEDOUT);
}

View File

@ -66,6 +66,7 @@
#define R92C_HSIMR 0x058 #define R92C_HSIMR 0x058
#define R92C_HSISR 0x05c #define R92C_HSISR 0x05c
#define R92C_MULTI_FUNC_CTRL 0x068 #define R92C_MULTI_FUNC_CTRL 0x068
#define R92C_LDO_SWR_CTRL 0x07c
#define R92C_MCUFWDL 0x080 #define R92C_MCUFWDL 0x080
#define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2) #define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2)
#define R92C_EFUSE_ACCESS 0x0cf #define R92C_EFUSE_ACCESS 0x0cf
@ -115,6 +116,7 @@
#define R92C_TXDMA_OFFSET_CHK 0x20c #define R92C_TXDMA_OFFSET_CHK 0x20c
#define R92C_TXDMA_STATUS 0x210 #define R92C_TXDMA_STATUS 0x210
#define R92C_RQPN_NPQ 0x214 #define R92C_RQPN_NPQ 0x214
#define R92C_AUTO_LLT 0x224
/* Rx DMA Configuration. */ /* Rx DMA Configuration. */
#define R92C_RXDMA_AGG_PG_TH 0x280 #define R92C_RXDMA_AGG_PG_TH 0x280
#define R92C_RXPKT_NUM 0x284 #define R92C_RXPKT_NUM 0x284
@ -297,6 +299,16 @@
#define R92C_SYS_CLKR_SYS_EN 0x00001000 #define R92C_SYS_CLKR_SYS_EN 0x00001000
#define R92C_SYS_CLKR_RING_EN 0x00002000 #define R92C_SYS_CLKR_RING_EN 0x00002000
/* Bits for R92C_RSV_CTRL. */
#define R92C_RSV_CTRL_WLOCK_ALL 0x01
#define R92C_RSV_CTRL_WLOCK_00 0x02
#define R92C_RSV_CTRL_WLOCK_04 0x04
#define R92C_RSV_CTRL_WLOCK_08 0x08
#define R92C_RSV_CTRL_WLOCK_40 0x10
#define R92C_RSV_CTRL_R_DIS_PRST_0 0x20
#define R92C_RSV_CTRL_R_DIS_PRST_1 0x40
#define R92C_RSV_CTRL_LOCK_ALL_EN 0x80
/* Bits for R92C_RF_CTRL. */ /* Bits for R92C_RF_CTRL. */
#define R92C_RF_CTRL_EN 0x01 #define R92C_RF_CTRL_EN 0x01
#define R92C_RF_CTRL_RSTB 0x02 #define R92C_RF_CTRL_RSTB 0x02
@ -339,6 +351,9 @@
/* Bits for R92C_LEDCFG0. */ /* Bits for R92C_LEDCFG0. */
#define R92C_LEDCFG0_DIS 0x08 #define R92C_LEDCFG0_DIS 0x08
/* Bits for R92C_LEDCFG1. */
#define R92C_LEDCFG1_DIS 0x80
/* Bits for R92C_MULTI_FUNC_CTRL. */ /* Bits for R92C_MULTI_FUNC_CTRL. */
#define R92C_MULTI_BT_FUNC_EN 0x00040000 #define R92C_MULTI_BT_FUNC_EN 0x00040000
@ -477,6 +492,9 @@
/* Bits for R92C_TXDMA_OFFSET_CHK. */ /* Bits for R92C_TXDMA_OFFSET_CHK. */
#define R92C_TXDMA_OFFSET_DROP_DATA_EN 0x00000200 #define R92C_TXDMA_OFFSET_DROP_DATA_EN 0x00000200
/* Bits for R92C_AUTO_LLT. */
#define R92C_AUTO_LLT_INIT 0x00010000
/* Bits for R92C_FWHW_TXQ_CTRL. */ /* Bits for R92C_FWHW_TXQ_CTRL. */
#define R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW 0x80 #define R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW 0x80
#define R92C_FWHW_TXQ_CTRL_REAL_BEACON 0x400000 #define R92C_FWHW_TXQ_CTRL_REAL_BEACON 0x400000
@ -683,6 +701,7 @@
#define R92C_OFDM0_TXIQIMBALANCE(chain) (0xc80 + (chain) * 8) #define R92C_OFDM0_TXIQIMBALANCE(chain) (0xc80 + (chain) * 8)
#define R92C_OFDM0_TXAFE(chain) (0xc94 + (chain) * 8) #define R92C_OFDM0_TXAFE(chain) (0xc94 + (chain) * 8)
#define R92C_OFDM0_RXIQEXTANTA 0xca0 #define R92C_OFDM0_RXIQEXTANTA 0xca0
#define R92C_OFDM0_TXPSEUDONOISEWGT 0xce4
#define R92C_OFDM1_LSTF 0xd00 #define R92C_OFDM1_LSTF 0xd00
/* Bits for R92C_FPGA[01]_RFMOD. */ /* Bits for R92C_FPGA[01]_RFMOD. */
@ -802,6 +821,9 @@
#define R92C_LSSI_READBACK_DATA_M 0x000fffff #define R92C_LSSI_READBACK_DATA_M 0x000fffff
#define R92C_LSSI_READBACK_DATA_S 0 #define R92C_LSSI_READBACK_DATA_S 0
/* Bits for R92C_CCK0_SYSTEM. */
#define R92C_CCK0_SYSTEM_CCK_SIDEBAND 0x00000010
/* Bits for R92C_OFDM0_AGCCORE1(i). */ /* Bits for R92C_OFDM0_AGCCORE1(i). */
#define R92C_OFDM0_AGCCORE1_GAIN_M 0x0000007f #define R92C_OFDM0_AGCCORE1_GAIN_M 0x0000007f
#define R92C_OFDM0_AGCCORE1_GAIN_S 0 #define R92C_OFDM0_AGCCORE1_GAIN_S 0

View File

@ -184,6 +184,7 @@ r92cu_attach(struct rtwn_usb_softc *uc)
sc->sc_fw_reset = r92c_fw_reset; sc->sc_fw_reset = r92c_fw_reset;
sc->sc_fw_download_enable = r92c_fw_download_enable; sc->sc_fw_download_enable = r92c_fw_download_enable;
#endif #endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r92c_set_page_size; sc->sc_set_page_size = r92c_set_page_size;
sc->sc_lc_calib = r92c_lc_calib; sc->sc_lc_calib = r92c_lc_calib;
sc->sc_iq_calib = r92c_iq_calib; /* XXX TODO */ sc->sc_iq_calib = r92c_iq_calib; /* XXX TODO */

View File

@ -0,0 +1,82 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef RTL8192E_H
#define RTL8192E_H
/*
* Global definitions.
*/
#define R92E_PUBQ_NPAGES 222
#define R92E_TX_PAGE_COUNT 243
#define R92E_TX_PAGE_SIZE 256
#define R92E_RX_DMA_BUFFER_SIZE 0x3d00
#define R92E_MAX_FW_SIZE 0x8000
/*
* Function declarations.
*/
/* r92e_attach.c */
void r92e_detach_private(struct rtwn_softc *);
/* r92e_chan.c */
void r92e_set_chan(struct rtwn_softc *, struct ieee80211_channel *);
/* r92e_fw.c */
#ifndef RTWN_WITHOUT_UCODE
void r92e_fw_reset(struct rtwn_softc *, int);
void r92e_set_media_status(struct rtwn_softc *, int);
int r92e_set_pwrmode(struct rtwn_softc *, struct ieee80211vap *, int);
#endif
/* r92e_init.c */
int r92e_llt_init(struct rtwn_softc *);
void r92e_init_bb(struct rtwn_softc *);
void r92e_init_rf(struct rtwn_softc *);
int r92e_power_on(struct rtwn_softc *);
void r92e_power_off(struct rtwn_softc *);
/* r92e_led.c */
void r92e_set_led(struct rtwn_softc *, int, int);
/* r92e_rf.c */
uint32_t r92e_rf_read(struct rtwn_softc *, int, uint8_t);
void r92e_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t);
/* r92e_rom.c */
void r92e_parse_rom_common(struct rtwn_softc *, uint8_t *);
void r92e_parse_rom(struct rtwn_softc *, uint8_t *);
/* r92e_rx.c */
void r92e_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
int8_t r92e_get_rssi_cck(struct rtwn_softc *, void *);
#endif /* RTL8192E_H */

View File

@ -0,0 +1,294 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/if_rtwn_ridx.h>
#include <dev/rtwn/if_rtwn_rx.h>
#include <dev/rtwn/rtl8192e/r92e.h>
#include <dev/rtwn/rtl8192e/r92e_reg.h>
#include <dev/rtwn/rtl8192e/r92e_var.h>
static int
r92e_get_power_group(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
uint8_t chan;
int group;
chan = rtwn_chan2centieee(c);
if (IEEE80211_IS_CHAN_2GHZ(c)) {
if (chan <= 2) group = 0;
else if (chan <= 5) group = 1;
else if (chan <= 8) group = 2;
else if (chan <= 11) group = 3;
else if (chan <= 14) group = 4;
else {
KASSERT(0, ("wrong 2GHz channel %d!\n", chan));
return (-1);
}
} else {
KASSERT(0, ("wrong channel band (flags %08X)\n", c->ic_flags));
return (-1);
}
return (group);
}
static void
r92e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c,
uint8_t power[RTWN_RIDX_COUNT])
{
struct r92e_softc *rs = sc->sc_priv;
int i, ridx, group, max_mcs;
/* Determine channel group. */
group = r92e_get_power_group(sc, c);
if (group == -1) { /* shouldn't happen */
device_printf(sc->sc_dev, "%s: incorrect channel\n", __func__);
return;
}
max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
/* XXX regulatory */
/* XXX net80211 regulatory */
for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
power[ridx] = rs->cck_tx_pwr[chain][group];
for (ridx = RTWN_RIDX_OFDM6; ridx <= max_mcs; ridx++)
power[ridx] = rs->ht40_tx_pwr_2g[chain][group];
for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
power[ridx] += rs->ofdm_tx_pwr_diff_2g[chain][0];
for (i = 0; i < sc->ntxchains; i++) {
uint8_t min_mcs;
uint8_t pwr_diff;
if (IEEE80211_IS_CHAN_HT40(c))
pwr_diff = rs->bw40_tx_pwr_diff_2g[chain][i];
else
pwr_diff = rs->bw20_tx_pwr_diff_2g[chain][i];
min_mcs = RTWN_RIDX_MCS(i * 8);
for (ridx = min_mcs; ridx <= max_mcs; ridx++)
power[ridx] += pwr_diff;
}
/* Apply max limit. */
for (ridx = RTWN_RIDX_CCK1; ridx <= max_mcs; ridx++) {
if (power[ridx] > R92C_MAX_TX_PWR)
power[ridx] = R92C_MAX_TX_PWR;
}
#ifdef RTWN_DEBUG
if (sc->sc_debug & RTWN_DEBUG_TXPWR) {
/* Dump per-rate Tx power values. */
printf("Tx power for chain %d:\n", chain);
for (ridx = RTWN_RIDX_CCK1; ridx < RTWN_RIDX_COUNT; ridx++)
printf("Rate %d = %u\n", ridx, power[ridx]);
}
#endif
}
static void
r92e_write_txpower(struct rtwn_softc *sc, int chain,
uint8_t power[RTWN_RIDX_COUNT])
{
uint32_t reg;
/* Write per-CCK rate Tx power. */
if (chain == 0) {
reg = rtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32);
reg = RW(reg, R92C_TXAGC_A_CCK1, power[RTWN_RIDX_CCK1]);
rtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg);
reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
reg = RW(reg, R92C_TXAGC_A_CCK2, power[RTWN_RIDX_CCK2]);
reg = RW(reg, R92C_TXAGC_A_CCK55, power[RTWN_RIDX_CCK55]);
reg = RW(reg, R92C_TXAGC_A_CCK11, power[RTWN_RIDX_CCK11]);
rtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
} else {
reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32);
reg = RW(reg, R92C_TXAGC_B_CCK1, power[RTWN_RIDX_CCK1]);
reg = RW(reg, R92C_TXAGC_B_CCK2, power[RTWN_RIDX_CCK2]);
reg = RW(reg, R92C_TXAGC_B_CCK55, power[RTWN_RIDX_CCK55]);
rtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg);
reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
reg = RW(reg, R92C_TXAGC_B_CCK11, power[RTWN_RIDX_CCK11]);
rtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
}
/* Write per-OFDM rate Tx power. */
rtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain),
SM(R92C_TXAGC_RATE06, power[RTWN_RIDX_OFDM6]) |
SM(R92C_TXAGC_RATE09, power[RTWN_RIDX_OFDM9]) |
SM(R92C_TXAGC_RATE12, power[RTWN_RIDX_OFDM12]) |
SM(R92C_TXAGC_RATE18, power[RTWN_RIDX_OFDM18]));
rtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain),
SM(R92C_TXAGC_RATE24, power[RTWN_RIDX_OFDM24]) |
SM(R92C_TXAGC_RATE36, power[RTWN_RIDX_OFDM36]) |
SM(R92C_TXAGC_RATE48, power[RTWN_RIDX_OFDM48]) |
SM(R92C_TXAGC_RATE54, power[RTWN_RIDX_OFDM54]));
/* Write per-MCS Tx power. */
rtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain),
SM(R92C_TXAGC_MCS00, power[RTWN_RIDX_MCS(0)]) |
SM(R92C_TXAGC_MCS01, power[RTWN_RIDX_MCS(1)]) |
SM(R92C_TXAGC_MCS02, power[RTWN_RIDX_MCS(2)]) |
SM(R92C_TXAGC_MCS03, power[RTWN_RIDX_MCS(3)]));
rtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain),
SM(R92C_TXAGC_MCS04, power[RTWN_RIDX_MCS(4)]) |
SM(R92C_TXAGC_MCS05, power[RTWN_RIDX_MCS(5)]) |
SM(R92C_TXAGC_MCS06, power[RTWN_RIDX_MCS(6)]) |
SM(R92C_TXAGC_MCS07, power[RTWN_RIDX_MCS(7)]));
if (sc->ntxchains >= 2) {
rtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain),
SM(R92C_TXAGC_MCS08, power[RTWN_RIDX_MCS(8)]) |
SM(R92C_TXAGC_MCS09, power[RTWN_RIDX_MCS(9)]) |
SM(R92C_TXAGC_MCS10, power[RTWN_RIDX_MCS(10)]) |
SM(R92C_TXAGC_MCS11, power[RTWN_RIDX_MCS(11)]));
rtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain),
SM(R92C_TXAGC_MCS12, power[RTWN_RIDX_MCS(12)]) |
SM(R92C_TXAGC_MCS13, power[RTWN_RIDX_MCS(13)]) |
SM(R92C_TXAGC_MCS14, power[RTWN_RIDX_MCS(14)]) |
SM(R92C_TXAGC_MCS15, power[RTWN_RIDX_MCS(15)]));
}
}
static void
r92e_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
uint8_t power[RTWN_RIDX_COUNT];
int i;
for (i = 0; i < sc->ntxchains; i++) {
memset(power, 0, sizeof(power));
/* Compute per-rate Tx power values. */
r92e_get_txpower(sc, i, c, power);
/* Write per-rate Tx power values to hardware. */
r92e_write_txpower(sc, i, power);
}
}
static void
r92e_set_bw40(struct rtwn_softc *sc, uint8_t chan, int prichlo)
{
int i;
rtwn_setbits_2(sc, R92C_WMAC_TRXPTCL_CTL, 0x100, 0x80);
rtwn_write_1(sc, R12A_DATA_SEC,
prichlo ? R12A_DATA_SEC_PRIM_DOWN_20 : R12A_DATA_SEC_PRIM_UP_20);
rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_40MHZ);
rtwn_bb_setbits(sc, R92C_FPGA1_RFMOD, 0, R92C_RFMOD_40MHZ);
/* Select 40MHz bandwidth. */
for (i = 0; i < sc->nrxchains; i++)
rtwn_rf_setbits(sc, i, R92C_RF_CHNLBW,
R88E_RF_CHNLBW_BW20, 0x400);
/* Set CCK side band. */
rtwn_bb_setbits(sc, R92C_CCK0_SYSTEM,
R92C_CCK0_SYSTEM_CCK_SIDEBAND, (prichlo ? 0 : 1) << 4);
rtwn_bb_setbits(sc, R92C_OFDM1_LSTF, 0x0c00, (prichlo ? 1 : 2) << 10);
rtwn_bb_setbits(sc, R92C_FPGA0_ANAPARAM2,
R92C_FPGA0_ANAPARAM2_CBW20, 0);
rtwn_bb_setbits(sc, 0x818, 0x0c000000, (prichlo ? 2 : 1) << 26);
}
static void
r92e_set_bw20(struct rtwn_softc *sc, uint8_t chan)
{
int i;
rtwn_setbits_2(sc, R92C_WMAC_TRXPTCL_CTL, 0x180, 0);
rtwn_write_1(sc, R12A_DATA_SEC, R12A_DATA_SEC_NO_EXT);
rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, R92C_RFMOD_40MHZ, 0);
rtwn_bb_setbits(sc, R92C_FPGA1_RFMOD, R92C_RFMOD_40MHZ, 0);
/* Select 20MHz bandwidth. */
for (i = 0; i < sc->nrxchains; i++)
rtwn_rf_setbits(sc, i, R92C_RF_CHNLBW,
R88E_RF_CHNLBW_BW20, 0xc00);
rtwn_bb_setbits(sc, R92C_OFDM0_TXPSEUDONOISEWGT, 0xc0000000, 0);
}
void
r92e_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
struct r92e_softc *rs = sc->sc_priv;
u_int chan;
int i;
chan = rtwn_chan2centieee(c);
for (i = 0; i < sc->nrxchains; i++) {
rtwn_rf_write(sc, i, R92C_RF_CHNLBW,
RW(rs->rf_chnlbw[0], R92C_RF_CHNLBW_CHNL, chan));
}
if (IEEE80211_IS_CHAN_HT40(c))
r92e_set_bw40(sc, chan, IEEE80211_IS_CHAN_HT40U(c));
else
r92e_set_bw20(sc, chan);
/* Set Tx power for this new channel. */
r92e_set_txpower(sc, c);
}

View File

@ -0,0 +1,137 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
#include <dev/rtwn/rtl8812a/r12a_fw_cmd.h>
#include <dev/rtwn/rtl8192e/r92e.h>
#ifndef RTWN_WITHOUT_UCODE
void
r92e_fw_reset(struct rtwn_softc *sc, int reason)
{
/* Reset MCU IO wrapper. */
rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0x01, 0);
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_CPUEN, 0, 1);
/* Enable MCU IO wrapper. */
rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0, 0x01);
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
0, R92C_SYS_FUNC_EN_CPUEN, 1);
}
void
r92e_set_media_status(struct rtwn_softc *sc, int macid)
{
struct r88e_fw_cmd_msrrpt status;
if (macid & RTWN_MACID_VALID)
status.msrb0 = R88E_MSRRPT_B0_ASSOC;
else
status.msrb0 = R88E_MSRRPT_B0_DISASSOC;
status.macid = (macid & ~RTWN_MACID_VALID);
if (r88e_fw_cmd(sc, R88E_CMD_MSR_RPT, &status, sizeof(status)) != 0) {
device_printf(sc->sc_dev, "%s: cannot change media status!\n",
__func__);
}
}
int
r92e_set_pwrmode(struct rtwn_softc *sc, struct ieee80211vap *vap, int off)
{
struct r12a_fw_cmd_pwrmode mode;
int error;
if (off && vap->iv_state == IEEE80211_S_RUN &&
(vap->iv_flags & IEEE80211_F_PMGTON)) {
mode.mode = R88E_PWRMODE_LEG;
/*
* TODO: switch to RFOFF state
* (something is missing here - Rx stops with it).
*/
#ifdef RTWN_TODO
mode.pwr_state = R88E_PWRMODE_STATE_RFOFF;
#else
mode.pwr_state = R88E_PWRMODE_STATE_RFON;
#endif
} else {
mode.mode = R88E_PWRMODE_CAM;
mode.pwr_state = R88E_PWRMODE_STATE_ALLON;
}
mode.pwrb1 =
SM(R88E_PWRMODE_B1_SMART_PS, R88E_PWRMODE_B1_LEG_NULLDATA) |
SM(R88E_PWRMODE_B1_RLBM, R88E_PWRMODE_B1_MODE_MIN);
/* XXX ignored */
mode.bcn_pass = 0;
mode.queue_uapsd = 0;
mode.pwrb5 = 0;
error = r88e_fw_cmd(sc, R88E_CMD_SET_PWRMODE, &mode, sizeof(mode));
if (error != 0) {
device_printf(sc->sc_dev,
"%s: CMD_SET_PWRMODE was not sent, error %d\n",
__func__, error);
}
return (error);
}
#endif

View File

@ -0,0 +1,385 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192e/r92e.h>
#include <dev/rtwn/rtl8192e/r92e_reg.h>
#include <dev/rtwn/rtl8192e/r92e_priv.h>
#include <dev/rtwn/rtl8192e/r92e_var.h>
int
r92e_llt_init(struct rtwn_softc *sc)
{
int ntries, error;
error = rtwn_setbits_4(sc, R92C_AUTO_LLT, 0, R92C_AUTO_LLT_INIT);
if (error != 0)
return (error);
for (ntries = 0; ntries < 1000; ntries++) {
if (!(rtwn_read_4(sc, R92C_AUTO_LLT) & R92C_AUTO_LLT_INIT))
return (0);
rtwn_delay(sc, 1);
}
return (ETIMEDOUT);
}
static void
r92e_crystalcap_write(struct rtwn_softc *sc)
{
struct r92e_softc *rs = sc->sc_priv;
uint32_t reg;
uint8_t val;
val = rs->crystalcap & 0x3f;
reg = rtwn_bb_read(sc, R92E_AFE_XTAL_CTRL);
rtwn_bb_write(sc, R92E_AFE_XTAL_CTRL,
RW(reg, R92E_AFE_XTAL_CTRL_ADDR, val | val << 6));
rtwn_bb_write(sc, R92C_AFE_XTAL_CTRL, 0x000f81fb);
}
void
r92e_init_bb(struct rtwn_softc *sc)
{
int i, j;
rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0,
R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD);
/* Enable BB and RF. */
rtwn_setbits_2(sc, R92C_SYS_FUNC_EN, 0,
R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
R92C_SYS_FUNC_EN_DIO_RF);
/* PathA RF Power On. */
rtwn_write_1(sc, R92C_RF_CTRL,
R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
/* Write BB initialization values. */
for (i = 0; i < sc->bb_size; i++) {
const struct rtwn_bb_prog *bb_prog = &sc->bb_prog[i];
while (!rtwn_check_condition(sc, bb_prog->cond)) {
KASSERT(bb_prog->next != NULL,
("%s: wrong condition value (i %d)\n",
__func__, i));
bb_prog = bb_prog->next;
}
for (j = 0; j < bb_prog->count; j++) {
RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
"BB: reg 0x%03x, val 0x%08x\n",
bb_prog->reg[j], bb_prog->val[j]);
rtwn_bb_write(sc, bb_prog->reg[j], bb_prog->val[j]);
rtwn_delay(sc, 1);
}
}
/* Write AGC values. */
for (i = 0; i < sc->agc_size; i++) {
const struct rtwn_agc_prog *agc_prog = &sc->agc_prog[i];
while (!rtwn_check_condition(sc, agc_prog->cond)) {
KASSERT(agc_prog->next != NULL,
("%s: wrong condition value (2) (i %d)\n",
__func__, i));
agc_prog = agc_prog->next;
}
for (j = 0; j < agc_prog->count; j++) {
RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
"AGC: val 0x%08x\n", agc_prog->val[j]);
rtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE,
agc_prog->val[j]);
rtwn_delay(sc, 1);
}
}
if (rtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) & R92C_HSSI_PARAM2_CCK_HIPWR)
sc->sc_flags |= RTWN_FLAG_CCK_HIPWR;
rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x00040022);
rtwn_delay(sc, 1);
rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x00040020);
rtwn_delay(sc, 1);
r92e_crystalcap_write(sc);
}
void
r92e_init_rf(struct rtwn_softc *sc)
{
struct r92e_softc *rs = sc->sc_priv;
uint32_t reg, type;
int i, chain, idx, off;
for (chain = 0, i = 0; chain < sc->nrxchains; chain++, i++) {
/* Save RF_ENV control type. */
idx = chain / 2;
off = (chain % 2) * 16;
reg = rtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
type = (reg >> off) & 0x10;
/* Set RF_ENV enable. */
rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACEOE(chain),
0, 0x100000);
rtwn_delay(sc, 1);
/* Set RF_ENV output high. */
rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACEOE(chain),
0, 0x10);
rtwn_delay(sc, 1);
/* Set address and data lengths of RF registers. */
rtwn_bb_setbits(sc, R92C_HSSI_PARAM2(chain),
R92C_HSSI_PARAM2_ADDR_LENGTH, 0);
rtwn_delay(sc, 1);
rtwn_bb_setbits(sc, R92C_HSSI_PARAM2(chain),
R92C_HSSI_PARAM2_DATA_LENGTH, 0);
rtwn_delay(sc, 1);
/* Write RF initialization values for this chain. */
i += r92c_init_rf_chain(sc, &sc->rf_prog[i], chain);
/* Cache RF register CHNLBW. */
rs->rf_chnlbw[chain] = rtwn_rf_read(sc, chain, R92C_RF_CHNLBW);
}
/* Turn CCK and OFDM blocks on. */
rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_CCK_EN);
rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_OFDM_EN);
}
static void
r92e_adj_crystal(struct rtwn_softc *sc)
{
rtwn_setbits_1(sc, R92C_AFE_PLL_CTRL, R92C_AFE_PLL_CTRL_FREF_SEL, 0);
rtwn_setbits_4(sc, R92E_APE_PLL_CTRL_EXT, 0x00000380, 0);
rtwn_setbits_1(sc, R92C_AFE_PLL_CTRL, 0x40, 0);
rtwn_setbits_4(sc, R92E_APE_PLL_CTRL_EXT, 0x00200000, 0);
}
int
r92e_power_on(struct rtwn_softc *sc)
{
#define RTWN_CHK(res) do { \
if (res != 0) \
return (EIO); \
} while(0)
int ntries;
if (rtwn_read_4(sc, R92C_SYS_CFG) & R92C_SYS_CFG_TRP_BT_EN)
RTWN_CHK(rtwn_write_1(sc, R92C_LDO_SWR_CTRL, 0xc3));
else {
RTWN_CHK(rtwn_setbits_4(sc, R92E_LDOV12_CTRL, 0x00100000,
0x00500000));
RTWN_CHK(rtwn_write_1(sc, R92C_LDO_SWR_CTRL, 0x83));
}
r92e_adj_crystal(sc);
/* Enable WL suspend. */
RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE, 0, 1));
/* Disable HWPDN, SW LPS and WL suspend. */
RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_APFM_RSM | R92C_APS_FSMCO_AFSM_HSUS |
R92C_APS_FSMCO_AFSM_PCIE | R92C_APS_FSMCO_APDM_HPDN, 0, 1));
/* Wait for power ready bit. */
for (ntries = 0; ntries < 5000; ntries++) {
if (rtwn_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST)
break;
rtwn_delay(sc, 10);
}
if (ntries == 5000) {
device_printf(sc->sc_dev,
"timeout waiting for chip power up\n");
return (ETIMEDOUT);
}
/* Release WLON reset. */
RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
R92C_APS_FSMCO_RDY_MACON, 2));
RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
R92C_APS_FSMCO_APFM_ONMAC, 1));
for (ntries = 0; ntries < 5000; ntries++) {
if (!(rtwn_read_2(sc, R92C_APS_FSMCO) &
R92C_APS_FSMCO_APFM_ONMAC))
break;
rtwn_delay(sc, 10);
}
if (ntries == 5000)
return (ETIMEDOUT);
/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
RTWN_CHK(rtwn_write_2(sc, R92C_CR, 0));
RTWN_CHK(rtwn_setbits_2(sc, R92C_CR, 0,
R92C_CR_HCI_TXDMA_EN | R92C_CR_TXDMA_EN |
R92C_CR_HCI_RXDMA_EN | R92C_CR_RXDMA_EN |
R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN |
((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0) |
R92C_CR_CALTMR_EN));
return (0);
}
void
r92e_power_off(struct rtwn_softc *sc)
{
int error, ntries;
/* Stop Rx. */
error = rtwn_write_1(sc, R92C_CR, 0);
if (error == ENXIO) /* hardware gone */
return;
/* Move card to Low Power state. */
/* Block all Tx queues. */
rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
for (ntries = 0; ntries < 5000; ntries++) {
/* Should be zero if no packet is transmitting. */
if (rtwn_read_4(sc, R88E_SCH_TXCMD) == 0)
break;
rtwn_delay(sc, 10);
}
if (ntries == 5000) {
device_printf(sc->sc_dev, "%s: failed to block Tx queues\n",
__func__);
return;
}
/* CCK and OFDM are disabled, and clock are gated. */
rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BBRSTB, 0);
rtwn_delay(sc, 1);
/* Reset whole BB. */
rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BB_GLB_RST, 0);
/* Reset MAC TRX. */
rtwn_write_1(sc, R92C_CR,
R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN);
/* Check if removed later. */
rtwn_setbits_1_shift(sc, R92C_CR, R92C_CR_ENSEC, 0, 1);
/* Respond TxOK to scheduler */
rtwn_setbits_1(sc, R92C_DUAL_TSF_RST, 0, R92C_DUAL_TSF_RST_TXOK);
/* Reset MCU. */
rtwn_write_1(sc, R92C_MCUFWDL, 0);
#ifndef RTWN_WITHOUT_UCODE
/* Reset MCU IO wrapper. */
rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0x01, 0);
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_CPUEN, 0, 1);
/* Enable MCU IO wrapper. */
rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0, 0x01);
#endif
/* Move card to Disabled state. */
/* Turn off RF. */
rtwn_write_1(sc, R92C_RF_CTRL, 0);
/* Switch DPDT_SEL_P output. */
rtwn_setbits_1(sc, R92C_LEDCFG2, 0x80, 0);
/* Turn off MAC by HW state machine */
rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0, R92C_APS_FSMCO_APFM_OFF,
1);
for (ntries = 0; ntries < 5000; ntries++) {
/* Wait until it will be disabled. */
if ((rtwn_read_2(sc, R92C_APS_FSMCO) &
R92C_APS_FSMCO_APFM_OFF) == 0)
break;
rtwn_delay(sc, 10);
}
if (ntries == 5000) {
device_printf(sc->sc_dev, "%s: could not turn off MAC\n",
__func__);
return;
}
/* SOP option to disable BG/MB. */
rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0xff,
R92C_APS_FSMCO_SOP_RCK, 3);
/* Unlock small LDO Register. */
rtwn_setbits_1(sc, 0xcc, 0, 0x4);
/* Disable small LDO. */
rtwn_setbits_1(sc, R92C_SPS0_CTRL, 0x1, 0);
/* Enable WL suspend. */
rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, R92C_APS_FSMCO_AFSM_PCIE,
R92C_APS_FSMCO_AFSM_HSUS, 1);
/* Enable SW LPS. */
rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0,
R92C_APS_FSMCO_APFM_RSM, 1);
}

View File

@ -0,0 +1,69 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/rtl8192e/r92e.h>
#include <dev/rtwn/rtl8192e/r92e_reg.h>
void
r92e_set_led(struct rtwn_softc *sc, int led, int on)
{
if (led == RTWN_LED_LINK) {
if (!on)
rtwn_setbits_1(sc, R92C_LEDCFG1, 0, R92C_LEDCFG1_DIS);
else
rtwn_setbits_1(sc, R92C_LEDCFG1, R92C_LEDCFG1_DIS, 0);
sc->ledlink = on; /* Save LED state. */
}
}

View File

@ -0,0 +1,262 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef R92E_PRIV_H
#define R92E_PRIV_H
/*
* MAC initialization values.
*/
static const struct rtwn_mac_prog rtl8192eu_mac[] = {
{ 0x011, 0xeb }, { 0x012, 0x07 }, { 0x014, 0x75 }, { 0x303, 0xa7 },
{ 0x428, 0x0a }, { 0x429, 0x10 }, { 0x430, 0x00 }, { 0x431, 0x00 },
{ 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, { 0x435, 0x05 },
{ 0x436, 0x07 }, { 0x437, 0x08 }, { 0x43c, 0x04 }, { 0x43d, 0x05 },
{ 0x43e, 0x07 }, { 0x43f, 0x08 }, { 0x440, 0x5d }, { 0x441, 0x01 },
{ 0x442, 0x00 }, { 0x444, 0x10 }, { 0x445, 0x00 }, { 0x446, 0x00 },
{ 0x447, 0x00 }, { 0x448, 0x00 }, { 0x449, 0xf0 }, { 0x44a, 0x0f },
{ 0x44b, 0x3e }, { 0x44c, 0x10 }, { 0x44d, 0x00 }, { 0x44e, 0x00 },
{ 0x44f, 0x00 }, { 0x450, 0x00 }, { 0x451, 0xf0 }, { 0x452, 0x0f },
{ 0x453, 0x00 }, { 0x456, 0x5e }, { 0x460, 0x66 }, { 0x461, 0x66 },
{ 0x4c8, 0xff }, { 0x4c9, 0x08 }, { 0x4cc, 0xff }, { 0x4cd, 0xff },
{ 0x4ce, 0x01 }, { 0x500, 0x26 }, { 0x501, 0xa2 }, { 0x502, 0x2f },
{ 0x503, 0x00 }, { 0x504, 0x28 }, { 0x505, 0xa3 }, { 0x506, 0x5e },
{ 0x507, 0x00 }, { 0x508, 0x2b }, { 0x509, 0xa4 }, { 0x50a, 0x5e },
{ 0x50b, 0x00 }, { 0x50c, 0x4f }, { 0x50d, 0xa4 }, { 0x50e, 0x00 },
{ 0x50f, 0x00 }, { 0x512, 0x1c }, { 0x514, 0x0a }, { 0x516, 0x0a },
{ 0x525, 0x4f }, { 0x540, 0x12 }, { 0x541, 0x64 }, { 0x550, 0x10 },
{ 0x551, 0x10 }, { 0x559, 0x02 }, { 0x55c, 0x50 }, { 0x55d, 0xff },
{ 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a }, { 0x620, 0xff },
{ 0x621, 0xff }, { 0x622, 0xff }, { 0x623, 0xff }, { 0x624, 0xff },
{ 0x625, 0xff }, { 0x626, 0xff }, { 0x627, 0xff }, { 0x638, 0x50 },
{ 0x63c, 0x0a }, { 0x63d, 0x0a }, { 0x63e, 0x0e }, { 0x63f, 0x0e },
{ 0x640, 0x40 }, { 0x642, 0x40 }, { 0x643, 0x00 }, { 0x652, 0xc8 },
{ 0x66e, 0x05 }, { 0x700, 0x21 }, { 0x701, 0x43 }, { 0x702, 0x65 },
{ 0x703, 0x87 }, { 0x708, 0x21 }, { 0x709, 0x43 }, { 0x70a, 0x65 },
{ 0x70b, 0x87 }
};
/*
* Baseband initialization values.
*/
static const uint16_t rtl8192eu_bb_regs[] = {
0x800, 0x804, 0x808, 0x80c, 0x810, 0x814, 0x818, 0x81c, 0x820,
0x824, 0x828, 0x82c, 0x830, 0x834, 0x838, 0x83c, 0x840, 0x844,
0x848, 0x84c, 0x850, 0x854, 0x858, 0x85c, 0x860, 0x864, 0x868,
0x86c, 0x870, 0x874, 0x878, 0x87c, 0x880, 0x884, 0x888, 0x88c,
0x890, 0x894, 0x898, 0x900, 0x904, 0x908, 0x90c, 0x910, 0x914,
0x918, 0x91c, 0x924, 0x928, 0x92c, 0x930, 0x934, 0x938, 0x93c,
0x940, 0x944, 0x94c, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14,
0xa18, 0xa1c, 0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 0xa78,
0xa7c, 0xa80, 0xb38, 0xc00, 0xc04, 0xc08, 0xc0c, 0xc10, 0xc14,
0xc18, 0xc1c, 0xc20, 0xc24, 0xc28, 0xc2c, 0xc30, 0xc34, 0xc38,
0xc3c, 0xc40, 0xc44, 0xc48, 0xc4c, 0xc50, 0xc54, 0xc58, 0xc5c,
0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74, 0xc78, 0xc7c, 0xc80,
0xc84, 0xc88, 0xc8c, 0xc90, 0xc94, 0xc98, 0xc9c, 0xca0, 0xca4,
0xca8, 0xcac, 0xcb0, 0xcb4, 0xcb8, 0xcbc, 0xcc0, 0xcc4, 0xcc8,
0xccc, 0xcd0, 0xcd4, 0xcd8, 0xcdc, 0xce0, 0xce4, 0xce8, 0xcec,
0xd00, 0xd04, 0xd08, 0xd0c, 0xd10, 0xd14, 0xd18, 0xd1c, 0xd2c,
0xd30, 0xd34, 0xd38, 0xd3c, 0xd40, 0xd44, 0xd48, 0xd4c, 0xd50,
0xd54, 0xd58, 0xd5c, 0xd60, 0xd64, 0xd68, 0xd6c, 0xd70, 0xd74,
0xd78, 0xd80, 0xd84, 0xd88, 0xe00, 0xe04, 0xe08, 0xe10, 0xe14,
0xe18, 0xe1c, 0xe28, 0xe30, 0xe34, 0xe38, 0xe3c, 0xe40, 0xe44,
0xe48, 0xe4c, 0xe50, 0xe54, 0xe58, 0xe5c, 0xe60, 0xe68, 0xe6c,
0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 0xed0,
0xed4, 0xed8, 0xedc, 0xee0, 0xeec, 0xee4, 0xee8, 0xf14, 0xf4c,
0xf00
};
static const uint32_t rtl8192eu_bb_vals[] = {
0x80040000, 0x00000003, 0x0000fc00, 0x0000000a, 0x10001331,
0x020c3d10, 0x02220385, 0x00000000, 0x01000100, 0x00390204,
0x01000100, 0x00390204, 0x32323232, 0x30303030, 0x30303030,
0x30303030, 0x00010000, 0x00010000, 0x28282828, 0x28282828,
0x00000000, 0x00000000, 0x009a009a, 0x01000014, 0x66f60000,
0x061f0000, 0x30303030, 0x30303030, 0x00000000, 0x55004200,
0x08080808, 0x00000000, 0xb0000c1c, 0x00000001, 0x00000000,
0xcc0000c0, 0x00000800, 0xfffffffe, 0x40302010, 0x00000000,
0x00000023, 0x00000000, 0x81121313, 0x806c0001, 0x00000001,
0x00000000, 0x00010000, 0x00000001, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000008, 0x00d0c7c8, 0x81ff000c, 0x8c838300,
0x2e68120f, 0x95009b78, 0x1114d028, 0x00881117, 0x89140f00,
0x1a1b0000, 0x090e1317, 0x00000204, 0x00d30000, 0x101fff00,
0x00000007, 0x00000900, 0x225b0606, 0x218075b1, 0x00000000,
0x48071d40, 0x03a05633, 0x000000e4, 0x6c6c6c6c, 0x08800000,
0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x69e9ac47, 0x469652af, 0x49795994,
0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
0x00340020, 0x0080801f, 0x00000020, 0x00248492, 0x00000000,
0x7112848b, 0x47c00bff, 0x00000036, 0x00000600, 0x02013169,
0x0000001f, 0x00b91612, 0x40000100, 0x21f60000, 0x40000100,
0xa0e40000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f,
0x00000000, 0x000300a0, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427,
0x00766932, 0x00222222, 0x00040000, 0x77644302, 0x2f97d40c,
0x00080740, 0x00020403, 0x0000907f, 0x20010201, 0xa0633333,
0x3333bc43, 0x7a8f5b6b, 0x0000007f, 0xcc979975, 0x00000000,
0x80608000, 0x00000000, 0x00127353, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x6437140a, 0x00000000, 0x00000282,
0x30032064, 0x4653de68, 0x04518a3c, 0x00002101, 0x2a201c16,
0x1812362e, 0x322c2220, 0x000e3c24, 0x01081008, 0x00000800,
0xf0b50000, 0x30303030, 0x30303030, 0x03903030, 0x30303030,
0x30303030, 0x30303030, 0x30303030, 0x00000000, 0x1000dc1f,
0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00, 0x01004800,
0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f, 0x02140102,
0x28160d05, 0x00000008, 0x0fc05656, 0x03c09696, 0x03c09696,
0x0c005656, 0x0c005656, 0x0c005656, 0x0c005656, 0x03c09696,
0x0c005656, 0x03c09696, 0x03c09696, 0x03c09696, 0x03c09696,
0x0000d6d6, 0x0000d6d6, 0x0fc01616, 0xb0000c1c, 0x00000001,
0x00000003, 0x00000000, 0x00000300
};
static const struct rtwn_bb_prog rtl8192eu_bb[] = {
{
nitems(rtl8192eu_bb_regs),
rtl8192eu_bb_regs,
rtl8192eu_bb_vals,
{ 0 },
NULL
}
};
static const uint32_t rtl8192eu_agc_vals[] = {
0xfb000001, 0xfb010001, 0xfb020001, 0xfb030001, 0xfb040001,
0xfb050001, 0xfa060001, 0xf9070001, 0xf8080001, 0xf7090001,
0xf60a0001, 0xf50b0001, 0xf40c0001, 0xf30d0001, 0xf20e0001,
0xf10f0001, 0xf0100001, 0xef110001, 0xee120001, 0xed130001,
0xec140001, 0xeb150001, 0xea160001, 0xe9170001, 0xe8180001,
0xe7190001, 0xc81a0001, 0xc71b0001, 0xc61c0001, 0x071d0001,
0x061e0001, 0x051f0001, 0x04200001, 0x03210001, 0xaa220001,
0xa9230001, 0xa8240001, 0xa7250001, 0xa6260001, 0x85270001,
0x84280001, 0x83290001, 0x252a0001, 0x242b0001, 0x232c0001,
0x222d0001, 0x672e0001, 0x662f0001, 0x65300001, 0x64310001,
0x63320001, 0x62330001, 0x61340001, 0x45350001, 0x44360001,
0x43370001, 0x42380001, 0x41390001, 0x403a0001, 0x403b0001,
0x403c0001, 0x403d0001, 0x403e0001, 0x403f0001, 0xfb400001,
0xfb410001, 0xfb420001, 0xfb430001, 0xfb440001, 0xfb450001,
0xfa460001, 0xf9470001, 0xf8480001, 0xf7490001, 0xf64a0001,
0xf54b0001, 0xf44c0001, 0xf34d0001, 0xf24e0001, 0xf14f0001,
0xf0500001, 0xef510001, 0xee520001, 0xed530001, 0xec540001,
0xeb550001, 0xea560001, 0xe9570001, 0xe8580001, 0xe7590001,
0xe65a0001, 0xe55b0001, 0xe45c0001, 0xe35d0001, 0xe25e0001,
0xe15f0001, 0x8a600001, 0x89610001, 0x88620001, 0x87630001,
0x86640001, 0x85650001, 0x84660001, 0x83670001, 0x82680001,
0x6b690001, 0x6a6a0001, 0x696b0001, 0x686c0001, 0x676d0001,
0x666e0001, 0x656f0001, 0x64700001, 0x63710001, 0x62720001,
0x61730001, 0x49740001, 0x48750001, 0x47760001, 0x46770001,
0x45780001, 0x44790001, 0x437a0001, 0x427b0001, 0x417c0001,
0x407d0001, 0x407e0001, 0x407f0001
};
static const struct rtwn_agc_prog rtl8192eu_agc[] = {
{
nitems(rtl8192eu_agc_vals),
rtl8192eu_agc_vals,
{ 0 },
NULL
}
};
/*
* RF initialization values.
*/
static const uint8_t rtl8192eu_rf0_regs[] = {
0x7f, 0x81, 0x00, 0x08, 0x18, 0x19, 0x1b, 0x1e, 0x1f, 0x2f, 0x3f,
0x42, 0x57, 0x58, 0x67, 0x83, 0xb0, 0xb1, 0xb2, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbf, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
0xc7, 0xc8, 0xc9, 0xca, 0xdf, 0xef, 0x51, 0x52, 0x53, 0x56, 0x35,
0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x18, 0x5a, 0x19, 0x34, 0x34,
0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x00, 0x84,
0x86, 0x87, 0x8e, 0x8f, 0xef, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xef,
0x18, 0x1e, 0x1f, 0x00
}, rtl8192eu_rf1_regs[] = {
0x7f, 0x81, 0x00, 0x08, 0x18, 0x19, 0x1b, 0x1e, 0x1f, 0x2f, 0x3f,
0x42, 0x57, 0x58, 0x67, 0x7f, 0x81, 0x83, 0xdf, 0xef, 0x51, 0x52,
0x53, 0x56, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x18, 0x5a,
0x19, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
0x34, 0x00, 0x84, 0x86, 0x87, 0x8e, 0x8f, 0xef, 0x3b, 0x3b, 0x3b,
0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
0x3b, 0x3b, 0xef, 0x00, 0x1e, 0x1f, 0x00
};
static const uint32_t rtl8192eu_rf0_vals[] = {
0x00082, 0x3fc00, 0x30000, 0x08400, 0x00407, 0x00012, 0x00064,
0x80009, 0x00880, 0x1a060, 0x00000, 0x060c0, 0xd0000, 0xbe180,
0x01552, 0x00000, 0xff9f1, 0x55418, 0x8cc00, 0x43083, 0x08166,
0x0803e, 0x1c69f, 0x0407f, 0x80001, 0x40001, 0x00400, 0xc0000,
0x02400, 0x00009, 0x40c91, 0x99999, 0x000a3, 0x88820, 0x76c06,
0x00000, 0x80000, 0x00180, 0x001a0, 0x69545, 0x7e45e, 0x00071,
0x51ff3, 0x000a8, 0x001e2, 0x002a8, 0x01c24, 0x09c24, 0x11c24,
0x19c24, 0x00c07, 0x48000, 0x739d0, 0x0add7, 0x09dd4, 0x08dd1,
0x07dce, 0x06dcb, 0x05dc8, 0x04dc5, 0x034cc, 0x0244f, 0x0144c,
0x00014, 0x30159, 0x68180, 0x0014e, 0x48e00, 0x65540, 0x88000,
0x020a0, 0xf02b0, 0xef7b0, 0xd4fb0, 0xcf060, 0xb0090, 0xa0080,
0x90080, 0x8f780, 0x78730, 0x60fb0, 0x5ffa0, 0x40620, 0x37090,
0x20080, 0x1f060, 0x0ffb0, 0x000a0, 0x0fc07, 0x00001, 0x80000,
0x33e70
}, rtl8192eu_rf1_vals[] = {
0x00082, 0x3fc00, 0x30000, 0x08400, 0x00407, 0x00012, 0x00064,
0x80009, 0x00880, 0x1a060, 0x00000, 0x060c0, 0xd0000, 0xbe180,
0x01552, 0x00082, 0x3f000, 0x00000, 0x00180, 0x001a0, 0x69545,
0x7e42e, 0x00071, 0x51ff3, 0x000a8, 0x001e0, 0x002a8, 0x01ca8,
0x09c24, 0x11c24, 0x19c24, 0x00c07, 0x48000, 0x739d0, 0x0add7,
0x09dd4, 0x08dd1, 0x07dce, 0x06dcb, 0x05dc8, 0x04dc5, 0x034cc,
0x0244f, 0x0144c, 0x00014, 0x30159, 0x68180, 0x000ce, 0x48a00,
0x65540, 0x88000, 0x020a0, 0xf02b0, 0xef7b0, 0xd4fb0, 0xcf060,
0xb0090, 0xa0080, 0x90080, 0x8f780, 0x78730, 0x60fb0, 0x5ffa0,
0x40620, 0x37090, 0x20080, 0x1f060, 0x0ffb0, 0x000a0, 0x10159,
0x00001, 0x80000, 0x33e70
};
static const struct rtwn_rf_prog rtl8192eu_rf[] = {
/* RF chain 0. */
{
nitems(rtl8192eu_rf0_regs),
rtl8192eu_rf0_regs,
rtl8192eu_rf0_vals,
{ 0 },
NULL
},
{ 0, NULL, NULL, { 0 }, NULL },
/* RF chain 1. */
{
nitems(rtl8192eu_rf1_regs),
rtl8192eu_rf1_regs,
rtl8192eu_rf1_vals,
{ 0 },
NULL
},
{ 0, NULL, NULL, { 0 }, NULL }
};
#endif /* R92E_PRIV_H */

View File

@ -0,0 +1,47 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef R92E_REG_H
#define R92E_REG_H
#include <dev/rtwn/rtl8188e/r88e_reg.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
/*
* MAC registers.
*/
/* System Configuration. */
#define R92E_LDOV12_CTRL 0x014
#define R92E_AFE_XTAL_CTRL 0x02c
#define R92E_APE_PLL_CTRL_EXT 0x078
/* Bits for R92E_AFE_XTAL_CTRL. */
#define R92E_AFE_XTAL_CTRL_ADDR_M 0x00fff000
#define R92E_AFE_XTAL_CTRL_ADDR_S 12
#endif /* R92E_REG_H */

View File

@ -0,0 +1,88 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/rtl8192e/r92e.h>
#include <dev/rtwn/rtl8192e/r92e_reg.h>
uint32_t
r92e_rf_read(struct rtwn_softc *sc, int chain, uint8_t addr)
{
uint32_t val;
val = rtwn_bb_read(sc, R92C_HSSI_PARAM2(chain));
rtwn_bb_write(sc, R92C_HSSI_PARAM2(chain),
RW(val, R92C_HSSI_PARAM2_READ_ADDR, addr) &
~R92C_HSSI_PARAM2_READ_EDGE);
rtwn_bb_setbits(sc, R92C_HSSI_PARAM2(0), R92C_HSSI_PARAM2_READ_EDGE, 0);
rtwn_bb_setbits(sc, R92C_HSSI_PARAM2(0), 0, R92C_HSSI_PARAM2_READ_EDGE);
rtwn_delay(sc, 20);
if (rtwn_bb_read(sc, R92C_HSSI_PARAM1(chain)) & R92C_HSSI_PARAM1_PI)
val = rtwn_bb_read(sc, R92C_HSPI_READBACK(chain));
else
val = rtwn_bb_read(sc, R92C_LSSI_READBACK(chain));
return (MS(val, R92C_LSSI_READBACK_DATA));
}
void
r92e_rf_write(struct rtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
{
rtwn_bb_setbits(sc, 0x818, 0x20000, 0);
rtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
SM(R88E_LSSI_PARAM_ADDR, addr) | SM(R92C_LSSI_PARAM_DATA, val));
rtwn_bb_setbits(sc, 0x818, 0, 0x20000);
}

View File

@ -0,0 +1,144 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/rtl8192e/r92e.h>
#include <dev/rtwn/rtl8192e/r92e_var.h>
#include <dev/rtwn/rtl8192e/r92e_rom_image.h>
void
r92e_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
{
struct r92e_softc *rs = sc->sc_priv;
struct r92e_rom *rom = (struct r92e_rom *)buf;
uint8_t pwr_diff;
int i, j, k;
sc->thermal_meter = rom->thermal_meter;
rs->crystalcap = RTWN_GET_ROM_VAR(rom->crystalcap,
R92E_ROM_CRYSTALCAP_DEF);
for (i = 0; i < sc->ntxchains; i++) {
struct r92e_tx_pwr_2g *pwr_2g = &rom->tx_pwr[i].pwr_2g;
struct r92e_tx_pwr_diff_2g *pwr_diff_2g =
&rom->tx_pwr[i].pwr_diff_2g;
for (j = 0; j < R92E_GROUP_2G - 1; j++) {
rs->cck_tx_pwr[i][j] =
RTWN_GET_ROM_VAR(pwr_2g->cck[j],
R92E_DEF_TX_PWR_2G);
rs->ht40_tx_pwr_2g[i][j] =
RTWN_GET_ROM_VAR(pwr_2g->ht40[j],
R92E_DEF_TX_PWR_2G);
}
rs->cck_tx_pwr[i][j] = RTWN_GET_ROM_VAR(pwr_2g->cck[j],
R92E_DEF_TX_PWR_2G);
rs->cck_tx_pwr_diff_2g[i][0] = 0;
rs->ofdm_tx_pwr_diff_2g[i][0] = RTWN_SIGN4TO8(
MS(pwr_diff_2g->ht20_ofdm, LOW_PART));
rs->bw20_tx_pwr_diff_2g[i][0] = RTWN_SIGN4TO8(
MS(pwr_diff_2g->ht20_ofdm, HIGH_PART));
rs->bw40_tx_pwr_diff_2g[i][0] = 0;
pwr_diff = RTWN_GET_ROM_VAR(pwr_diff_2g->ht20_ofdm,
R92E_DEF_TX_PWR_HT20_DIFF);
if (pwr_diff != R92E_DEF_TX_PWR_HT20_DIFF) {
rs->ofdm_tx_pwr_diff_2g[i][0] = RTWN_SIGN4TO8(
MS(pwr_diff_2g->ht20_ofdm, LOW_PART));
rs->bw20_tx_pwr_diff_2g[i][0] = RTWN_SIGN4TO8(
MS(pwr_diff_2g->ht20_ofdm, HIGH_PART));
} else {
rs->ofdm_tx_pwr_diff_2g[i][0] =
rs->bw20_tx_pwr_diff_2g[i][0] = pwr_diff;
}
for (j = 1, k = 0; k < nitems(pwr_diff_2g->diff123); j++, k++) {
pwr_diff = RTWN_GET_ROM_VAR(
pwr_diff_2g->diff123[k].ofdm_cck,
R92E_DEF_TX_PWR_DIFF);
if (pwr_diff != R92E_DEF_TX_PWR_DIFF) {
rs->cck_tx_pwr_diff_2g[i][j] = RTWN_SIGN4TO8(
MS(pwr_diff_2g->diff123[k].ofdm_cck,
LOW_PART));
rs->ofdm_tx_pwr_diff_2g[i][j] = RTWN_SIGN4TO8(
MS(pwr_diff_2g->diff123[k].ofdm_cck,
HIGH_PART));
} else {
rs->cck_tx_pwr_diff_2g[i][j] =
rs->ofdm_tx_pwr_diff_2g[i][j] = pwr_diff;
}
pwr_diff = RTWN_GET_ROM_VAR(
pwr_diff_2g->diff123[k].ht40_ht20,
R92E_DEF_TX_PWR_DIFF);
if (pwr_diff != R92E_DEF_TX_PWR_DIFF) {
rs->bw20_tx_pwr_diff_2g[i][j] = RTWN_SIGN4TO8(
MS(pwr_diff_2g->diff123[k].ht40_ht20,
LOW_PART));
rs->bw40_tx_pwr_diff_2g[i][j] = RTWN_SIGN4TO8(
MS(pwr_diff_2g->diff123[k].ht40_ht20,
HIGH_PART));
} else {
rs->bw20_tx_pwr_diff_2g[i][j] =
rs->bw40_tx_pwr_diff_2g[i][j] = pwr_diff;
}
}
}
rs->regulatory = MS(rom->rf_board_opt, R92C_ROM_RF1_REGULATORY);
/* Read MAC address. */
IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
}

View File

@ -0,0 +1,42 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef R92E_ROM_DEFS_H
#define R92E_ROM_DEFS_H
#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
#define R92E_GROUP_2G 6
#define R92E_MAX_TX_COUNT 4
#define R92E_MAX_RF_PATH 4
#define R92E_EFUSE_MAX_LEN 512
#define R92E_EFUSE_MAP_LEN 512
#endif /* R92E_ROM_DEFS_H */

View File

@ -0,0 +1,87 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
*
* 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.
*
* $FreeBSD$
*/
#ifndef R92E_ROM_IMAGE_H
#define R92E_ROM_IMAGE_H
#include <dev/rtwn/rtl8192e/r92e_rom_defs.h>
#define R92E_DEF_TX_PWR_2G 0x2d
#define R92E_DEF_TX_PWR_HT20_DIFF 0x02
#define R92E_DEF_TX_PWR_DIFF 0xfe
struct r92e_tx_pwr_2g {
uint8_t cck[R92E_GROUP_2G];
uint8_t ht40[R92E_GROUP_2G - 1];
} __packed;
struct r92e_tx_pwr_diff_2g {
uint8_t ht20_ofdm;
struct {
uint8_t ht40_ht20;
uint8_t ofdm_cck;
} __packed diff123[R92E_MAX_TX_COUNT - 1];
} __packed;
struct r92e_tx_pwr {
struct r92e_tx_pwr_2g pwr_2g;
struct r92e_tx_pwr_diff_2g pwr_diff_2g;
uint8_t reserved[24];
} __packed;
/*
* RTL8192EU ROM image.
*/
struct r92e_rom {
uint8_t reserved1[16];
struct r92e_tx_pwr tx_pwr[R92E_MAX_RF_PATH];
uint8_t channel_plan;
uint8_t crystalcap;
#define R92E_ROM_CRYSTALCAP_DEF 0x20
uint8_t thermal_meter;
uint8_t iqk_lck;
uint8_t pa_type;
uint8_t lna_type_2g;
uint8_t reserved2;
uint8_t lna_type_5g;
uint8_t reserved3;
uint8_t rf_board_opt;
uint8_t rf_feature_opt;
uint8_t rf_bt_opt;
uint8_t version;
uint8_t customer_id;
uint8_t tx_bbswing_2g;
uint8_t tx_bbswing_5g;
uint8_t tx_pwr_calib_rate;
uint8_t rf_ant_opt;
uint8_t rfe_option;
uint8_t reserved4[5];
uint16_t vid;
uint16_t pid;
uint8_t reserved5[3];
uint8_t macaddr[IEEE80211_ADDR_LEN];
uint8_t reserved6[2];
uint8_t string[7]; /* "Realtek" */
uint8_t reserved7[282];
} __packed;
_Static_assert(sizeof(struct r92e_rom) == R92E_EFUSE_MAP_LEN,
"R92E_EFUSE_MAP_LEN must be equal to sizeof(struct r92e_rom)!");
#endif /* R92E_ROM_IMAGE_H */

View File

@ -0,0 +1,97 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2014, 2017 Kevin Lo <kevlo@FreeBSD.org>
* Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org>
*
* 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$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_ratectl.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/if_rtwn_ridx.h>
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8192e/r92e.h>
#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
#include <dev/rtwn/rtl8812a/r12a_fw_cmd.h>
#ifndef RTWN_WITHOUT_UCODE
void
r92e_handle_c2h_report(struct rtwn_softc *sc, uint8_t *buf, int len)
{
/* Skip Rx descriptor. */
buf += sizeof(struct r92c_rx_stat);
len -= sizeof(struct r92c_rx_stat);
if (len < 2) {
device_printf(sc->sc_dev, "C2H report too short (len %d)\n",
len);
return;
}
len -= 2;
switch (buf[0]) { /* command id */
case R12A_C2H_TX_REPORT:
/* NOTREACHED */
KASSERT(0, ("use handle_tx_report() instead of %s\n",
__func__));
break;
}
}
#else
void
r92e_handle_c2h_report(struct rtwn_softc *sc, uint8_t *buf, int len)
{
/* Should not happen. */
device_printf(sc->sc_dev, "%s: called\n", __func__);
}
#endif
int8_t
r92e_get_rssi_cck(struct rtwn_softc *sc, void *physt)
{
return (10 + r88e_get_rssi_cck(sc, physt));
}

View File

@ -0,0 +1,54 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef R92E_VAR_H
#define R92E_VAR_H
#include <dev/rtwn/rtl8192e/r92e_rom_defs.h>
struct r92e_softc {
uint8_t chip;
uint8_t rs_flags;
uint8_t regulatory;
uint8_t crystalcap;
int8_t cck_tx_pwr[R92E_MAX_RF_PATH][R92E_GROUP_2G];
int8_t ht40_tx_pwr_2g[R92E_MAX_RF_PATH][R92E_GROUP_2G];
int8_t cck_tx_pwr_diff_2g[R92E_MAX_RF_PATH][R92E_MAX_TX_COUNT];
int8_t ofdm_tx_pwr_diff_2g[R92E_MAX_RF_PATH][R92E_MAX_TX_COUNT];
int8_t bw20_tx_pwr_diff_2g[R92E_MAX_RF_PATH][R92E_MAX_TX_COUNT];
int8_t bw40_tx_pwr_diff_2g[R92E_MAX_RF_PATH][R92E_MAX_TX_COUNT];
int ac_usb_dma_size;
int ac_usb_dma_time;
uint32_t rf_chnlbw[R92E_MAX_RF_PATH];
};
#endif /* R92E_VAR_H */

View File

@ -0,0 +1,43 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef RTL8192EU_H
#define RTL8192EU_H
#include <dev/rtwn/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8192e/r92e.h>
/*
* Function declarations.
*/
/* r92eu_init.c */
void r92eu_init_rx_agg(struct rtwn_softc *);
void r92eu_post_init(struct rtwn_softc *);
#endif /* RTL8192EU_H */

View File

@ -0,0 +1,202 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
*
* 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$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/if_rtwn_nop.h>
#include <dev/rtwn/usb/rtwn_usb_var.h>
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8192e/r92e_priv.h>
#include <dev/rtwn/rtl8192e/r92e_reg.h>
#include <dev/rtwn/rtl8192e/r92e_var.h>
#include <dev/rtwn/rtl8192e/usb/r92eu.h>
#include <dev/rtwn/rtl8812a/usb/r12au.h>
#include <dev/rtwn/rtl8812a/usb/r12au_tx_desc.h>
#include <dev/rtwn/rtl8821a/usb/r21au.h>
#include <dev/rtwn/rtl8821a/r21a_reg.h>
void r92eu_attach(struct rtwn_usb_softc *);
static void
r92eu_attach_private(struct rtwn_softc *sc)
{
struct r92e_softc *rs;
rs = malloc(sizeof(struct r92e_softc), M_RTWN_PRIV, M_WAITOK | M_ZERO);
rs->ac_usb_dma_size = 0x06;
rs->ac_usb_dma_time = 0x20;
sc->sc_priv = rs;
}
void
r92e_detach_private(struct rtwn_softc *sc)
{
struct r92e_softc *rs = sc->sc_priv;
free(rs, M_RTWN_PRIV);
}
static void
r92eu_adj_devcaps(struct rtwn_softc *sc)
{
/* XXX TODO? */
}
void
r92eu_attach(struct rtwn_usb_softc *uc)
{
struct rtwn_softc *sc = &uc->uc_sc;
/* USB part. */
uc->uc_align_rx = r12au_align_rx;
uc->tx_agg_desc_num = 3;
/* Common part. */
sc->sc_flags = RTWN_FLAG_EXT_HDR;
sc->sc_set_chan = r92e_set_chan;
sc->sc_fill_tx_desc = r12a_fill_tx_desc;
sc->sc_fill_tx_desc_raw = r12a_fill_tx_desc_raw;
sc->sc_fill_tx_desc_null = r12a_fill_tx_desc_null;
sc->sc_dump_tx_desc = r12au_dump_tx_desc;
sc->sc_tx_radiotap_flags = r12a_tx_radiotap_flags;
sc->sc_rx_radiotap_flags = r12a_rx_radiotap_flags;
sc->sc_get_rx_stats = r12a_get_rx_stats;
sc->sc_get_rssi_cck = r92e_get_rssi_cck;
sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm;
sc->sc_classify_intr = r12au_classify_intr;
sc->sc_handle_tx_report = r12a_ratectl_tx_complete;
sc->sc_handle_c2h_report = r92e_handle_c2h_report;
sc->sc_check_frame = rtwn_nop_int_softc_mbuf;
sc->sc_rf_read = r92e_rf_read;
sc->sc_rf_write = r92e_rf_write;
sc->sc_check_condition = r92c_check_condition;
sc->sc_efuse_postread = rtwn_nop_softc;
sc->sc_parse_rom = r92e_parse_rom;
sc->sc_set_led = r92e_set_led;
sc->sc_power_on = r92e_power_on;
sc->sc_power_off = r92e_power_off;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_fw_reset = r92e_fw_reset;
sc->sc_fw_download_enable = r12a_fw_download_enable;
#endif
sc->sc_llt_init = r92e_llt_init;
sc->sc_set_page_size = rtwn_nop_int_softc;
sc->sc_lc_calib = r92c_lc_calib;
sc->sc_iq_calib = r88e_iq_calib; /* XXX TODO */
sc->sc_read_chipid_vendor = rtwn_nop_softc_uint32;
sc->sc_adj_devcaps = r92eu_adj_devcaps;
sc->sc_vap_preattach = rtwn_nop_softc_vap;
sc->sc_postattach = rtwn_nop_softc;
sc->sc_detach_private = r92e_detach_private;
sc->sc_set_media_status = r92e_set_media_status;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_set_rsvd_page = r88e_set_rsvd_page;
sc->sc_set_pwrmode = r92e_set_pwrmode;
sc->sc_set_rssi = rtwn_nop_softc; /* XXX TODO? */
#endif
sc->sc_beacon_init = r12a_beacon_init;
sc->sc_beacon_enable = r92c_beacon_enable;
sc->sc_beacon_set_rate = rtwn_nop_void_int;
sc->sc_beacon_select = r21a_beacon_select;
sc->sc_temp_measure = r88e_temp_measure;
sc->sc_temp_read = r88e_temp_read;
sc->sc_init_tx_agg = r21au_init_tx_agg;
sc->sc_init_rx_agg = r92eu_init_rx_agg;
sc->sc_init_ampdu = rtwn_nop_softc;
sc->sc_init_intr = r12a_init_intr;
sc->sc_init_edca = r92c_init_edca;
sc->sc_init_bb = r92e_init_bb;
sc->sc_init_rf = r92e_init_rf;
sc->sc_init_antsel = rtwn_nop_softc;
sc->sc_post_init = r92eu_post_init;
sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc;
sc->mac_prog = &rtl8192eu_mac[0];
sc->mac_size = nitems(rtl8192eu_mac);
sc->bb_prog = &rtl8192eu_bb[0];
sc->bb_size = nitems(rtl8192eu_bb);
sc->agc_prog = &rtl8192eu_agc[0];
sc->agc_size = nitems(rtl8192eu_agc);
sc->rf_prog = &rtl8192eu_rf[0];
sc->name = "RTL8192EU";
sc->fwname = "rtwn-rtl8192eufw";
sc->fwsig = 0x92e;
sc->page_count = R92E_TX_PAGE_COUNT;
sc->pktbuf_count = 0; /* Unused */
sc->ackto = 0x40;
sc->npubqpages = R92E_PUBQ_NPAGES;
sc->page_size = R92E_TX_PAGE_SIZE;
sc->txdesc_len = sizeof(struct r12au_tx_desc);
sc->efuse_maxlen = R92E_EFUSE_MAX_LEN;
sc->efuse_maplen = R92E_EFUSE_MAP_LEN;
sc->rx_dma_size = R92E_RX_DMA_BUFFER_SIZE;
sc->macid_limit = R12A_MACID_MAX + 1;
sc->cam_entry_limit = R12A_CAM_ENTRY_COUNT;
sc->fwsize_limit = R92E_MAX_FW_SIZE;
sc->temp_delta = R88E_CALIB_THRESHOLD;
sc->bcn_status_reg[0] = R92C_TDECTRL;
sc->bcn_status_reg[1] = R21A_DWBCN1_CTRL;
sc->rcr = 0;
sc->ntxchains = 2;
sc->nrxchains = 2;
r92eu_attach_private(sc);
}

View File

@ -0,0 +1,96 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_wlan.h"
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/rtl8192e/r92e_var.h>
#include <dev/rtwn/rtl8192e/usb/r92eu.h>
#include <dev/rtwn/rtl8192e/usb/r92eu_reg.h>
void
r92eu_init_rx_agg(struct rtwn_softc *sc)
{
struct r92e_softc *rs = sc->sc_priv;
/* Rx aggregation (USB). */
rtwn_setbits_1(sc, R12A_RXDMA_PRO, 0x20, 0x1e);
rtwn_write_4(sc, R92C_RXDMA_AGG_PG_TH,
rs->ac_usb_dma_size | (rs->ac_usb_dma_time << 8));
rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0,
R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
}
void
r92eu_post_init(struct rtwn_softc *sc)
{
/* Setup RTS BW (equal to data BW). */
rtwn_setbits_1(sc, R92C_QUEUE_CTRL, 0x08, 0);
/* Reset USB mode switch setting. */
rtwn_write_1(sc, R92C_ACLK_MON, 0);
rtwn_write_1(sc, R92C_USB_HRPWM, 0);
#ifndef RTWN_WITHOUT_UCODE
if (sc->sc_flags & RTWN_FW_LOADED) {
if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
/* TODO: implement */
sc->sc_ratectl = RTWN_RATECTL_NET80211;
} else
sc->sc_ratectl = sc->sc_ratectl_sysctl;
} else
#endif
sc->sc_ratectl = RTWN_RATECTL_NONE;
}

View File

@ -0,0 +1,36 @@
/*-
* Copyright (c) 2017 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef R92EU_REG_H
#define R92EU_REG_H
#include <dev/rtwn/rtl8188e/usb/r88eu_reg.h>
#include <dev/rtwn/rtl8192e/r92e_reg.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#endif /* R92EU_REG_H */

View File

@ -77,6 +77,8 @@ r12a_beacon_init(struct rtwn_softc *sc, void *buf, int id)
txd->txdw3 = htole32(R12A_TXDW3_DRVRATE); txd->txdw3 = htole32(R12A_TXDW3_DRVRATE);
txd->txdw3 |= htole32(SM(R12A_TXDW3_SEQ_SEL, id)); txd->txdw3 |= htole32(SM(R12A_TXDW3_SEQ_SEL, id));
txd->txdw4 = htole32(SM(R12A_TXDW4_DATARATE, RTWN_RIDX_CCK1));
txd->txdw6 = htole32(SM(R21A_TXDW6_MBSSID, id)); txd->txdw6 = htole32(SM(R21A_TXDW6_MBSSID, id));
} }

View File

@ -68,14 +68,14 @@ void
r12a_fw_reset(struct rtwn_softc *sc, int reason) r12a_fw_reset(struct rtwn_softc *sc, int reason)
{ {
/* Reset MCU IO wrapper. */ /* Reset MCU IO wrapper. */
rtwn_setbits_1(sc, R92C_RSV_CTRL, 0x02, 0); rtwn_setbits_1(sc, R92C_RSV_CTRL, R92C_RSV_CTRL_WLOCK_00, 0);
rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0x08, 0); rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0x08, 0);
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN, rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_CPUEN, 0, 1); R92C_SYS_FUNC_EN_CPUEN, 0, 1);
/* Enable MCU IO wrapper. */ /* Enable MCU IO wrapper. */
rtwn_setbits_1(sc, R92C_RSV_CTRL, 0x02, 0); rtwn_setbits_1(sc, R92C_RSV_CTRL, R92C_RSV_CTRL_WLOCK_00, 0);
rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0, 0x08); rtwn_setbits_1(sc, R92C_RSV_CTRL + 1, 0, 0x08);
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN, rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,

View File

@ -215,6 +215,7 @@ r12au_attach(struct rtwn_usb_softc *uc)
sc->sc_fw_reset = r12a_fw_reset; sc->sc_fw_reset = r12a_fw_reset;
sc->sc_fw_download_enable = r12a_fw_download_enable; sc->sc_fw_download_enable = r12a_fw_download_enable;
#endif #endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r12a_set_page_size; sc->sc_set_page_size = r12a_set_page_size;
sc->sc_lc_calib = r12a_lc_calib; sc->sc_lc_calib = r12a_lc_calib;
sc->sc_iq_calib = r12a_iq_calib; sc->sc_iq_calib = r12a_iq_calib;

View File

@ -174,7 +174,7 @@ r21a_power_on(struct rtwn_softc *sc)
R92C_CR_CALTMR_EN)); R92C_CR_CALTMR_EN));
if (rtwn_read_4(sc, R92C_SYS_CFG) & R92C_SYS_CFG_TRP_BT_EN) if (rtwn_read_4(sc, R92C_SYS_CFG) & R92C_SYS_CFG_TRP_BT_EN)
RTWN_CHK(rtwn_setbits_1(sc, 0x07C, 0, 0x40)); RTWN_CHK(rtwn_setbits_1(sc, R92C_LDO_SWR_CTRL, 0, 0x40));
return (0); return (0);
#undef RTWN_CHK #undef RTWN_CHK

View File

@ -201,6 +201,7 @@ r21au_attach(struct rtwn_usb_softc *uc)
sc->sc_fw_reset = r21a_fw_reset; sc->sc_fw_reset = r21a_fw_reset;
sc->sc_fw_download_enable = r12a_fw_download_enable; sc->sc_fw_download_enable = r12a_fw_download_enable;
#endif #endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = rtwn_nop_int_softc; sc->sc_set_page_size = rtwn_nop_int_softc;
sc->sc_lc_calib = rtwn_nop_softc; /* XXX not used */ sc->sc_lc_calib = rtwn_nop_softc; /* XXX not used */
sc->sc_iq_calib = r12a_iq_calib; sc->sc_iq_calib = r12a_iq_calib;

View File

@ -21,12 +21,14 @@
*/ */
void r92cu_attach(struct rtwn_usb_softc *); void r92cu_attach(struct rtwn_usb_softc *);
void r92eu_attach(struct rtwn_usb_softc *);
void r88eu_attach(struct rtwn_usb_softc *); void r88eu_attach(struct rtwn_usb_softc *);
void r12au_attach(struct rtwn_usb_softc *); void r12au_attach(struct rtwn_usb_softc *);
void r21au_attach(struct rtwn_usb_softc *); void r21au_attach(struct rtwn_usb_softc *);
enum { enum {
RTWN_CHIP_RTL8192CU, RTWN_CHIP_RTL8192CU,
RTWN_CHIP_RTL8192EU,
RTWN_CHIP_RTL8188EU, RTWN_CHIP_RTL8188EU,
RTWN_CHIP_RTL8812AU, RTWN_CHIP_RTL8812AU,
RTWN_CHIP_RTL8821AU, RTWN_CHIP_RTL8821AU,
@ -101,6 +103,15 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8192CU_DEV(ZYXEL, RTL8192CU), RTWN_RTL8192CU_DEV(ZYXEL, RTL8192CU),
#undef RTWN_RTL8192CU_DEV #undef RTWN_RTL8192CU_DEV
/* RTL8192EU */
#define RTWN_RTL8192EU_DEV(v,p) \
{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, RTWN_CHIP_RTL8192EU) }
RTWN_RTL8192EU_DEV(DLINK, DWA131E1),
RTWN_RTL8192EU_DEV(REALTEK, RTL8192EU),
RTWN_RTL8192EU_DEV(TPLINK, WN822NV4),
RTWN_RTL8192EU_DEV(TPLINK, WN823NV2),
#undef RTWN_RTL8192EU_DEV
/* RTL8188EU */ /* RTL8188EU */
#define RTWN_RTL8188EU_DEV(v,p) \ #define RTWN_RTL8188EU_DEV(v,p) \
{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, RTWN_CHIP_RTL8188EU) } { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, RTWN_CHIP_RTL8188EU) }
@ -148,6 +159,7 @@ typedef void (*chip_usb_attach)(struct rtwn_usb_softc *);
static const chip_usb_attach rtwn_chip_usb_attach[RTWN_CHIP_MAX_USB] = { static const chip_usb_attach rtwn_chip_usb_attach[RTWN_CHIP_MAX_USB] = {
[RTWN_CHIP_RTL8192CU] = r92cu_attach, [RTWN_CHIP_RTL8192CU] = r92cu_attach,
[RTWN_CHIP_RTL8192EU] = r92eu_attach,
[RTWN_CHIP_RTL8188EU] = r88eu_attach, [RTWN_CHIP_RTL8188EU] = r88eu_attach,
[RTWN_CHIP_RTL8812AU] = r12au_attach, [RTWN_CHIP_RTL8812AU] = r12au_attach,
[RTWN_CHIP_RTL8821AU] = r21au_attach [RTWN_CHIP_RTL8821AU] = r21au_attach

View File

@ -3815,6 +3815,7 @@ product REALTEK DUMMY 0x0000 Dummy product
product REALTEK USB20CRW 0x0158 USB20CRW Card Reader product REALTEK USB20CRW 0x0158 USB20CRW Card Reader
product REALTEK RTL8188ETV 0x0179 RTL8188ETV product REALTEK RTL8188ETV 0x0179 RTL8188ETV
product REALTEK RTL8188CTV 0x018a RTL8188CTV product REALTEK RTL8188CTV 0x018a RTL8188CTV
product REALTEK RTL8188RU_2 0x317f RTL8188RU
product REALTEK USBKR100 0x8150 USBKR100 USB Ethernet product REALTEK USBKR100 0x8150 USBKR100 USB Ethernet
product REALTEK RTL8152 0x8152 RTL8152 USB Ethernet product REALTEK RTL8152 0x8152 RTL8152 USB Ethernet
product REALTEK RTL8153 0x8153 RTL8153 USB Ethernet product REALTEK RTL8153 0x8153 RTL8153 USB Ethernet
@ -3831,6 +3832,7 @@ product REALTEK RTL8188CU_1 0x817a RTL8188CU
product REALTEK RTL8188CU_2 0x817b RTL8188CU product REALTEK RTL8188CU_2 0x817b RTL8188CU
product REALTEK RTL8187 0x8187 RTL8187 Wireless Adapter product REALTEK RTL8187 0x8187 RTL8187 Wireless Adapter
product REALTEK RTL8187B_0 0x8189 RTL8187B Wireless Adapter product REALTEK RTL8187B_0 0x8189 RTL8187B Wireless Adapter
product REALTEK RTL8192EU 0x818b RTL8192EU
product REALTEK RTL8188CU_3 0x8191 RTL8188CU product REALTEK RTL8188CU_3 0x8191 RTL8188CU
product REALTEK RTL8196EU 0x8196 RTL8196EU product REALTEK RTL8196EU 0x8196 RTL8196EU
product REALTEK RTL8187B_1 0x8197 RTL8187B Wireless Adapter product REALTEK RTL8187B_1 0x8197 RTL8187B Wireless Adapter
@ -3844,7 +3846,7 @@ product REALTEK RTL8188RU_1 0x817d RTL8188RU
product REALTEK RTL8188RU_3 0x817f RTL8188RU product REALTEK RTL8188RU_3 0x817f RTL8188RU
product REALTEK RTL8712 0x8712 RTL8712 product REALTEK RTL8712 0x8712 RTL8712
product REALTEK RTL8713 0x8712 RTL8713 product REALTEK RTL8713 0x8712 RTL8713
product REALTEK RTL8188RU_2 0x317f RTL8188RU product REALTEK RTL8723BU 0xb720 RTL8723BU
product REALTEK RTL8192SU 0xc512 RTL8192SU product REALTEK RTL8192SU 0xc512 RTL8192SU
/* RedOctane products */ /* RedOctane products */
@ -4484,6 +4486,7 @@ product TOSHIBA TRANSMEMORY 0x6545 USB ThumbDrive
/* TP-Link products */ /* TP-Link products */
product TPLINK T4U 0x0101 Archer T4U product TPLINK T4U 0x0101 Archer T4U
product TPLINK WN822NV4 0x0108 TL-WN822N v4
product TPLINK WN823NV2 0x0109 TL-WN823N v2 product TPLINK WN823NV2 0x0109 TL-WN823N v2
/* Trek Technology products */ /* Trek Technology products */

View File

@ -16,7 +16,7 @@ SRCS = if_rtwn.c if_rtwn_tx.c if_rtwn_rx.c if_rtwn_beacon.c \
.PATH: ${.CURDIR}/../../dev/rtwn/rtl8192c .PATH: ${.CURDIR}/../../dev/rtwn/rtl8192c
SRCS += r92c_attach.c r92c_beacon.c r92c_calib.c r92c_chan.c r92c_fw.c \ SRCS += r92c_attach.c r92c_beacon.c r92c_calib.c r92c_chan.c r92c_fw.c \
r92c_init.c r92c_rf.c r92c_rom.c r92c_rx.c r92c_tx.c \ r92c_init.c r92c_llt.c r92c_rf.c r92c_rom.c r92c_rx.c r92c_tx.c \
r92c.h r92c_priv.h r92c_reg.h r92c_var.h r92c_rom_defs.h \ r92c.h r92c_priv.h r92c_reg.h r92c_var.h r92c_rom_defs.h \
r92c_rom_image.h r92c_fw_cmd.h r92c_rx_desc.h r92c_tx_desc.h r92c_rom_image.h r92c_fw_cmd.h r92c_rx_desc.h r92c_tx_desc.h
@ -26,6 +26,11 @@ SRCS += r88e_beacon.c r88e_calib.c r88e_chan.c r88e_fw.c r88e_init.c \
r88e_priv.h r88e_reg.h r88e_rom_defs.h r88e_rom_image.h \ r88e_priv.h r88e_reg.h r88e_rom_defs.h r88e_rom_image.h \
r88e_fw_cmd.h r88e_rx_desc.h r88e_tx_desc.h r88e_fw_cmd.h r88e_rx_desc.h r88e_tx_desc.h
.PATH: ${.CURDIR}/../../dev/rtwn/rtl8192e
SRCS += r92e_chan.c r92e_fw.c r92e_init.c r92e_led.c r92e_rf.c \
r92e_rom.c r92e_rx.c r92e.h r92e_priv.h r92e_reg.h \
r92e_rom_image.h r92e_rom_defs.h
.PATH: ${.CURDIR}/../../dev/rtwn/rtl8812a .PATH: ${.CURDIR}/../../dev/rtwn/rtl8812a
SRCS += r12a_beacon.c r12a_calib.c r12a_caps.c r12a_chan.c r12a_fw.c \ SRCS += r12a_beacon.c r12a_calib.c r12a_caps.c r12a_chan.c r12a_fw.c \
r12a_init.c r12a_led.c r12a_rf.c r12a_rom.c r12a_rx.c r12a_tx.c \ r12a_init.c r12a_led.c r12a_rf.c r12a_rom.c r12a_rx.c r12a_tx.c \

View File

@ -20,6 +20,9 @@ SRCS += r88eu_attach.c r88eu_init.c r88eu_rx.c \
SRCS += r92cu_attach.c r92cu_init.c r92cu_led.c r92cu_rx.c r92cu_tx.c \ SRCS += r92cu_attach.c r92cu_init.c r92cu_led.c r92cu_rx.c r92cu_tx.c \
r92cu.h r92cu_priv.h r92cu_reg.h r92cu_tx_desc.h r92cu.h r92cu_priv.h r92cu_reg.h r92cu_tx_desc.h
.PATH: ${.CURDIR}/../../dev/rtwn/rtl8192e/usb
SRCS += r92eu_attach.c r92eu_init.c r92eu.h r92eu_reg.h
.PATH: ${.CURDIR}/../../dev/rtwn/rtl8812a/usb .PATH: ${.CURDIR}/../../dev/rtwn/rtl8812a/usb
SRCS += r12au_attach.c r12au_init.c r12au_rx.c r12au_tx.c \ SRCS += r12au_attach.c r12au_init.c r12au_rx.c r12au_tx.c \
r12au.h r12au_reg.h r12au_tx_desc.h r12au.h r12au_reg.h r12au_tx_desc.h

View File

@ -1,6 +1,6 @@
# $FreeBSD$ # $FreeBSD$
SUBDIR= rtwnrtl8188eu rtwnrtl8192cT rtwnrtl8192cU rtwnrtl8812au rtwnrtl8821au \ SUBDIR= rtwnrtl8188eu rtwnrtl8192cT rtwnrtl8192cU rtwnrtl8192eu rtwnrtl8812au \
rtwnrtl8192cE rtwnrtl8192cEB rtwnrtl8821au rtwnrtl8192cE rtwnrtl8192cEB
.include <bsd.subdir.mk> .include <bsd.subdir.mk>

View File

@ -0,0 +1,6 @@
# $FreeBSD$
KMOD= rtwn-rtl8192eufw
IMG= rtwn-rtl8192eufw
.include <bsd.kmod.mk>