Merge ^/head r312624 through r312719.

This commit is contained in:
dim 2017-01-24 19:59:25 +00:00
commit fe0878f57f
101 changed files with 4688 additions and 616 deletions

View File

@ -2753,7 +2753,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x0bda";
match "product" "(0x818a|0x8191)";
match "product" "(0x818a|0x818b|0x8191)";
action "kldload -n if_rtwn_usb";
};
@ -3793,7 +3793,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x1199";
match "product" "(0x68aa|0x68c0|0x9041)";
match "product" "(0x68aa|0x68c0|0x9041|0x9071)";
action "kldload -n u3g";
};
@ -3905,7 +3905,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x12d1";
match "product" "(0x1573|0x1803|0x1c05|0x1c0b)";
match "product" "(0x1573|0x15c1|0x1803|0x1c05|0x1c0b)";
action "kldload -n u3g";
};
@ -5025,7 +5025,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
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";
};
@ -5297,7 +5297,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x2357";
match "product" "0x0101";
match "product" "(0x0101|0x0108|0x0109)";
action "kldload -n if_rtwn_usb";
};
@ -5889,5 +5889,5 @@ nomatch 32 {
action "kldload -n umass";
};
# 2743 USB entries processed
# 2751 USB entries processed

View File

@ -34,7 +34,7 @@ ENTRY(cerror)
stp x0, lr, [sp]
bl _C_LABEL(__error)
ldp x1, lr, [sp]
str x1, [x0]
str w1, [x0]
movn x0, #0
movn x1, #0
add sp, sp, #16

View File

@ -349,6 +349,8 @@ To prevent this, the
.Fl u
(unlink) flag causes restore to remove old entries before attempting
to create new ones.
This flag is recommended when using extended attributes
to avoid improperly accumulating attributes on pre-existing files.
.It Fl v
Normally
.Nm

View File

@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd October 17, 2016
.Dd January 24, 2017
.Dt RTWN 4
.Os
.Sh NAME
@ -52,9 +52,9 @@ if_rtwn_usb_load="YES"
The
.Nm
driver provides support for wireless network devices based on
the Realtek RTL8192C, RTL8188E, RTL8812A and RTL8821A programming APIs.
These APIs are used by a wide variety of chips; most chips with USB
and some with PCI interface are supported.
the Realtek RTL8192C, RTL8188E, RTL8192E, RTL8812A and RTL8821A
programming APIs. These APIs are used by a wide variety of chips;
most chips with USB and some with PCI interface are supported.
.Pp
To enable use for PCI/PCIe systems, see the rtwn_pci(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-rtl8192cfwT.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-rtl8821aufw.ko
.El

View File

@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"/
.Dd January 6, 2017
.Dd January 24, 2017
.Dt RTWN_USB 4
.Os
.Sh NAME
@ -56,7 +56,7 @@ driver.
.Sh HARDWARE
The
.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:
.Pp
.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-125 rev D1" 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-172 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-WN725N v2" 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 v2" Ta USB 2.0
.It "TRENDnet TEW-805UB" Ta USB 3.0
.It "ZyXEL NWD6605" Ta USB 3.0
.El

View File

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

View File

@ -54,7 +54,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd January 17, 2017
.Dd January 20, 2017
.Dt TMPFS 5
.Os
.Sh NAME
@ -77,7 +77,7 @@ tmpfs_load="YES"
.Sh DESCRIPTION
The
.Nm
driver implements in-memory, or
driver implements an in-memory, or
.Tn tmpfs
file system.
The filesystem stores both file metadata and data in main memory.
@ -85,22 +85,22 @@ This allows very fast and low latency accesses to the data.
The data is volatile.
An umount or system reboot invalidates it.
These properties make the filesystem's mounts suitable for fast
scratch storage, e.g.
scratch storage, like
.Pa /tmp .
.Pp
If the system becomes low on memory and swap is configured (see
.Xr swapon 8 ),
file data may be written to the swap space, freeing memory
the system can transfer file data to swap space, freeing memory
for other needs.
The current implementation never swaps out metadata, including
the directory content.
Metadata, including the directory content, is never swapped out by the
current implementation.
Keep this in mind when planning the mount limits, especially when expecting
to place many small files on a tmpfs mount.
.Pp
When a file from a tmpfs mount is mmaped (see
.Xr mmap 2 )
into the process address space, the swap VM object which manages the file
pages is used to implement mapping and to avoid double-copying of
When
.Xr mmap 2
is used on a file from a tmpfs mount, the swap VM object managing the
file pages is used to implement mapping and avoid double-copying of
the file data.
This quirk causes process inspection tools, like
.Xr procstat 1 ,
@ -120,6 +120,10 @@ Defaults to the mount point's UID.
.It Cm mode
Specifies the mode (in octal notation) of the root inode of the file system.
Defaults to the mount point's mode.
.It Cm nonc
Do not use namecache to resolve names to files for the created mount.
This saves memory, but currently might impair scalability for highly
used mounts on large machines.
.It Cm inodes
Specifies the maximum number of nodes available to the file system.
If not specified, the file system chooses a reasonable maximum based on

View File

@ -718,7 +718,7 @@ exec_linux_imgact_try(struct image_params *imgp)
{
const char *head = (const char *)imgp->image_header;
char *rpath;
int error = -1, len;
int error = -1;
/*
* The interpreter for shell scripts run from a linux binary needs
@ -736,17 +736,12 @@ exec_linux_imgact_try(struct image_params *imgp)
linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
imgp->interpreter_name, UIO_SYSSPACE,
&rpath, 0, AT_FDCWD);
if (rpath != NULL) {
len = strlen(rpath) + 1;
if (len <= MAXSHELLCMDLEN)
memcpy(imgp->interpreter_name,
rpath, len);
free(rpath, M_TEMP);
}
if (rpath != NULL)
imgp->args->fname_buf =
imgp->interpreter_name = rpath;
}
}
return(error);
return (error);
}
#define LINUX_VSYSCALL_START (-10UL << 20)

View File

@ -69,11 +69,18 @@ imx_wdog_cpu_reset(vm_offset_t wdcr_physaddr)
* Trigger an immediate reset by clearing the SRS bit in the watchdog
* control register. The reset happens on the next cycle of the wdog
* 32KHz clock, so hang out in a spin loop until the reset takes effect.
*
* Imx6 erratum ERR004346 says the SRS bit has to be cleared twice
* within the same cycle of the 32khz clock to reliably trigger the
* reset. Writing it 3 times in a row ensures at least 2 of the writes
* happen in the same 32k clock cycle.
*/
if ((pcr = devmap_ptov(wdcr_physaddr, sizeof(*pcr))) == NULL) {
printf("cpu_reset() can't find its control register... locking up now.");
} else {
*pcr &= ~WDOG_CR_SRS;
*pcr &= ~WDOG_CR_SRS;
*pcr &= ~WDOG_CR_SRS;
}
for (;;)
continue;

View File

@ -1582,14 +1582,19 @@ cpsw_intr_rx(void *arg)
static struct mbuf *
cpsw_rx_dequeue(struct cpsw_softc *sc)
{
int nsegs, port, removed;
struct cpsw_cpdma_bd bd;
struct cpsw_slot *last, *slot;
struct cpswp_softc *psc;
struct mbuf *mb_head, *mb_tail;
int port, removed = 0;
struct mbuf *m, *m0, *mb_head, *mb_tail;
uint16_t m0_flags;
nsegs = 0;
m0 = NULL;
last = NULL;
mb_head = mb_tail = NULL;
mb_head = NULL;
mb_tail = NULL;
removed = 0;
/* Pull completed packets off hardware RX queue. */
while ((slot = STAILQ_FIRST(&sc->rx.active)) != NULL) {
@ -1612,10 +1617,12 @@ cpsw_rx_dequeue(struct cpsw_softc *sc)
bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
m = slot->mbuf;
slot->mbuf = NULL;
if (bd.flags & CPDMA_BD_TDOWNCMPLT) {
CPSW_DEBUGF(sc, ("RX teardown is complete"));
m_freem(slot->mbuf);
slot->mbuf = NULL;
m_freem(m);
sc->rx.running = 0;
sc->rx.teardown = 0;
break;
@ -1627,28 +1634,36 @@ cpsw_rx_dequeue(struct cpsw_softc *sc)
psc = device_get_softc(sc->port[port].dev);
/* Set up mbuf */
/* TODO: track SOP/EOP bits to assemble a full mbuf
out of received fragments. */
slot->mbuf->m_data += bd.bufoff;
slot->mbuf->m_len = bd.buflen;
m->m_data += bd.bufoff;
m->m_len = bd.buflen;
if (bd.flags & CPDMA_BD_SOP) {
slot->mbuf->m_pkthdr.len = bd.pktlen;
slot->mbuf->m_pkthdr.rcvif = psc->ifp;
slot->mbuf->m_flags |= M_PKTHDR;
m->m_pkthdr.len = bd.pktlen;
m->m_pkthdr.rcvif = psc->ifp;
m->m_flags |= M_PKTHDR;
m0_flags = bd.flags;
m0 = m;
}
nsegs++;
m->m_next = NULL;
m->m_nextpkt = NULL;
if (bd.flags & CPDMA_BD_EOP && m0 != NULL) {
if (m0_flags & CPDMA_BD_PASS_CRC)
m_adj(m0, -ETHER_CRC_LEN);
m0_flags = 0;
m0 = NULL;
if (nsegs > sc->rx.longest_chain)
sc->rx.longest_chain = nsegs;
nsegs = 0;
}
slot->mbuf->m_next = NULL;
slot->mbuf->m_nextpkt = NULL;
if (bd.flags & CPDMA_BD_PASS_CRC)
m_adj(slot->mbuf, -ETHER_CRC_LEN);
if ((psc->ifp->if_capenable & IFCAP_RXCSUM) != 0) {
/* check for valid CRC by looking into pkt_err[5:4] */
if ((bd.flags &
(CPDMA_BD_SOP | CPDMA_BD_PKT_ERR_MASK)) ==
CPDMA_BD_SOP) {
slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_VALID;
slot->mbuf->m_pkthdr.csum_data = 0xffff;
m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
m->m_pkthdr.csum_data = 0xffff;
}
}
@ -1661,15 +1676,21 @@ cpsw_rx_dequeue(struct cpsw_softc *sc)
}
/* Add mbuf to packet list to be returned. */
if (mb_tail) {
mb_tail->m_nextpkt = slot->mbuf;
if (mb_tail != NULL && (bd.flags & CPDMA_BD_SOP)) {
mb_tail->m_nextpkt = m;
} else if (mb_tail != NULL) {
mb_tail->m_next = m;
} else if (mb_tail == NULL && (bd.flags & CPDMA_BD_SOP) == 0) {
if (bootverbose)
printf(
"%s: %s: discanding fragment packet w/o header\n",
__func__, psc->ifp->if_xname);
m_freem(m);
continue;
} else {
mb_head = slot->mbuf;
mb_head = m;
}
mb_tail = slot->mbuf;
slot->mbuf = NULL;
if (sc->rx_batch > 0 && sc->rx_batch == removed)
break;
mb_tail = m;
}
if (removed != 0) {
@ -1960,7 +1981,8 @@ cpsw_tx_dequeue(struct cpsw_softc *sc)
sc->tx.teardown = 1;
}
if ((flags & CPDMA_BD_OWNER) != 0 && sc->tx.teardown == 0)
if ((flags & (CPDMA_BD_SOP | CPDMA_BD_OWNER)) ==
(CPDMA_BD_SOP | CPDMA_BD_OWNER) && sc->tx.teardown == 0)
break; /* Hardware is still using this packet. */
bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTWRITE);
@ -2686,9 +2708,6 @@ cpsw_add_sysctls(struct cpsw_softc *sc)
SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "debug",
CTLFLAG_RW, &sc->debug, 0, "Enable switch debug messages");
SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "rx_batch",
CTLFLAG_RW, &sc->rx_batch, 0, "Set the rx batch size");
SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "attachedSecs",
CTLTYPE_UINT | CTLFLAG_RD, sc, 0, cpsw_stat_attached, "IU",
"Time since driver attach");

View File

@ -89,7 +89,6 @@ struct cpsw_softc {
int active_slave;
int debug;
int dualemac;
int rx_batch;
phandle_t node;
struct bintime attach_uptime; /* system uptime when attach happened. */
struct cpsw_port port[2];

View File

@ -105,8 +105,6 @@ static void ipi_preempt(void *);
static void ipi_rendezvous(void *);
static void ipi_stop(void *);
static int ipi_handler(void *arg);
struct mtx ap_boot_mtx;
struct pcb stoppcbs[MAXCPU];

View File

@ -50,13 +50,7 @@
};
&i2c0 {
tda998x: hdmi-encoder {
compatible = "nxp,tda998x";
reg = <0x70>;
pinctrl-names = "default", "off";
pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
tda998x: tda19988 {
status = "okay";
};
};

File diff suppressed because it is too large Load Diff

View File

@ -120,7 +120,6 @@ struct ctl_wwpn_iid {
* port_name: A string describing the FETD. e.g. "LSI 1030T U320"
* or whatever you want to use to describe the driver.
*
*
* physical_port: This is the physical port number of this
* particular port within the driver/hardware. This
* number is hardware/driver specific.
@ -179,11 +178,6 @@ struct ctl_wwpn_iid {
* to request a dump of any debugging information or
* state to the console.
*
* max_targets: The maximum number of targets that we can create
* per-port.
*
* max_target_id: The highest target ID that we can use.
*
* targ_port: The CTL layer assigns a "port number" to every
* FETD. This port number should be passed back in
* in the header of every ctl_io that is queued to
@ -234,8 +228,6 @@ struct ctl_port {
void *targ_lun_arg; /* passed to CTL */
void (*fe_datamove)(union ctl_io *io); /* passed to CTL */
void (*fe_done)(union ctl_io *io); /* passed to CTL */
int max_targets; /* passed to CTL */
int max_target_id; /* passed to CTL */
int32_t targ_port; /* passed back to FETD */
void *ctl_pool_ref; /* passed back to FETD */
uint32_t max_initiators; /* passed back to FETD */

View File

@ -147,11 +147,6 @@ cfcs_init(void)
port->onoff_arg = softc;
port->fe_datamove = cfcs_datamove;
port->fe_done = cfcs_done;
/* XXX KDM what should we report here? */
/* XXX These should probably be fetched from CTL. */
port->max_targets = 1;
port->max_target_id = 15;
port->targ_port = -1;
retval = ctl_port_register(port);

View File

@ -104,8 +104,6 @@ cfi_init(void)
port->port_name = "ioctl";
port->fe_datamove = cfi_datamove;
port->fe_done = cfi_done;
port->max_targets = 1;
port->max_target_id = 0;
port->targ_port = -1;
port->max_initiators = 1;

View File

@ -2127,11 +2127,6 @@ cfiscsi_ioctl_port_create(struct ctl_req *req)
port->onoff_arg = ct;
port->fe_datamove = cfiscsi_datamove;
port->fe_done = cfiscsi_done;
/* XXX KDM what should we report here? */
/* XXX These should probably be fetched from CTL. */
port->max_targets = 1;
port->max_target_id = 15;
port->targ_port = -1;
port->options = opts;
@ -2643,7 +2638,7 @@ cfiscsi_datamove_out(union ctl_io *io)
* Complete write underflow. Not a single byte to read. Return.
*/
expected_len = ntohl(bhssc->bhssc_expected_data_transfer_length);
if (io->scsiio.kern_rel_offset > expected_len) {
if (io->scsiio.kern_rel_offset >= expected_len) {
io->scsiio.be_move_done(io);
return;
}

View File

@ -95,8 +95,6 @@ tpcl_init(void)
port->port_name = "tpc";
port->fe_datamove = tpcl_datamove;
port->fe_done = tpcl_done;
port->max_targets = 1;
port->max_target_id = 0;
port->targ_port = -1;
port->max_initiators = 1;

View File

@ -402,12 +402,6 @@ ctlfeasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
port->targ_lun_arg = softc;
port->fe_datamove = ctlfe_datamove;
port->fe_done = ctlfe_done;
/*
* XXX KDM the path inquiry doesn't give us the maximum
* number of targets supported.
*/
port->max_targets = cpi->max_target;
port->max_target_id = cpi->max_target;
port->targ_port = -1;
/*

View File

@ -16255,18 +16255,11 @@ dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
}
static int
#ifdef __FreeBSD__
dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp, struct proc *p)
#else
dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp)
#endif
{
dtrace_helpers_t *help;
dtrace_vstate_t *vstate;
dtrace_enabling_t *enab = NULL;
#ifndef __FreeBSD__
proc_t *p = curproc;
#endif
int i, gen, rv, nhelpers = 0, nprovs = 0, destroy = 1;
uintptr_t daddr = (uintptr_t)dof;
@ -16277,8 +16270,8 @@ dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp)
vstate = &help->dthps_vstate;
if ((rv = dtrace_dof_slurp(dof, vstate, NULL, &enab,
dhp != NULL ? dhp->dofhp_addr : 0, B_FALSE)) != 0) {
if ((rv = dtrace_dof_slurp(dof, vstate, NULL, &enab, dhp->dofhp_addr,
B_FALSE)) != 0) {
dtrace_dof_destroy(dof);
return (rv);
}
@ -16286,22 +16279,20 @@ dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp)
/*
* Look for helper providers and validate their descriptions.
*/
if (dhp != NULL) {
for (i = 0; i < dof->dofh_secnum; i++) {
dof_sec_t *sec = (dof_sec_t *)(uintptr_t)(daddr +
dof->dofh_secoff + i * dof->dofh_secsize);
for (i = 0; i < dof->dofh_secnum; i++) {
dof_sec_t *sec = (dof_sec_t *)(uintptr_t)(daddr +
dof->dofh_secoff + i * dof->dofh_secsize);
if (sec->dofs_type != DOF_SECT_PROVIDER)
continue;
if (sec->dofs_type != DOF_SECT_PROVIDER)
continue;
if (dtrace_helper_provider_validate(dof, sec) != 0) {
dtrace_enabling_destroy(enab);
dtrace_dof_destroy(dof);
return (-1);
}
nprovs++;
if (dtrace_helper_provider_validate(dof, sec) != 0) {
dtrace_enabling_destroy(enab);
dtrace_dof_destroy(dof);
return (-1);
}
nprovs++;
}
/*
@ -16342,7 +16333,7 @@ dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp)
gen = help->dthps_generation++;
dtrace_enabling_destroy(enab);
if (dhp != NULL && nprovs > 0) {
if (nprovs > 0) {
/*
* Now that this is in-kernel, we change the sense of the
* members: dofhp_dof denotes the in-kernel copy of the DOF

View File

@ -1410,7 +1410,6 @@ typedef struct {
#define DTRACEHIOC_REMOVE (DTRACEHIOC | 2) /* remove helper */
#define DTRACEHIOC_ADDDOF (DTRACEHIOC | 3) /* add helper DOF */
#else
#define DTRACEHIOC_ADD _IOWR('z', 1, dof_hdr_t)/* add helper */
#define DTRACEHIOC_REMOVE _IOW('z', 2, int) /* remove helper */
#define DTRACEHIOC_ADDDOF _IOWR('z', 3, dof_helper_t)/* add helper DOF */
#endif

View File

@ -44,10 +44,8 @@ dtrace_ioctl_helper(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
case DTRACEHIOC_ADDDOF:
dhp = (dof_helper_t *)addr;
addr = (caddr_t)(uintptr_t)dhp->dofhp_dof;
/* FALLTHROUGH */
case DTRACEHIOC_ADD:
p = curproc;
if (dhp == NULL || p->p_pid == dhp->dofhp_pid) {
if (p->p_pid == dhp->dofhp_pid) {
p = curproc;
dof = dtrace_dof_copyin((uintptr_t)addr, &rval);
} else {
p = pfind(dhp->dofhp_pid);
@ -72,10 +70,7 @@ dtrace_ioctl_helper(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
mutex_enter(&dtrace_lock);
if ((rval = dtrace_helper_slurp(dof, dhp, p)) != -1) {
if (dhp != NULL) {
dhp->dofhp_gen = rval;
copyout(dhp, addr, sizeof(*dhp));
}
dhp->dofhp_gen = rval;
rval = 0;
} else {
rval = EINVAL;

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_fw.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_rom.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_rx.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
dev/rtwn/rtl8812a/r12a_beacon.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}" \
no-obj no-implicit-rule \
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 \
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 \

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

@ -1028,12 +1028,16 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
* otherwise) to be transmitted.
*/
sc->sc_txq_data_minfree = 10;
/*
* Leave this as default to maintain legacy behaviour.
* Shortening the cabq/mcastq may end up causing some
* undesirable behaviour.
* Shorten this to 64 packets, or 1/4 ath_txbuf, whichever
* is smaller.
*
* Anything bigger can potentially see the cabq consume
* almost all buffers, starving everything else, only to
* see most fail to transmit in the given beacon interval.
*/
sc->sc_txq_mcastq_maxdepth = ath_txbuf;
sc->sc_txq_mcastq_maxdepth = MIN(64, ath_txbuf / 4);
/*
* How deep can the node software TX queue get whilst it's asleep.
@ -1041,11 +1045,10 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
sc->sc_txq_node_psq_maxdepth = 16;
/*
* Default the maximum queue depth for a given node
* to 1/4'th the TX buffers, or 64, whichever
* is larger.
* Default the maximum queue to to 1/4'th the TX buffers, or
* 64, whichever is smaller.
*/
sc->sc_txq_node_maxdepth = MAX(64, ath_txbuf / 4);
sc->sc_txq_node_maxdepth = MIN(64, ath_txbuf / 4);
/* Enable CABQ by default */
sc->sc_cabq_enable = 1;

View File

@ -3129,7 +3129,21 @@ ath_tx_swq(struct ath_softc *sc, struct ieee80211_node *ni,
ATH_TID_INSERT_TAIL(atid, bf, bf_list);
/* XXX sched? */
} else if (ath_tx_ampdu_running(sc, an, tid)) {
/* AMPDU running, attempt direct dispatch if possible */
/*
* AMPDU running, queue single-frame if the hardware queue
* isn't busy.
*
* If the hardware queue is busy, sending an aggregate frame
* then just hold off so we can queue more aggregate frames.
*
* Otherwise we may end up with single frames leaking through
* because we are dispatching them too quickly.
*
* TODO: maybe we should treat this as two policies - minimise
* latency, or maximise throughput. Then for BE/BK we can
* maximise throughput, and VO/VI (if AMPDU is enabled!)
* minimise latency.
*/
/*
* Always queue the frame to the tail of the list.
@ -3138,18 +3152,18 @@ ath_tx_swq(struct ath_softc *sc, struct ieee80211_node *ni,
/*
* If the hardware queue isn't busy, direct dispatch
* the head frame in the list. Don't schedule the
* TID - let it build some more frames first?
* the head frame in the list.
*
* When running A-MPDU, always just check the hardware
* queue depth against the aggregate frame limit.
* We don't want to burst a large number of single frames
* out to the hardware; we want to aggressively hold back.
* Note: if we're say, configured to do ADDBA but not A-MPDU
* then maybe we want to still queue two non-aggregate frames
* to the hardware. Again with the per-TID policy
* configuration..)
*
* Otherwise, schedule the TID.
*/
/* XXX TXQ locking */
if (txq->axq_depth + txq->fifo.axq_depth < sc->sc_hwq_limit_aggr) {
if (txq->axq_depth + txq->fifo.axq_depth == 0) {
bf = ATH_TID_FIRST(atid);
ATH_TID_REMOVE(atid, bf, bf_list);
@ -5615,19 +5629,40 @@ ath_txq_sched(struct ath_softc *sc, struct ath_txq *txq)
ATH_TX_LOCK_ASSERT(sc);
/*
* Don't schedule if the hardware queue is busy.
* This (hopefully) gives some more time to aggregate
* some packets in the aggregation queue.
* For non-EDMA chips, aggr frames that have been built are
* in axq_aggr_depth, whether they've been scheduled or not.
* There's no FIFO, so txq->axq_depth is what's been scheduled
* to the hardware.
*
* XXX It doesn't stop a parallel sender from sneaking
* in transmitting a frame!
* For EDMA chips, we do it in two stages. The existing code
* builds a list of frames to go to the hardware and the EDMA
* code turns it into a single entry to push into the FIFO.
* That way we don't take up one packet per FIFO slot.
* We do push one aggregate per FIFO slot though, just to keep
* things simple.
*
* The FIFO depth is what's in the hardware; the txq->axq_depth
* is what's been scheduled to the FIFO.
*
* fifo.axq_depth is the number of frames (or aggregates) pushed
* into the EDMA FIFO. For multi-frame lists, this is the number
* of frames pushed in.
* axq_fifo_depth is the number of FIFO slots currently busy.
*/
/* XXX TXQ locking */
if (txq->axq_aggr_depth + txq->fifo.axq_depth >= sc->sc_hwq_limit_aggr) {
/* For EDMA and non-EDMA, check built/scheduled against aggr limit */
if (txq->axq_aggr_depth >= sc->sc_hwq_limit_aggr) {
sc->sc_aggr_stats.aggr_sched_nopkt++;
return;
}
if (txq->axq_depth >= sc->sc_hwq_limit_nonaggr) {
/*
* For non-EDMA chips, axq_depth is the "what's scheduled to
* the hardware list". For EDMA it's "What's built for the hardware"
* and fifo.axq_depth is how many frames have been dispatched
* already to the hardware.
*/
if (txq->axq_depth + txq->fifo.axq_depth >= sc->sc_hwq_limit_nonaggr) {
sc->sc_aggr_stats.aggr_sched_nopkt++;
return;
}

View File

@ -178,6 +178,13 @@ ath_tx_edma_push_staging_list(struct ath_softc *sc, struct ath_txq *txq,
ATH_TXQ_LOCK_ASSERT(txq);
DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_TX_PROC,
"%s: called; TXQ=%d, fifo.depth=%d, axq_q empty=%d\n",
__func__,
txq->axq_qnum,
txq->axq_fifo_depth,
!! (TAILQ_EMPTY(&txq->axq_q)));
/*
* Don't bother doing any work if it's full.
*/
@ -802,6 +809,8 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
uint32_t txstatus[32];
#endif
DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: called\n", __func__);
for (idx = 0; ; idx++) {
bzero(&ts, sizeof(ts));
@ -812,8 +821,12 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
status = ath_hal_txprocdesc(ah, NULL, (void *) &ts);
ATH_TXSTATUS_UNLOCK(sc);
if (status == HAL_EINPROGRESS)
if (status == HAL_EINPROGRESS) {
DPRINTF(sc, ATH_DEBUG_TX_PROC,
"%s: (%d): EINPROGRESS\n",
__func__, idx);
break;
}
#ifdef ATH_DEBUG
if (sc->sc_debug & ATH_DEBUG_TX_PROC)
@ -1016,6 +1029,10 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
/* Attempt to schedule more hardware frames to the TX FIFO */
for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) {
ATH_TX_LOCK(sc);
ath_txq_sched(sc, &sc->sc_txq[i]);
ATH_TX_UNLOCK(sc);
ATH_TXQ_LOCK(&sc->sc_txq[i]);
ath_edma_tx_fifo_fill(sc, &sc->sc_txq[i]);
ATH_TXQ_UNLOCK(&sc->sc_txq[i]);
@ -1024,6 +1041,8 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
/* Kick software scheduler */
ath_tx_swq_kick(sc);
}
DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: end\n", __func__);
}
static void

View File

@ -408,10 +408,13 @@ em_isc_txd_credits_update(void *arg, uint16_t txqid, uint32_t cidx_init, bool cl
cidx = cidx_init;
buf = &txr->tx_buffers[cidx];
tx_desc = &txr->tx_base[cidx];
last = buf->eop;
last = buf->eop;
if (last == -1)
return (processed);
eop_desc = &txr->tx_base[last];
DPRINTF(iflib_get_dev(adapter->ctx), "credits_update: cidx_init=%d clear=%d last=%d\n",
DPRINTF(iflib_get_dev(adapter->ctx),
"credits_update: cidx_init=%d clear=%d last=%d\n",
cidx_init, clear, last);
/*
* What this does is get the index of the
@ -420,7 +423,7 @@ em_isc_txd_credits_update(void *arg, uint16_t txqid, uint32_t cidx_init, bool cl
* simple comparison on the inner while loop.
*/
if (++last == scctx->isc_ntxd[0])
last = 0;
last = 0;
done = last;
@ -436,7 +439,7 @@ em_isc_txd_credits_update(void *arg, uint16_t txqid, uint32_t cidx_init, bool cl
tx_desc++;
buf++;
processed++;
/* wrap the ring ? */
if (++cidx == scctx->isc_ntxd[0]) {
cidx = 0;

View File

@ -1738,7 +1738,7 @@ em_if_stop(if_ctx_t ctx)
e1000_reset_hw(&adapter->hw);
if (adapter->hw.mac.type >= e1000_82544)
E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0);
E1000_WRITE_REG(&adapter->hw, E1000_WUFC, 0);
e1000_led_off(&adapter->hw);
e1000_cleanup_led(&adapter->hw);
@ -2313,7 +2313,7 @@ em_reset(if_ctx_t ctx)
/* Issue a global reset */
e1000_reset_hw(hw);
E1000_WRITE_REG(hw, E1000_WUC, 0);
E1000_WRITE_REG(hw, E1000_WUFC, 0);
em_disable_aspm(adapter);
/* and a re-init */
if (e1000_init_hw(hw) < 0) {
@ -2514,9 +2514,12 @@ em_setup_interface(if_ctx_t ctx)
/* Enable only WOL MAGIC by default */
if (adapter->wol) {
if_setcapabilitiesbit(ifp, IFCAP_WOL, 0);
if_setcapenablebit(ifp, IFCAP_WOL_MAGIC, 0);
}
if_setcapenablebit(ifp, IFCAP_WOL_MAGIC,
IFCAP_WOL_MCAST| IFCAP_WOL_UCAST);
} else {
if_setcapenablebit(ifp, 0, IFCAP_WOL_MAGIC |
IFCAP_WOL_MCAST| IFCAP_WOL_UCAST);
}
/*
* Specify the media types supported by this adapter and register
@ -3314,6 +3317,15 @@ em_get_wakeup(if_ctx_t ctx)
case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_pch_spt:
case e1000_82575: /* listing all igb devices */
case e1000_82576:
case e1000_82580:
case e1000_i350:
case e1000_i354:
case e1000_i210:
case e1000_i211:
case e1000_vfadapt:
case e1000_vfadapt_i350:
apme_mask = E1000_WUC_APME;
adapter->has_amt = TRUE;
eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC);
@ -3393,7 +3405,7 @@ em_enable_wakeup(if_ctx_t ctx)
ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
wuc = E1000_READ_REG(&adapter->hw, E1000_WUC);
wuc |= E1000_WUC_PME_EN ;
wuc |= (E1000_WUC_PME_EN | E1000_WUC_APME);
E1000_WRITE_REG(&adapter->hw, E1000_WUC, wuc);
if ((adapter->hw.mac.type == e1000_ich8lan) ||
@ -3417,6 +3429,9 @@ em_enable_wakeup(if_ctx_t ctx)
if ((if_getcapenable(ifp) & IFCAP_WOL_MAGIC) == 0)
adapter->wol &= ~E1000_WUFC_MAG;
if ((if_getcapenable(ifp) & IFCAP_WOL_UCAST) == 0)
adapter->wol &= ~E1000_WUFC_EX;
if ((if_getcapenable(ifp) & IFCAP_WOL_MCAST) == 0)
adapter->wol &= ~E1000_WUFC_MC;
else {
@ -3425,10 +3440,7 @@ em_enable_wakeup(if_ctx_t ctx)
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
}
if ((adapter->hw.mac.type == e1000_pchlan) ||
(adapter->hw.mac.type == e1000_pch2lan) ||
(adapter->hw.mac.type == e1000_pch_lpt) ||
(adapter->hw.mac.type == e1000_pch_spt)) {
if ( adapter->hw.mac.type >= e1000_pchlan) {
if (em_enable_phy_wakeup(adapter))
return;
} else {
@ -3493,7 +3505,7 @@ em_enable_phy_wakeup(struct adapter *adapter)
/* enable PHY wakeup in MAC register */
E1000_WRITE_REG(hw, E1000_WUC,
E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN | E1000_WUC_APME);
E1000_WRITE_REG(hw, E1000_WUFC, adapter->wol);
/* configure and enable PHY wakeup in PHY registers */

View File

@ -500,6 +500,8 @@ hn_nvs_conf_ndis(struct hn_softc *sc, int mtu)
conf.nvs_type = HN_NVS_TYPE_NDIS_CONF;
conf.nvs_mtu = mtu;
conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN;
if (sc->hn_nvs_ver >= HN_NVS_VERSION_5)
conf.nvs_caps |= HN_NVS_NDIS_CONF_SRIOV;
/* NOTE: No response. */
error = hn_nvs_req_send(sc, &conf, sizeof(conf));
@ -719,3 +721,15 @@ hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
return hn_nvs_send_rndis_sglist(chan, HN_NVS_RNDIS_MTYPE_CTRL,
sndc, gpa, gpa_cnt);
}
void
hn_nvs_set_datapath(struct hn_softc *sc, uint32_t path)
{
struct hn_nvs_datapath dp;
memset(&dp, 0, sizeof(dp));
dp.nvs_type = HN_NVS_TYPE_SET_DATAPATH;
dp.nvs_active_path = path;
hn_nvs_req_send(sc, &dp, sizeof(dp));
}

View File

@ -100,6 +100,7 @@ void hn_nvs_sent_xact(struct hn_nvs_sendctx *sndc,
int hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa,
int gpa_cnt);
void hn_nvs_set_datapath(struct hn_softc *sc, uint32_t path);
extern struct hn_nvs_sendctx hn_nvs_sendctx_none;

View File

@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/taskqueue.h>
#include <sys/buf_ring.h>
#include <sys/eventhandler.h>
#include <machine/atomic.h>
#include <machine/in_cksum.h>
@ -84,6 +85,7 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>
#include <net/if_var.h>
@ -216,6 +218,11 @@ struct hn_rxinfo {
uint32_t hash_value;
};
struct hn_update_vf {
struct hn_rx_ring *rxr;
struct ifnet *vf;
};
#define HN_RXINFO_VLAN 0x0001
#define HN_RXINFO_CSUM 0x0002
#define HN_RXINFO_HASHINF 0x0004
@ -294,8 +301,9 @@ static int hn_txagg_pkts_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_txagg_pktmax_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_txagg_align_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_polling_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_vf_sysctl(SYSCTL_HANDLER_ARGS);
static void hn_stop(struct hn_softc *);
static void hn_stop(struct hn_softc *, bool);
static void hn_init_locked(struct hn_softc *);
static int hn_chan_attach(struct hn_softc *,
struct vmbus_channel *);
@ -707,7 +715,8 @@ hn_rxfilter_config(struct hn_softc *sc)
HN_LOCK_ASSERT(sc);
if (ifp->if_flags & IFF_PROMISC) {
if ((ifp->if_flags & IFF_PROMISC) ||
(sc->hn_flags & HN_FLAG_VF)) {
filter = NDIS_PACKET_TYPE_PROMISCUOUS;
} else {
filter = NDIS_PACKET_TYPE_DIRECTED;
@ -896,6 +905,122 @@ hn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
}
static void
hn_update_vf_task(void *arg, int pending __unused)
{
struct hn_update_vf *uv = arg;
uv->rxr->hn_vf = uv->vf;
}
static void
hn_update_vf(struct hn_softc *sc, struct ifnet *vf)
{
struct hn_rx_ring *rxr;
struct hn_update_vf uv;
struct task task;
int i;
HN_LOCK_ASSERT(sc);
TASK_INIT(&task, 0, hn_update_vf_task, &uv);
for (i = 0; i < sc->hn_rx_ring_cnt; ++i) {
rxr = &sc->hn_rx_ring[i];
if (i < sc->hn_rx_ring_inuse) {
uv.rxr = rxr;
uv.vf = vf;
vmbus_chan_run_task(rxr->hn_chan, &task);
} else {
rxr->hn_vf = vf;
}
}
}
static void
hn_set_vf(struct hn_softc *sc, struct ifnet *ifp, bool vf)
{
struct ifnet *hn_ifp;
HN_LOCK(sc);
if (!(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED))
goto out;
hn_ifp = sc->hn_ifp;
if (ifp == hn_ifp)
goto out;
if (ifp->if_alloctype != IFT_ETHER)
goto out;
/* Ignore lagg/vlan interfaces */
if (strcmp(ifp->if_dname, "lagg") == 0 ||
strcmp(ifp->if_dname, "vlan") == 0)
goto out;
if (bcmp(IF_LLADDR(ifp), IF_LLADDR(hn_ifp), ETHER_ADDR_LEN) != 0)
goto out;
/* Now we're sure 'ifp' is a real VF device. */
if (vf) {
if (sc->hn_flags & HN_FLAG_VF)
goto out;
sc->hn_flags |= HN_FLAG_VF;
hn_rxfilter_config(sc);
} else {
if (!(sc->hn_flags & HN_FLAG_VF))
goto out;
sc->hn_flags &= ~HN_FLAG_VF;
if (sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING)
hn_rxfilter_config(sc);
else
hn_set_rxfilter(sc, NDIS_PACKET_TYPE_NONE);
}
hn_nvs_set_datapath(sc,
vf ? HN_NVS_DATAPATH_VF : HN_NVS_DATAPATH_SYNTHETIC);
hn_update_vf(sc, vf ? ifp : NULL);
if (vf) {
hn_suspend_mgmt(sc);
sc->hn_link_flags &=
~(HN_LINK_FLAG_LINKUP | HN_LINK_FLAG_NETCHG);
if_link_state_change(sc->hn_ifp, LINK_STATE_DOWN);
} else {
hn_resume_mgmt(sc);
}
devctl_notify("HYPERV_NIC_VF", if_name(hn_ifp),
vf ? "VF_UP" : "VF_DOWN", NULL);
if (bootverbose)
if_printf(hn_ifp, "Data path is switched %s %s\n",
vf ? "to" : "from", if_name(ifp));
out:
HN_UNLOCK(sc);
}
static void
hn_ifnet_event(void *arg, struct ifnet *ifp, int event)
{
if (event != IFNET_EVENT_UP && event != IFNET_EVENT_DOWN)
return;
hn_set_vf(arg, ifp, event == IFNET_EVENT_UP);
}
static void
hn_ifaddr_event(void *arg, struct ifnet *ifp)
{
hn_set_vf(arg, ifp, ifp->if_flags & IFF_UP);
}
/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
static const struct hyperv_guid g_net_vsc_device_type = {
.hv_guid = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
@ -1133,6 +1258,9 @@ hn_attach(device_t dev)
CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
hn_polling_sysctl, "I",
"Polling frequency: [100,1000000], 0 disable polling");
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "vf",
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
hn_vf_sysctl, "A", "Virtual Function's name");
/*
* Setup the ifmedia, which has been initialized earlier.
@ -1221,6 +1349,12 @@ hn_attach(device_t dev)
sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0;
hn_update_link_status(sc);
sc->hn_ifnet_evthand = EVENTHANDLER_REGISTER(ifnet_event,
hn_ifnet_event, sc, EVENTHANDLER_PRI_ANY);
sc->hn_ifaddr_evthand = EVENTHANDLER_REGISTER(ifaddr_event,
hn_ifaddr_event, sc, EVENTHANDLER_PRI_ANY);
return (0);
failed:
if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED)
@ -1235,6 +1369,11 @@ hn_detach(device_t dev)
struct hn_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->hn_ifp;
if (sc->hn_ifaddr_evthand != NULL)
EVENTHANDLER_DEREGISTER(ifaddr_event, sc->hn_ifaddr_evthand);
if (sc->hn_ifnet_evthand != NULL)
EVENTHANDLER_DEREGISTER(ifnet_event, sc->hn_ifnet_evthand);
if (sc->hn_xact != NULL && vmbus_chan_is_revoked(sc->hn_prichan)) {
/*
* In case that the vmbus missed the orphan handler
@ -1247,7 +1386,7 @@ hn_detach(device_t dev)
HN_LOCK(sc);
if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
hn_stop(sc);
hn_stop(sc, true);
/*
* NOTE:
* hn_stop() only suspends data, so managment
@ -2124,20 +2263,15 @@ static int
hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
const struct hn_rxinfo *info)
{
struct ifnet *ifp = rxr->hn_ifp;
struct ifnet *ifp;
struct mbuf *m_new;
int size, do_lro = 0, do_csum = 1;
int hash_type;
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
return (0);
/* If the VF is active, inject the packet through the VF */
ifp = rxr->hn_vf ? rxr->hn_vf : rxr->hn_ifp;
/*
* Bail out if packet contains more data than configured MTU.
*/
if (dlen > (ifp->if_mtu + ETHER_HDR_LEN)) {
return (0);
} else if (dlen <= MHLEN) {
if (dlen <= MHLEN) {
m_new = m_gethdr(M_NOWAIT, MT_DATA);
if (m_new == NULL) {
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
@ -2447,7 +2581,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
hn_stop(sc);
hn_stop(sc, false);
}
sc->hn_if_flags = ifp->if_flags;
@ -2537,7 +2671,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
static void
hn_stop(struct hn_softc *sc)
hn_stop(struct hn_softc *sc, bool detaching)
{
struct ifnet *ifp = sc->hn_ifp;
int i;
@ -2558,6 +2692,13 @@ hn_stop(struct hn_softc *sc)
atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
for (i = 0; i < sc->hn_tx_ring_inuse; ++i)
sc->hn_tx_ring[i].hn_oactive = 0;
/*
* If the VF is active, make sure the filter is not 0, even if
* the synthetic NIC is down.
*/
if (!detaching && (sc->hn_flags & HN_FLAG_VF))
hn_rxfilter_config(sc);
}
static void
@ -3087,6 +3228,22 @@ hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS)
return sysctl_handle_string(oidp, hash_str, sizeof(hash_str), req);
}
static int
hn_vf_sysctl(SYSCTL_HANDLER_ARGS)
{
struct hn_softc *sc = arg1;
char vf_name[128];
struct ifnet *vf;
HN_LOCK(sc);
vf_name[0] = '\0';
vf = sc->hn_rx_ring[0].hn_vf;
if (vf != NULL)
snprintf(vf_name, sizeof(vf_name), "%s", if_name(vf));
HN_UNLOCK(sc);
return sysctl_handle_string(oidp, vf_name, sizeof(vf_name), req);
}
static int
hn_check_iplen(const struct mbuf *m, int hoff)
{
@ -4323,6 +4480,7 @@ hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan)
KASSERT((rxr->hn_rx_flags & HN_RX_FLAG_ATTACHED) == 0,
("RX ring %d already attached", idx));
rxr->hn_rx_flags |= HN_RX_FLAG_ATTACHED;
rxr->hn_chan = chan;
if (bootverbose) {
if_printf(sc->hn_ifp, "link RX ring %d to chan%u\n",
@ -4901,7 +5059,8 @@ hn_suspend(struct hn_softc *sc)
/* Disable polling. */
hn_polling(sc, 0);
if (sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING)
if ((sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) ||
(sc->hn_flags & HN_FLAG_VF))
hn_suspend_data(sc);
hn_suspend_mgmt(sc);
}
@ -4990,9 +5149,18 @@ static void
hn_resume(struct hn_softc *sc)
{
if (sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING)
if ((sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) ||
(sc->hn_flags & HN_FLAG_VF))
hn_resume_data(sc);
hn_resume_mgmt(sc);
/*
* When the VF is activated, the synthetic interface is changed
* to DOWN in hn_set_vf(). Here, if the VF is still active, we
* don't call hn_resume_mgmt() until the VF is deactivated in
* hn_set_vf().
*/
if (!(sc->hn_flags & HN_FLAG_VF))
hn_resume_mgmt(sc);
/*
* Re-enable polling if this interface is running and

View File

@ -133,6 +133,17 @@ struct hn_nvs_ndis_init {
} __packed;
CTASSERT(sizeof(struct hn_nvs_ndis_init) >= HN_NVS_REQSIZE_MIN);
#define HN_NVS_DATAPATH_SYNTHETIC 0
#define HN_NVS_DATAPATH_VF 1
/* No response */
struct hn_nvs_datapath {
uint32_t nvs_type; /* HN_NVS_TYPE_SET_DATAPATH */
uint32_t nvs_active_path;/* HN_NVS_DATAPATH_* */
uint32_t nvs_rsvd[6];
} __packed;
CTASSERT(sizeof(struct hn_nvs_datapath) >= HN_NVS_REQSIZE_MIN);
struct hn_nvs_rxbuf_conn {
uint32_t nvs_type; /* HN_NVS_TYPE_RXBUF_CONN */
uint32_t nvs_gpadl; /* RXBUF vmbus GPADL */

View File

@ -59,6 +59,7 @@ struct hn_tx_ring;
struct hn_rx_ring {
struct ifnet *hn_ifp;
struct ifnet *hn_vf; /* SR-IOV VF */
struct hn_tx_ring *hn_txr;
void *hn_pktbuf;
int hn_pktbuf_len;
@ -85,6 +86,8 @@ struct hn_rx_ring {
void *hn_br; /* TX/RX bufring */
struct hyperv_dma hn_br_dma;
struct vmbus_channel *hn_chan;
} __aligned(CACHE_LINE_SIZE);
#define HN_TRUST_HCSUM_IP 0x0001
@ -232,6 +235,9 @@ struct hn_softc {
int hn_rss_ind_size;
uint32_t hn_rss_hash; /* NDIS_HASH_ */
struct ndis_rssprm_toeplitz hn_rss;
eventhandler_tag hn_ifaddr_evthand;
eventhandler_tag hn_ifnet_evthand;
};
#define HN_FLAG_RXBUF_CONNECTED 0x0001
@ -242,6 +248,7 @@ struct hn_softc {
#define HN_FLAG_NO_SLEEPING 0x0020
#define HN_FLAG_RXBUF_REF 0x0040
#define HN_FLAG_CHIM_REF 0x0080
#define HN_FLAG_VF 0x0100
#define HN_FLAG_ERRORS (HN_FLAG_RXBUF_REF | HN_FLAG_CHIM_REF)

View File

@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
#if (__FreeBSD_version >= 1001511)
#include <sys/capsicum.h>
#elif (__FreeBSD_version > 900000)
#include <sys/capabilty.h>
#include <sys/capability.h>
#endif
#include <sys/conf.h>

View File

@ -121,9 +121,6 @@ static int rtwn_run(struct rtwn_softc *,
static void rtwn_watchdog(void *);
#endif
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_mac_init(struct rtwn_softc *);
static void rtwn_mrr_init(struct rtwn_softc *);
@ -1383,54 +1380,6 @@ rtwn_parent(struct ieee80211com *ic)
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
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_download_enable)(struct rtwn_softc *, int);
#endif
int (*sc_llt_init)(struct rtwn_softc *);
int (*sc_set_page_size)(struct rtwn_softc *);
void (*sc_lc_calib)(struct rtwn_softc *);
void (*sc_iq_calib)(struct rtwn_softc *);
@ -472,8 +473,8 @@ void rtwn_suspend(struct rtwn_softc *);
/* Aliases. */
#define rtwn_bb_write rtwn_write_4
#define rtwn_bb_read rtwn_read_4
#define rtwn_bb_setbits rtwn_setbits_4
#define rtwn_bb_read rtwn_read_4
#define rtwn_bb_setbits rtwn_setbits_4
/* Device-specific. */
#define rtwn_rf_read(_sc, _chain, _addr) \
@ -504,6 +505,8 @@ void rtwn_suspend(struct rtwn_softc *);
#define rtwn_fw_download_enable(_sc, _enable) \
(((_sc)->sc_fw_download_enable)((_sc), (_enable)))
#endif
#define rtwn_llt_init(_sc) \
(((_sc)->sc_llt_init)((_sc)))
#define rtwn_set_page_size(_sc) \
(((_sc)->sc_set_page_size)((_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_download_enable = r88e_fw_download_enable;
#endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r92c_set_page_size;
sc->sc_lc_calib = r92c_lc_calib;
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_download_enable = r92c_fw_download_enable;
#endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r92c_set_page_size;
sc->sc_lc_calib = r92c_lc_calib;
sc->sc_iq_calib = r92ce_iq_calib;

View File

@ -77,6 +77,7 @@ void r92c_handle_c2h_report(void *);
/* r92c_init.c */
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 *);
void r92c_init_bb_common(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_pa_bias_init(struct rtwn_softc *);
/* r92c_llt.c */
int r92c_llt_write(struct rtwn_softc *, uint32_t, uint32_t);
/* r92c_rf.c */
uint32_t r92c_rf_read(struct rtwn_softc *, int, uint8_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);
}
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
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_HSISR 0x05c
#define R92C_MULTI_FUNC_CTRL 0x068
#define R92C_LDO_SWR_CTRL 0x07c
#define R92C_MCUFWDL 0x080
#define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2)
#define R92C_EFUSE_ACCESS 0x0cf
@ -115,6 +116,7 @@
#define R92C_TXDMA_OFFSET_CHK 0x20c
#define R92C_TXDMA_STATUS 0x210
#define R92C_RQPN_NPQ 0x214
#define R92C_AUTO_LLT 0x224
/* Rx DMA Configuration. */
#define R92C_RXDMA_AGG_PG_TH 0x280
#define R92C_RXPKT_NUM 0x284
@ -297,6 +299,16 @@
#define R92C_SYS_CLKR_SYS_EN 0x00001000
#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. */
#define R92C_RF_CTRL_EN 0x01
#define R92C_RF_CTRL_RSTB 0x02
@ -339,6 +351,9 @@
/* Bits for R92C_LEDCFG0. */
#define R92C_LEDCFG0_DIS 0x08
/* Bits for R92C_LEDCFG1. */
#define R92C_LEDCFG1_DIS 0x80
/* Bits for R92C_MULTI_FUNC_CTRL. */
#define R92C_MULTI_BT_FUNC_EN 0x00040000
@ -477,6 +492,9 @@
/* Bits for R92C_TXDMA_OFFSET_CHK. */
#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. */
#define R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW 0x80
#define R92C_FWHW_TXQ_CTRL_REAL_BEACON 0x400000
@ -683,6 +701,7 @@
#define R92C_OFDM0_TXIQIMBALANCE(chain) (0xc80 + (chain) * 8)
#define R92C_OFDM0_TXAFE(chain) (0xc94 + (chain) * 8)
#define R92C_OFDM0_RXIQEXTANTA 0xca0
#define R92C_OFDM0_TXPSEUDONOISEWGT 0xce4
#define R92C_OFDM1_LSTF 0xd00
/* Bits for R92C_FPGA[01]_RFMOD. */
@ -802,6 +821,9 @@
#define R92C_LSSI_READBACK_DATA_M 0x000fffff
#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). */
#define R92C_OFDM0_AGCCORE1_GAIN_M 0x0000007f
#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_download_enable = r92c_fw_download_enable;
#endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r92c_set_page_size;
sc->sc_lc_calib = r92c_lc_calib;
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(SM(R12A_TXDW3_SEQ_SEL, id));
txd->txdw4 = htole32(SM(R12A_TXDW4_DATARATE, RTWN_RIDX_CCK1));
txd->txdw6 = htole32(SM(R21A_TXDW6_MBSSID, id));
}

View File

@ -68,14 +68,14 @@ void
r12a_fw_reset(struct rtwn_softc *sc, int reason)
{
/* 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_shift(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_CPUEN, 0, 1);
/* 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_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_download_enable = r12a_fw_download_enable;
#endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = r12a_set_page_size;
sc->sc_lc_calib = r12a_lc_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));
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);
#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_download_enable = r12a_fw_download_enable;
#endif
sc->sc_llt_init = r92c_llt_init;
sc->sc_set_page_size = rtwn_nop_int_softc;
sc->sc_lc_calib = rtwn_nop_softc; /* XXX not used */
sc->sc_iq_calib = r12a_iq_calib;

View File

@ -21,12 +21,14 @@
*/
void r92cu_attach(struct rtwn_usb_softc *);
void r92eu_attach(struct rtwn_usb_softc *);
void r88eu_attach(struct rtwn_usb_softc *);
void r12au_attach(struct rtwn_usb_softc *);
void r21au_attach(struct rtwn_usb_softc *);
enum {
RTWN_CHIP_RTL8192CU,
RTWN_CHIP_RTL8192EU,
RTWN_CHIP_RTL8188EU,
RTWN_CHIP_RTL8812AU,
RTWN_CHIP_RTL8821AU,
@ -92,7 +94,6 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8192CU_DEV(REALTEK, RTL8191CU),
RTWN_RTL8192CU_DEV(REALTEK, RTL8192CE),
RTWN_RTL8192CU_DEV(REALTEK, RTL8192CU),
RTWN_RTL8192CU_DEV(REALTEK, RTL8192CU_1),
RTWN_RTL8192CU_DEV(SITECOMEU, RTL8188CU_1),
RTWN_RTL8192CU_DEV(SITECOMEU, RTL8188CU_2),
RTWN_RTL8192CU_DEV(SITECOMEU, RTL8192CU),
@ -101,6 +102,15 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8192CU_DEV(ZYXEL, RTL8192CU),
#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 */
#define RTWN_RTL8188EU_DEV(v,p) \
{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, RTWN_CHIP_RTL8188EU) }
@ -148,6 +158,7 @@ typedef void (*chip_usb_attach)(struct rtwn_usb_softc *);
static const chip_usb_attach rtwn_chip_usb_attach[RTWN_CHIP_MAX_USB] = {
[RTWN_CHIP_RTL8192CU] = r92cu_attach,
[RTWN_CHIP_RTL8192EU] = r92eu_attach,
[RTWN_CHIP_RTL8188EU] = r88eu_attach,
[RTWN_CHIP_RTL8812AU] = r12au_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 RTL8188ETV 0x0179 RTL8188ETV
product REALTEK RTL8188CTV 0x018a RTL8188CTV
product REALTEK RTL8188RU_2 0x317f RTL8188RU
product REALTEK USBKR100 0x8150 USBKR100 USB Ethernet
product REALTEK RTL8152 0x8152 RTL8152 USB Ethernet
product REALTEK RTL8153 0x8153 RTL8153 USB Ethernet
@ -3824,27 +3825,27 @@ product REALTEK RTL8172 0x8172 RTL8172
product REALTEK RTL8173 0x8173 RTL8173
product REALTEK RTL8174 0x8174 RTL8174
product REALTEK RTL8188CU_0 0x8176 RTL8188CU
product REALTEK RTL8192CU_1 0x8178 RTL8192CU
product REALTEK RTL8191CU 0x8177 RTL8191CU
product REALTEK RTL8192CU 0x8178 RTL8192CU
product REALTEK RTL8188EU 0x8179 RTL8188EU
product REALTEK RTL8188CE_1 0x817e RTL8188CE
product REALTEK RTL8188CU_1 0x817a RTL8188CU
product REALTEK RTL8188CU_2 0x817b RTL8188CU
product REALTEK RTL8192CE 0x817c RTL8192CE
product REALTEK RTL8188RU_1 0x817d RTL8188RU
product REALTEK RTL8188CE_1 0x817e RTL8188CE
product REALTEK RTL8188RU_3 0x817f RTL8188RU
product REALTEK RTL8187 0x8187 RTL8187 Wireless Adapter
product REALTEK RTL8187B_0 0x8189 RTL8187B Wireless Adapter
product REALTEK RTL8188CUS 0x818a RTL8188CUS
product REALTEK RTL8192EU 0x818b RTL8192EU
product REALTEK RTL8188CU_3 0x8191 RTL8188CU
product REALTEK RTL8196EU 0x8196 RTL8196EU
product REALTEK RTL8187B_1 0x8197 RTL8187B Wireless Adapter
product REALTEK RTL8187B_2 0x8198 RTL8187B Wireless Adapter
product REALTEK RTL8188CUS 0x818a RTL8188CUS
product REALTEK RTL8188CU_COMBO 0x8754 RTL8188CU
product REALTEK RTL8191CU 0x8177 RTL8191CU
product REALTEK RTL8192CU 0x8178 RTL8192CU
product REALTEK RTL8192CE 0x817c RTL8192CE
product REALTEK RTL8188RU_1 0x817d RTL8188RU
product REALTEK RTL8188RU_3 0x817f RTL8188RU
product REALTEK RTL8712 0x8712 RTL8712
product REALTEK RTL8713 0x8712 RTL8713
product REALTEK RTL8188RU_2 0x317f RTL8188RU
product REALTEK RTL8713 0x8713 RTL8713
product REALTEK RTL8188CU_COMBO 0x8754 RTL8188CU
product REALTEK RTL8723BU 0xb720 RTL8723BU
product REALTEK RTL8192SU 0xc512 RTL8192SU
/* RedOctane products */
@ -4484,6 +4485,7 @@ product TOSHIBA TRANSMEMORY 0x6545 USB ThumbDrive
/* TP-Link products */
product TPLINK T4U 0x0101 Archer T4U
product TPLINK WN822NV4 0x0108 TL-WN822N v4
product TPLINK WN823NV2 0x0109 TL-WN823N v2
/* Trek Technology products */

View File

@ -206,7 +206,22 @@ critical_exit(void)
if (td->td_critnest == 1) {
td->td_critnest = 0;
/*
* Interrupt handlers execute critical_exit() on
* leave, and td_owepreempt may be left set by an
* interrupt handler only when td_critnest > 0. If we
* are decrementing td_critnest from 1 to 0, read
* td_owepreempt after decrementing, to not miss the
* preempt. Disallow compiler to reorder operations.
*/
__compiler_membar();
if (td->td_owepreempt && !kdb_active) {
/*
* Microoptimization: we committed to switch,
* disable preemption in interrupt handlers
* while spinning for the thread lock.
*/
td->td_critnest = 1;
thread_lock(td);
td->td_critnest--;

View File

@ -387,6 +387,11 @@ sys_clock_settime(struct thread *td, struct clock_settime_args *uap)
return (kern_clock_settime(td, uap->clock_id, &ats));
}
static int allow_insane_settime = 0;
SYSCTL_INT(_debug, OID_AUTO, allow_insane_settime, CTLFLAG_RWTUN,
&allow_insane_settime, 0,
"do not perform possibly restrictive checks on settime(2) args");
int
kern_clock_settime(struct thread *td, clockid_t clock_id, struct timespec *ats)
{
@ -400,6 +405,8 @@ kern_clock_settime(struct thread *td, clockid_t clock_id, struct timespec *ats)
if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000 ||
ats->tv_sec < 0)
return (EINVAL);
if (!allow_insane_settime && ats->tv_sec > 9999ULL * 366 * 24 * 60 * 60)
return (EINVAL);
/* XXX Don't convert nsec->usec and back */
TIMESPEC_TO_TIMEVAL(&atv, ats);
error = settime(td, &atv);

View File

@ -178,7 +178,7 @@ clock_ct_to_ts(struct clocktime *ct, struct timespec *ts)
void
clock_ts_to_ct(struct timespec *ts, struct clocktime *ct)
{
int i, year, days;
time_t i, year, days;
time_t rsec; /* remainder seconds */
time_t secs;
@ -214,6 +214,20 @@ clock_ts_to_ct(struct timespec *ts, struct clocktime *ct)
print_ct(ct);
printf("\n");
}
KASSERT(ct->year >= 0 && ct->year < 10000,
("year %d isn't a 4 digit year", ct->year));
KASSERT(ct->mon >= 1 && ct->mon <= 12,
("month %d not in 1-12", ct->mon));
KASSERT(ct->day >= 1 && ct->day <= 31,
("day %d not in 1-31", ct->day));
KASSERT(ct->hour >= 0 && ct->hour <= 23,
("hour %d not in 0-23", ct->hour));
KASSERT(ct->min >= 0 && ct->min <= 59,
("minute %d not in 0-59", ct->min));
/* Not sure if this interface needs to handle leapseconds or not. */
KASSERT(ct->sec >= 0 && ct->sec <= 60,
("seconds %d not in 0-60", ct->sec));
}
int

View File

@ -630,6 +630,29 @@ taskqgroup_find(struct taskqgroup *qgroup, void *uniq)
return (idx);
}
/*
* smp_started is unusable since it is not set for UP kernels or even for
* SMP kernels when there is 1 CPU. This is usually handled by adding a
* (mp_ncpus == 1) test, but that would be broken here since we need to
* to synchronize with the SI_SUB_SMP ordering. Even in the pure SMP case
* smp_started only gives a fuzzy ordering relative to SI_SUB_SMP.
*
* So maintain our own flag. It must be set after all CPUs are started
* and before SI_SUB_SMP:SI_ORDER_ANY so that the SYSINIT for delayed
* adjustment is properly delayed. SI_ORDER_FOURTH is clearly before
* SI_ORDER_ANY and unclearly after the CPUs are started. It would be
* simpler for adjustment to pass a flag indicating if it is delayed.
*/
static int tqg_smp_started;
static void
tqg_record_smp_started(void *arg)
{
tqg_smp_started = 1;
}
SYSINIT(tqg_record_smp_started, SI_SUB_SMP, SI_ORDER_FOURTH,
tqg_record_smp_started, NULL);
void
taskqgroup_attach(struct taskqgroup *qgroup, struct grouptask *gtask,
@ -647,7 +670,7 @@ taskqgroup_attach(struct taskqgroup *qgroup, struct grouptask *gtask,
qgroup->tqg_queue[qid].tgc_cnt++;
LIST_INSERT_HEAD(&qgroup->tqg_queue[qid].tgc_tasks, gtask, gt_list);
gtask->gt_taskqueue = qgroup->tqg_queue[qid].tgc_taskq;
if (irq != -1 && (smp_started || mp_ncpus == 1)) {
if (irq != -1 && tqg_smp_started ) {
gtask->gt_cpu = qgroup->tqg_queue[qid].tgc_cpu;
CPU_ZERO(&mask);
CPU_SET(qgroup->tqg_queue[qid].tgc_cpu, &mask);
@ -697,7 +720,7 @@ taskqgroup_attach_cpu(struct taskqgroup *qgroup, struct grouptask *gtask,
gtask->gt_irq = irq;
gtask->gt_cpu = cpu;
mtx_lock(&qgroup->tqg_lock);
if (smp_started || mp_ncpus == 1) {
if (tqg_smp_started) {
for (i = 0; i < qgroup->tqg_cnt; i++)
if (qgroup->tqg_queue[i].tgc_cpu == cpu) {
qid = i;
@ -731,7 +754,7 @@ taskqgroup_attach_cpu_deferred(struct taskqgroup *qgroup, struct grouptask *gtas
qid = -1;
irq = gtask->gt_irq;
cpu = gtask->gt_cpu;
MPASS(smp_started || mp_ncpus == 1);
MPASS(tqg_smp_started);
mtx_lock(&qgroup->tqg_lock);
for (i = 0; i < qgroup->tqg_cnt; i++)
if (qgroup->tqg_queue[i].tgc_cpu == cpu) {
@ -824,9 +847,10 @@ _taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride)
mtx_assert(&qgroup->tqg_lock, MA_OWNED);
if (cnt < 1 || cnt * stride > mp_ncpus || (!smp_started && (mp_ncpus != 1))) {
printf("taskqgroup_adjust failed cnt: %d stride: %d mp_ncpus: %d smp_started: %d\n",
cnt, stride, mp_ncpus, smp_started);
if (cnt < 1 || cnt * stride > mp_ncpus || !tqg_smp_started) {
printf("%s: failed cnt: %d stride: %d "
"mp_ncpus: %d smp_started: %d\n",
__func__, cnt, stride, mp_ncpus, smp_started);
return (EINVAL);
}
if (qgroup->tqg_adjusting) {

View File

@ -132,6 +132,7 @@ crossmp_vop_unlock(struct vop_unlock_args *ap)
}
static struct vop_vector crossmp_vnodeops = {
.vop_default = &default_vnodeops,
.vop_islocked = crossmp_vop_islocked,
.vop_lock1 = crossmp_vop_lock1,
.vop_unlock = crossmp_vop_unlock,

View File

@ -1538,27 +1538,21 @@ _vn_lock(struct vnode *vp, int flags, char *file, int line)
int error;
VNASSERT((flags & LK_TYPE_MASK) != 0, vp,
("vn_lock called with no locktype."));
#ifdef DEBUG_VFS_LOCKS
KASSERT(vp->v_holdcnt != 0,
("vn_lock %p: zero hold count", vp));
#endif
("vn_lock: no locktype"));
VNASSERT(vp->v_holdcnt != 0, vp, ("vn_lock: zero hold count"));
retry:
error = VOP_LOCK1(vp, flags, file, line);
flags &= ~LK_INTERLOCK; /* Interlock is always dropped. */
KASSERT((flags & LK_RETRY) == 0 || error == 0,
("LK_RETRY set with incompatible flags (0x%x) or "
" an error occurred (%d)", flags, error));
("vn_lock: error %d incompatible with flags %#x", error, flags));
if ((flags & LK_RETRY) == 0) {
if (error == 0 && vp->v_iflag & VI_DOOMED) {
if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0) {
VOP_UNLOCK(vp, 0);
error = ENOENT;
}
} else {
if (error != 0)
goto retry;
}
} else if (error != 0)
goto retry;
return (error);
}
@ -1566,9 +1560,7 @@ retry:
* File table vnode close routine.
*/
static int
vn_closefile(fp, td)
struct file *fp;
struct thread *td;
vn_closefile(struct file *fp, struct thread *td)
{
struct vnode *vp;
struct flock lf;
@ -1577,12 +1569,14 @@ vn_closefile(fp, td)
vp = fp->f_vnode;
fp->f_ops = &badfileops;
if (__predict_false(fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE)
if (__predict_false((fp->f_flag & FHASLOCK) != 0) &&
fp->f_type == DTYPE_VNODE)
vrefact(vp);
error = vn_close(vp, fp->f_flag, fp->f_cred, td);
if (__predict_false(fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
if (__predict_false((fp->f_flag & FHASLOCK) != 0) &&
fp->f_type == DTYPE_VNODE) {
lf.l_whence = SEEK_SET;
lf.l_start = 0;
lf.l_len = 0;

View File

@ -6,6 +6,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/libkern.h>
u_char const bcd2bin_data[] = {
@ -20,6 +21,7 @@ u_char const bcd2bin_data[] = {
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99
};
CTASSERT(nitems(bcd2bin_data) == LIBKERN_LEN_BCD2BIN);
u_char const bin2bcd_data[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
@ -33,6 +35,8 @@ u_char const bin2bcd_data[] = {
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99
};
CTASSERT(nitems(bin2bcd_data) == LIBKERN_LEN_BIN2BCD);
/* This is actually used with radix [2..36] */
char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
CTASSERT(nitems(hex2ascii_data) == LIBKERN_LEN_HEX2ASCII + 1);

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
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_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_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
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 \

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 \
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
SRCS += r12au_attach.c r12au_init.c r12au_rx.c r12au_tx.c \
r12au.h r12au_reg.h r12au_tx_desc.h

View File

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

View File

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

View File

@ -528,9 +528,6 @@ lacp_port_create(struct lagg_port *lgp)
struct ifmultiaddr *rifma = NULL;
int error;
boolean_t active = TRUE; /* XXX should be configurable */
boolean_t fast = FALSE; /* Configurable via ioctl */
link_init_sdl(ifp, (struct sockaddr *)&sdl, IFT_ETHER);
sdl.sdl_alen = ETHER_ADDR_LEN;
@ -559,9 +556,7 @@ lacp_port_create(struct lagg_port *lgp)
lacp_fill_actorinfo(lp, &lp->lp_actor);
lacp_fill_markerinfo(lp, &lp->lp_marker);
lp->lp_state =
(active ? LACP_STATE_ACTIVITY : 0) |
(fast ? LACP_STATE_TIMEOUT : 0);
lp->lp_state = LACP_STATE_ACTIVITY;
lp->lp_aggregator = NULL;
lacp_sm_rx_set_expired(lp);
LACP_UNLOCK(lsc);

View File

@ -59,6 +59,7 @@
#include <sys/domain.h>
#include <sys/jail.h>
#include <sys/priv.h>
#include <sys/eventhandler.h>
#include <machine/stdarg.h>
#include <vm/uma.h>
@ -2218,6 +2219,7 @@ void
if_down(struct ifnet *ifp)
{
EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_DOWN);
if_unroute(ifp, IFF_UP, AF_UNSPEC);
}
@ -2230,6 +2232,7 @@ if_up(struct ifnet *ifp)
{
if_route(ifp, IFF_UP, AF_UNSPEC);
EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_UP);
}
/*

View File

@ -1193,13 +1193,36 @@ iflib_dma_free_multi(iflib_dma_info_t *dmalist, int count)
iflib_dma_free(*dmaiter);
}
#ifdef EARLY_AP_STARTUP
static const int iflib_started = 1;
#else
/*
* We used to abuse the smp_started flag to decide if the queues have been
* fully initialized (by late taskqgroup_adjust() calls in a SYSINIT()).
* That gave bad races, since the SYSINIT() runs strictly after smp_started
* is set. Run a SYSINIT() strictly after that to just set a usable
* completion flag.
*/
static int iflib_started;
static void
iflib_record_started(void *arg)
{
iflib_started = 1;
}
SYSINIT(iflib_record_started, SI_SUB_SMP + 1, SI_ORDER_FIRST,
iflib_record_started, NULL);
#endif
static int
iflib_fast_intr(void *arg)
{
iflib_filter_info_t info = arg;
struct grouptask *gtask = info->ifi_task;
if (!smp_started && mp_ncpus > 1)
if (!iflib_started)
return (FILTER_HANDLED);
DBG_COUNTER_INC(fast_intrs);
@ -3728,7 +3751,16 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
device_printf(dev, "qset structure setup failed %d\n", err);
goto fail_queues;
}
/*
* Group taskqueues aren't properly set up until SMP is started,
* so we disable interrupts until we can handle them post
* SI_SUB_SMP.
*
* XXX: disabling interrupts doesn't actually work, at least for
* the non-MSI case. When they occur before SI_SUB_SMP completes,
* we do null handling and depend on this not causing too large an
* interrupt storm.
*/
IFDI_INTR_DISABLE(ctx);
if (msix > 1 && (err = IFDI_MSIX_INTR_ASSIGN(ctx, msix)) != 0) {
device_printf(dev, "IFDI_MSIX_INTR_ASSIGN failed %d\n", err);
@ -4556,13 +4588,6 @@ iflib_legacy_setup(if_ctx_t ctx, driver_filter_t filter, void *filter_arg, int *
void *q;
int err;
/*
* group taskqueues aren't properly set up until SMP is started
* so we disable interrupts until we can handle them post
* SI_SUB_SMP
*/
IFDI_INTR_DISABLE(ctx);
q = &ctx->ifc_rxqs[0];
info = &rxq[0].ifr_filter_info;
gtask = &rxq[0].ifr_task;

View File

@ -1317,6 +1317,7 @@ getflags_5ghz(const uint8_t bands[], uint32_t flags[], int ht40, int vht80)
if (isset(bands, IEEE80211_MODE_VHT_5GHZ)) {
flags[nmodes++] = IEEE80211_CHAN_A | IEEE80211_CHAN_HT20 |
IEEE80211_CHAN_VHT20;
}
/* 40MHz */
if (ht40) {
@ -1340,7 +1341,6 @@ getflags_5ghz(const uint8_t bands[], uint32_t flags[], int ht40, int vht80)
IEEE80211_CHAN_HT40U | IEEE80211_CHAN_VHT80;
flags[nmodes++] = IEEE80211_CHAN_A |
IEEE80211_CHAN_HT40D | IEEE80211_CHAN_VHT80;
}
}
/* XXX VHT80+80 */

View File

@ -296,8 +296,12 @@ db_trace_self(void)
{
db_addr_t addr;
addr = (db_addr_t)__builtin_frame_address(1);
db_backtrace(curthread, addr, -1);
addr = (db_addr_t)__builtin_frame_address(0);
if (addr == 0) {
db_printf("Null frame address\n");
return;
}
db_backtrace(curthread, *(db_addr_t *)addr, -1);
}
int

View File

@ -74,4 +74,7 @@ struct sigframe {
#endif /* !LOCORE */
/* Definitions for syscalls */
#define NARGREG 8 /* 8 args in regs */
#endif /* !_MACHINE_FRAME_H_ */

View File

@ -95,7 +95,7 @@ cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
register_t *ap;
int nap;
nap = 8;
nap = NARGREG;
p = td->td_proc;
ap = &td->td_frame->tf_a[0];
@ -116,7 +116,7 @@ cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
sa->narg = sa->callp->sy_narg;
memcpy(sa->args, ap, nap * sizeof(register_t));
if (sa->narg > nap)
panic("TODO: Could we have more then 8 args?");
panic("TODO: Could we have more then %d args?", NARGREG);
td->td_retval[0] = 0;
td->td_retval[1] = 0;

View File

@ -284,4 +284,11 @@ typedef void (*swapoff_fn)(void *, struct swdevt *);
EVENTHANDLER_DECLARE(swapon, swapon_fn);
EVENTHANDLER_DECLARE(swapoff, swapoff_fn);
/* ifup/ifdown events */
#define IFNET_EVENT_UP 0
#define IFNET_EVENT_DOWN 1
struct ifnet;
typedef void (*ifnet_event_fn)(void *, struct ifnet *ifp, int event);
EVENTHANDLER_DECLARE(ifnet_event, ifnet_event_fn);
#endif /* _SYS_EVENTHANDLER_H_ */

View File

@ -81,7 +81,7 @@ int taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride);
extern struct taskqgroup *qgroup_##name
#if (!defined(SMP) || defined(EARLY_AP_STARTUP))
#ifdef EARLY_AP_STARTUP
#define TASKQGROUP_DEFINE(name, cnt, stride) \
\
struct taskqgroup *qgroup_##name; \
@ -95,7 +95,8 @@ taskqgroup_define_##name(void *arg) \
\
SYSINIT(taskqgroup_##name, SI_SUB_INIT_IF, SI_ORDER_FIRST, \
taskqgroup_define_##name, NULL)
#else /* SMP && !EARLY_AP_STARTUP */
#else /* !EARLY_AP_STARTUP */
#define TASKQGROUP_DEFINE(name, cnt, stride) \
\
struct taskqgroup *qgroup_##name; \
@ -104,15 +105,6 @@ static void \
taskqgroup_define_##name(void *arg) \
{ \
qgroup_##name = taskqgroup_create(#name); \
/* Adjustment will be null unless smp_cpus == 1. */ \
/* \
* XXX this was intended to fix the smp_cpus == 1 case, but \
* doesn't actually work for that. It gives thes same strange \
* panic as adjustment at SI_SUB_INIT_IF:SI_ORDER_ANY for a \
* device that works with a pure UP kernel. \
*/ \
/* XXX this code is common now, so should not be ifdefed. */ \
taskqgroup_adjust(qgroup_##name, (cnt), (stride)); \
} \
\
SYSINIT(taskqgroup_##name, SI_SUB_INIT_IF, SI_ORDER_FIRST, \
@ -121,17 +113,13 @@ SYSINIT(taskqgroup_##name, SI_SUB_INIT_IF, SI_ORDER_FIRST, \
static void \
taskqgroup_adjust_##name(void *arg) \
{ \
/* \
* Adjustment when smp_cpus > 1 only works accidentally \
* (when there is no device interrupt before adjustment). \
*/ \
taskqgroup_adjust(qgroup_##name, (cnt), (stride)); \
} \
\
SYSINIT(taskqgroup_adj_##name, SI_SUB_SMP, SI_ORDER_ANY, \
taskqgroup_adjust_##name, NULL); \
#endif /* !SMP || EARLY_AP_STARTUP */
#endif /* EARLY_AP_STARTUP */
TASKQGROUP_DECLARE(net);

View File

@ -49,9 +49,36 @@ extern u_char const bcd2bin_data[];
extern u_char const bin2bcd_data[];
extern char const hex2ascii_data[];
#define bcd2bin(bcd) (bcd2bin_data[bcd])
#define bin2bcd(bin) (bin2bcd_data[bin])
#define hex2ascii(hex) (hex2ascii_data[hex])
#define LIBKERN_LEN_BCD2BIN 154
#define LIBKERN_LEN_BIN2BCD 100
#define LIBKERN_LEN_HEX2ASCII 36
static inline u_char
bcd2bin(int bcd)
{
KASSERT(bcd >= 0 && bcd < LIBKERN_LEN_BCD2BIN,
("invalid bcd %d", bcd));
return (bcd2bin_data[bcd]);
}
static inline u_char
bin2bcd(int bin)
{
KASSERT(bin >= 0 && bin < LIBKERN_LEN_BIN2BCD,
("invalid bin %d", bin));
return (bin2bcd_data[bin]);
}
static inline char
hex2ascii(int hex)
{
KASSERT(hex >= 0 && hex < LIBKERN_LEN_HEX2ASCII,
("invalid hex %d", hex));
return (hex2ascii_data[hex]);
}
static __inline int imax(int a, int b) { return (a > b ? a : b); }
static __inline int imin(int a, int b) { return (a < b ? a : b); }

View File

@ -31,7 +31,7 @@
.\" @(#)find.1 8.7 (Berkeley) 5/9/95
.\" $FreeBSD$
.\"
.Dd April 13, 2014
.Dd January 24, 2017
.Dt FIND 1
.Os
.Sh NAME
@ -572,6 +572,7 @@ processes all but the command line arguments.
True if the difference between the file last modification time and the time
.Nm
was started, rounded up to the next full minute, is
more than
.Ar n
.Pq + Ns Ar n ,
less than

View File

@ -514,74 +514,74 @@ kernel_list(int iscsi_fd, const struct target *targ __unused,
* Display-only modifier as this information
* is also present within the 'session' container
*/
xo_emit("{L:/%-25s}{V:sessionId/%u}\n",
xo_emit("{L:/%-26s}{V:sessionId/%u}\n",
"Session ID:", state->iss_id);
xo_open_container("initiator");
xo_emit("{L:/%-25s}{V:name/%s}\n",
xo_emit("{L:/%-26s}{V:name/%s}\n",
"Initiator name:", conf->isc_initiator);
xo_emit("{L:/%-25s}{V:portal/%s}\n",
xo_emit("{L:/%-26s}{V:portal/%s}\n",
"Initiator portal:", conf->isc_initiator_addr);
xo_emit("{L:/%-25s}{V:alias/%s}\n",
xo_emit("{L:/%-26s}{V:alias/%s}\n",
"Initiator alias:", conf->isc_initiator_alias);
xo_close_container("initiator");
xo_open_container("target");
xo_emit("{L:/%-25s}{V:name/%s}\n",
xo_emit("{L:/%-26s}{V:name/%s}\n",
"Target name:", conf->isc_target);
xo_emit("{L:/%-25s}{V:portal/%s}\n",
xo_emit("{L:/%-26s}{V:portal/%s}\n",
"Target portal:", conf->isc_target_addr);
xo_emit("{L:/%-25s}{V:alias/%s}\n",
xo_emit("{L:/%-26s}{V:alias/%s}\n",
"Target alias:", state->iss_target_alias);
xo_close_container("target");
xo_open_container("auth");
xo_emit("{L:/%-25s}{V:user/%s}\n",
xo_emit("{L:/%-26s}{V:user/%s}\n",
"User:", conf->isc_user);
xo_emit("{L:/%-25s}{V:secret/%s}\n",
xo_emit("{L:/%-26s}{V:secret/%s}\n",
"Secret:", conf->isc_secret);
xo_emit("{L:/%-25s}{V:mutualUser/%s}\n",
xo_emit("{L:/%-26s}{V:mutualUser/%s}\n",
"Mutual user:", conf->isc_mutual_user);
xo_emit("{L:/%-25s}{V:mutualSecret/%s}\n",
xo_emit("{L:/%-26s}{V:mutualSecret/%s}\n",
"Mutual secret:", conf->isc_mutual_secret);
xo_close_container("auth");
xo_emit("{L:/%-25s}{V:type/%s}\n",
xo_emit("{L:/%-26s}{V:type/%s}\n",
"Session type:",
conf->isc_discovery ? "Discovery" : "Normal");
xo_emit("{L:/%-25s}{V:enable/%s}\n",
xo_emit("{L:/%-26s}{V:enable/%s}\n",
"Enable:",
conf->isc_enable ? "Yes" : "No");
xo_emit("{L:/%-25s}{V:state/%s}\n",
xo_emit("{L:/%-26s}{V:state/%s}\n",
"Session state:",
state->iss_connected ? "Connected" : "Disconnected");
xo_emit("{L:/%-25s}{V:failureReason/%s}\n",
xo_emit("{L:/%-26s}{V:failureReason/%s}\n",
"Failure reason:", state->iss_reason);
xo_emit("{L:/%-25s}{V:headerDigest/%s}\n",
xo_emit("{L:/%-26s}{V:headerDigest/%s}\n",
"Header digest:",
state->iss_header_digest == ISCSI_DIGEST_CRC32C ?
"CRC32C" : "None");
xo_emit("{L:/%-25s}{V:dataDigest/%s}\n",
xo_emit("{L:/%-26s}{V:dataDigest/%s}\n",
"Data digest:",
state->iss_data_digest == ISCSI_DIGEST_CRC32C ?
"CRC32C" : "None");
xo_emit("{L:/%-25s}{V:recvDataSegmentLen/%d}\n",
xo_emit("{L:/%-26s}{V:recvDataSegmentLen/%d}\n",
"MaxRecvDataSegmentLength:",
state->iss_max_recv_data_segment_length);
xo_emit("{L:/%-25s}{V:sendDataSegmentLen/%d}\n",
xo_emit("{L:/%-26s}{V:sendDataSegmentLen/%d}\n",
"MaxSendDataSegmentLength:",
state->iss_max_send_data_segment_length);
xo_emit("{L:/%-25s}{V:maxBurstLen/%d}\n",
xo_emit("{L:/%-26s}{V:maxBurstLen/%d}\n",
"MaxBurstLen:", state->iss_max_burst_length);
xo_emit("{L:/%-25s}{V:firstBurstLen/%d}\n",
xo_emit("{L:/%-26s}{V:firstBurstLen/%d}\n",
"FirstBurstLen:", state->iss_first_burst_length);
xo_emit("{L:/%-25s}{V:immediateData/%s}\n",
xo_emit("{L:/%-26s}{V:immediateData/%s}\n",
"ImmediateData:", state->iss_immediate_data ? "Yes" : "No");
xo_emit("{L:/%-25s}{V:iSER/%s}\n",
xo_emit("{L:/%-26s}{V:iSER/%s}\n",
"iSER (RDMA):", conf->isc_iser ? "Yes" : "No");
xo_emit("{L:/%-25s}{V:offloadDriver/%s}\n",
xo_emit("{L:/%-26s}{V:offloadDriver/%s}\n",
"Offload driver:", state->iss_offload);
xo_emit("{L:/%-25s}",
xo_emit("{L:/%-26s}",
"Device nodes:");
print_periphs(state->iss_id);
xo_emit("\n\n");

View File

@ -303,7 +303,7 @@ findchild(pid_t pid, int dont_alloc)
cpp = &(*cpp)->link)
;
if (*cpp == NULL) {
if (dont_alloc)
if (dont_alloc)
return(NULL);
if (child_freelist) {
*cpp = child_freelist;
@ -344,6 +344,8 @@ sigchild(int signo __unused)
save_errno = errno;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
cp = findchild(pid, 1);
if (cp == NULL)
continue;
if (cp->free)
delchild(cp);
else {

View File

@ -59,7 +59,7 @@ sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign,
FILE *ibuf;
char *cp, *cp2, line[LINESIZE];
int ishead, infld, ignoring, dostat, firstline;
int c, length, prefixlen;
int c = 0, length, prefixlen;
/*
* Compute the prefix string, without trailing whitespace
@ -566,8 +566,13 @@ savemail(char name[], FILE *fi)
char buf[BUFSIZ];
int i;
time_t now;
mode_t saved_umask;
if ((fo = Fopen(name, "a")) == NULL) {
saved_umask = umask(077);
fo = Fopen(name, "a");
umask(saved_umask);
if (fo == NULL) {
warn("%s", name);
return (-1);
}

View File

@ -83,12 +83,12 @@ static struct level_stack *g_ls;
#if defined(SORT_THREADS)
/* stack guarding mutex */
static pthread_cond_t g_ls_cond;
static pthread_mutex_t g_ls_mutex;
/* counter: how many items are left */
static size_t sort_left;
/* guarding mutex */
static pthread_mutex_t sort_left_mutex;
/* semaphore to count threads */
static sem_t mtsem;
@ -99,23 +99,25 @@ static sem_t mtsem;
static inline void
sort_left_dec(size_t n)
{
pthread_mutex_lock(&sort_left_mutex);
pthread_mutex_lock(&g_ls_mutex);
sort_left -= n;
pthread_mutex_unlock(&sort_left_mutex);
if (sort_left == 0 && nthreads > 1)
pthread_cond_broadcast(&g_ls_cond);
pthread_mutex_unlock(&g_ls_mutex);
}
/*
* Do we have something to sort ?
*
* This routine does not need to be locked.
*/
static inline bool
have_sort_left(void)
{
bool ret;
pthread_mutex_lock(&sort_left_mutex);
ret = (sort_left > 0);
pthread_mutex_unlock(&sort_left_mutex);
return (ret);
}
@ -144,6 +146,11 @@ push_ls(struct sort_level *sl)
new_ls->next = g_ls;
g_ls = new_ls;
#if defined(SORT_THREADS)
if (nthreads > 1)
pthread_cond_signal(&g_ls_cond);
#endif
#if defined(SORT_THREADS)
if (nthreads > 1)
pthread_mutex_unlock(&g_ls_mutex);
@ -184,13 +191,19 @@ pop_ls_mt(void)
pthread_mutex_lock(&g_ls_mutex);
if (g_ls) {
sl = g_ls->sl;
saved_ls = g_ls;
g_ls = g_ls->next;
} else {
for (;;) {
if (g_ls) {
sl = g_ls->sl;
saved_ls = g_ls;
g_ls = g_ls->next;
break;
}
sl = NULL;
saved_ls = NULL;
if (have_sort_left() == 0)
break;
pthread_cond_wait(&g_ls_cond, &g_ls_mutex);
}
pthread_mutex_unlock(&g_ls_mutex);
@ -495,13 +508,8 @@ run_sort_cycle_mt(void)
for (;;) {
slc = pop_ls_mt();
if (slc == NULL) {
if (have_sort_left()) {
pthread_yield();
continue;
}
if (slc == NULL)
break;
}
run_sort_level_next(slc);
}
}
@ -512,9 +520,7 @@ run_sort_cycle_mt(void)
static void*
sort_thread(void* arg)
{
run_sort_cycle_mt();
sem_post(&mtsem);
return (arg);
@ -610,8 +616,7 @@ run_top_sort_level(struct sort_level *sl)
pthread_t pth;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,
PTHREAD_DETACHED);
pthread_attr_setdetachstate(&attr, PTHREAD_DETACHED);
for (;;) {
int res = pthread_create(&pth, &attr,
@ -628,7 +633,7 @@ run_top_sort_level(struct sort_level *sl)
pthread_attr_destroy(&attr);
}
for(i = 0; i < nthreads; ++i)
for (i = 0; i < nthreads; ++i)
sem_wait(&mtsem);
}
#endif /* defined(SORT_THREADS) */
@ -651,7 +656,7 @@ run_sort(struct sort_list_item **base, size_t nmemb)
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_ADAPTIVE_NP);
pthread_mutex_init(&g_ls_mutex, &mattr);
pthread_mutex_init(&sort_left_mutex, &mattr);
pthread_cond_init(&g_ls_cond, NULL);
pthread_mutexattr_destroy(&mattr);
@ -679,7 +684,6 @@ run_sort(struct sort_list_item **base, size_t nmemb)
if (nthreads > 1) {
sem_destroy(&mtsem);
pthread_mutex_destroy(&g_ls_mutex);
pthread_mutex_destroy(&sort_left_mutex);
}
nthreads = nthreads_save;
#endif

View File

@ -0,0 +1,106 @@
/*-
* Copyright 2017 Li-Wen Hsu <lwhsu@FreeBSD.org>
*
* 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$");
/* FreeBSD/riscv64-specific system call handling. */
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <machine/frame.h>
#include <machine/reg.h>
#include <stdbool.h>
#include <stdio.h>
#include <sysdecode.h>
#include "truss.h"
static int
riscv64_fetch_args(struct trussinfo *trussinfo, u_int narg)
{
struct reg regs;
struct current_syscall *cs;
lwpid_t tid;
u_int i, reg, syscall_num;
tid = trussinfo->curthread->tid;
cs = &trussinfo->curthread->cs;
if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
return (-1);
}
/*
* FreeBSD has two special kinds of system call redirections --
* SYS_syscall, and SYS___syscall. The former is the old syscall()
* routine, basically; the latter is for quad-aligned arguments.
*
* The system call argument count and code from ptrace() already
* account for these, but we need to skip over the first argument.
*/
syscall_num = regs.t[0];
if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) {
reg = 1;
syscall_num = regs.a[0];
} else {
reg = 0;
}
for (i = 0; i < narg && reg < NARGREG; i++, reg++)
cs->args[i] = regs.a[reg];
return (0);
}
static int
riscv64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
{
struct reg regs;
lwpid_t tid;
tid = trussinfo->curthread->tid;
if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
return (-1);
}
retval[0] = regs.a[0];
retval[1] = regs.a[1];
*errorp = !!(regs.t[0]);
return (0);
}
static struct procabi riscv64_freebsd = {
"FreeBSD ELF64",
SYSDECODE_ABI_FREEBSD,
riscv64_fetch_args,
riscv64_fetch_retval,
STAILQ_HEAD_INITIALIZER(riscv64_freebsd.extra_syscalls),
{ NULL }
};
PROCABI(riscv64_freebsd);

View File

@ -35,7 +35,7 @@
.\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $
.\" $FreeBSD$
.\"
.Dd December 21, 2016
.Dd January 23, 2017
.Dt CTLADM 8
.Os
.Sh NAME
@ -941,6 +941,14 @@ Specifies file or device name to use for backing store.
.It Va num_threads
Specifies number of backend threads to use for this LUN.
.El
.Pp
Options specific for ramdisk backend:
.Bl -tag -width 12n
.It Va capacity
Specifies capacity of backing store (maximum RAM for data).
The default value is zero, that disables backing store completely,
making all writes go to nowhere, while all reads return zeroes.
.El
.Sh EXAMPLES
.Dl ctladm tur 1
.Pp
@ -977,7 +985,14 @@ starting at LBA 0xff432140.
Create a LUN with the
.Dq fake
ramdisk as a backing store.
The LUN will claim to have a size of approximately 10 terabytes.
The LUN will claim to have a size of approximately 10 terabytes,
while having no real data store (all written data are lost).
.Pp
.Dl ctladm create -b ramdisk -s 10T -o capacity=10G
.Pp
Create a thin provisioned LUN with a ramdisk as a backing store.
The LUN will have maximal backing store capacity of 10 gigabytes,
while reporting size of 10 terabytes,
.Pp
.Dl ctladm create -b block -o file=src/usr.sbin/ctladm/ctladm.8
.Pp

View File

@ -41,12 +41,8 @@ static const char rcsid[] =
static int
numerics(char const * str)
{
int rc = isdigit((unsigned char)*str);
if (rc)
while (isdigit((unsigned char)*str) || *str == 'x')
++str;
return rc && !*str;
return (str[strspn(str, "0123456789x")] == '\0');
}
static int

View File

@ -1493,7 +1493,7 @@ pw_user_mod(int argc, char **argv, char *arg1)
intmax_t id = -1;
int ch, fd = -1;
size_t i, j;
bool quiet, createhome, pretty, dryrun, nis, edited, docreatehome;
bool quiet, createhome, pretty, dryrun, nis, edited;
bool precrypted;
mode_t homemode = 0;
time_t expire_days, password_days, now;
@ -1503,7 +1503,7 @@ pw_user_mod(int argc, char **argv, char *arg1)
passwd = NULL;
class = nispasswd = NULL;
quiet = createhome = pretty = dryrun = nis = precrypted = false;
edited = docreatehome = false;
edited = false;
if (arg1 != NULL) {
if (arg1[strspn(arg1, "0123456789")] == '\0')
@ -1704,8 +1704,6 @@ pw_user_mod(int argc, char **argv, char *arg1)
if (!createhome)
warnx("WARNING: home `%s' does not exist",
pwd->pw_dir);
else
docreatehome = true;
} else if (!S_ISDIR(st.st_mode)) {
warnx("WARNING: home `%s' is not a directory",
pwd->pw_dir);
@ -1797,7 +1795,7 @@ pw_user_mod(int argc, char **argv, char *arg1)
* that this also `works' for editing users if -m is used, but
* existing files will *not* be overwritten.
*/
if (PWALTDIR() != PWF_ALT && docreatehome && pwd->pw_dir &&
if (PWALTDIR() != PWF_ALT && createhome && pwd->pw_dir &&
*pwd->pw_dir == '/' && pwd->pw_dir[1]) {
if (!skel)
skel = cnf->dotdir;

View File

@ -253,6 +253,26 @@ user_mod_w_yes_body() {
$(atf_get_srcdir)/crypt $passhash "foo"
}
atf_test_case user_mod_m
user_mod_m_body() {
populate_root_etc_skel
mkdir -p ${HOME}/home
mkdir -p ${HOME}/skel
echo "entry" > ${HOME}/skel/.file
atf_check -s exit:0 ${RPW} useradd foo
! test -d ${HOME}/home/foo || atf_fail "Directory should not have been created"
atf_check -s exit:0 ${RPW} usermod foo -m -k /skel
test -d ${HOME}/home/foo || atf_fail "Directory should have been created"
test -f ${HOME}/home/foo/.file || atf_fail "Skell files not added"
echo "entry" > ${HOME}/skel/.file2
atf_check -s exit:0 ${RPW} usermod foo -m -k /skel
test -f ${HOME}/home/foo/.file2 || atf_fail "Skell files not added"
echo > ${HOME}/home/foo/.file2
atf_check -s exit:0 ${RPW} usermod foo -m -k /skel
atf_check -s exit:0 -o inline:"\n" cat ${HOME}/home/foo/.file2
}
atf_init_test_cases() {
atf_add_test_case user_mod
@ -275,4 +295,5 @@ atf_init_test_cases() {
atf_add_test_case user_mod_w_none
atf_add_test_case user_mod_w_random
atf_add_test_case user_mod_w_yes
atf_add_test_case user_mod_m
}

Some files were not shown because too many files have changed in this diff Show More