rtwn: Import from FreeBSD.

This commit is contained in:
Christian Mauderer 2016-11-22 10:41:47 +01:00
parent 9bc41d057e
commit 0cbb715ade
149 changed files with 26962 additions and 2 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,271 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* 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 <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <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/if_rtwn_beacon.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/if_rtwn_tx.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
static void
rtwn_reset_beacon_valid(struct rtwn_softc *sc, int id)
{
KASSERT (id == 0 || id == 1, ("wrong port id %d\n", id));
/* XXX cannot be cleared on RTL8188CE */
rtwn_setbits_1_shift(sc, sc->bcn_status_reg[id],
R92C_TDECTRL_BCN_VALID, 0, 2);
RTWN_DPRINTF(sc, RTWN_DEBUG_BEACON,
"%s: 'beacon valid' bit for vap %d was unset\n",
__func__, id);
}
static int
rtwn_check_beacon_valid(struct rtwn_softc *sc, int id)
{
uint16_t reg;
int ntries;
if (id == RTWN_VAP_ID_INVALID)
return (0);
reg = sc->bcn_status_reg[id];
for (ntries = 0; ntries < 10; ntries++) {
if (rtwn_read_4(sc, reg) & R92C_TDECTRL_BCN_VALID) {
RTWN_DPRINTF(sc, RTWN_DEBUG_BEACON,
"%s: beacon for vap %d was recognized\n",
__func__, id);
break;
}
rtwn_delay(sc, sc->bcn_check_interval);
}
if (ntries == 10)
return (ETIMEDOUT);
return (0);
}
void
rtwn_switch_bcnq(struct rtwn_softc *sc, int id)
{
if (sc->cur_bcnq_id != id) {
/* Wait until any previous transmit completes. */
(void) rtwn_check_beacon_valid(sc, sc->cur_bcnq_id);
/* Change current port. */
rtwn_beacon_select(sc, id);
sc->cur_bcnq_id = id;
}
/* Reset 'beacon valid' bit. */
rtwn_reset_beacon_valid(sc, id);
}
int
rtwn_setup_beacon(struct rtwn_softc *sc, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct rtwn_vap *uvp = RTWN_VAP(vap);
struct mbuf *m;
RTWN_ASSERT_LOCKED(sc);
if (ni->ni_chan == IEEE80211_CHAN_ANYC)
return (EINVAL);
m = ieee80211_beacon_alloc(ni);
if (m == NULL) {
device_printf(sc->sc_dev,
"%s: could not allocate beacon frame\n", __func__);
return (ENOMEM);
}
if (uvp->bcn_mbuf != NULL) {
rtwn_beacon_unload(sc, uvp->id);
m_freem(uvp->bcn_mbuf);
}
uvp->bcn_mbuf = m;
rtwn_beacon_set_rate(sc, &uvp->bcn_desc.txd[0],
IEEE80211_IS_CHAN_5GHZ(ni->ni_chan));
return (rtwn_tx_beacon_check(sc, uvp));
}
/*
* Push a beacon frame into the chip. Beacon will
* be repeated by the chip every R92C_BCN_INTERVAL.
*/
static int
rtwn_tx_beacon(struct rtwn_softc *sc, struct rtwn_vap *uvp)
{
int error;
RTWN_ASSERT_LOCKED(sc);
RTWN_DPRINTF(sc, RTWN_DEBUG_BEACON,
"%s: sending beacon for vap %d\n", __func__, uvp->id);
error = rtwn_tx_start(sc, NULL, uvp->bcn_mbuf, &uvp->bcn_desc.txd[0],
IEEE80211_FC0_TYPE_MGT, uvp->id);
return (error);
}
void
rtwn_update_beacon(struct ieee80211vap *vap, int item)
{
struct ieee80211com *ic = vap->iv_ic;
struct rtwn_softc *sc = ic->ic_softc;
struct rtwn_vap *uvp = RTWN_VAP(vap);
struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off;
struct ieee80211_node *ni = vap->iv_bss;
int mcast = 0;
RTWN_LOCK(sc);
if (uvp->bcn_mbuf == NULL) {
uvp->bcn_mbuf = ieee80211_beacon_alloc(ni);
if (uvp->bcn_mbuf == NULL) {
device_printf(sc->sc_dev,
"%s: could not allocate beacon frame\n", __func__);
RTWN_UNLOCK(sc);
return;
}
}
RTWN_DPRINTF(sc, RTWN_DEBUG_BEACON,
"%s: vap id %d, iv_csa_count %d, ic_csa_count %d, item %d\n",
__func__, uvp->id, vap->iv_csa_count, ic->ic_csa_count, item);
switch (item) {
case IEEE80211_BEACON_CSA:
if (vap->iv_csa_count != ic->ic_csa_count) {
/*
* XXX two APs with different beacon intervals
* are not handled properly.
*/
/* XXX check TBTT? */
taskqueue_enqueue_timeout(taskqueue_thread,
&uvp->tx_beacon_csa,
msecs_to_ticks(ni->ni_intval));
}
break;
case IEEE80211_BEACON_TIM:
mcast = 1; /* XXX */
break;
default:
break;
}
setbit(bo->bo_flags, item);
rtwn_beacon_update_begin(sc, vap);
RTWN_UNLOCK(sc);
ieee80211_beacon_update(ni, uvp->bcn_mbuf, mcast);
/* XXX clear manually */
clrbit(bo->bo_flags, IEEE80211_BEACON_CSA);
RTWN_LOCK(sc);
rtwn_tx_beacon(sc, uvp);
rtwn_beacon_update_end(sc, vap);
RTWN_UNLOCK(sc);
}
void
rtwn_tx_beacon_csa(void *arg, int npending __unused)
{
struct ieee80211vap *vap = arg;
struct ieee80211com *ic = vap->iv_ic;
struct rtwn_softc *sc = ic->ic_softc;
struct rtwn_vap *rvp = RTWN_VAP(vap);
KASSERT (rvp->id == 0 || rvp->id == 1,
("wrong port id %d\n", rvp->id));
IEEE80211_LOCK(ic);
if (ic->ic_flags & IEEE80211_F_CSAPENDING) {
RTWN_DPRINTF(sc, RTWN_DEBUG_BEACON,
"%s: vap id %d, iv_csa_count %d, ic_csa_count %d\n",
__func__, rvp->id, vap->iv_csa_count, ic->ic_csa_count);
rtwn_update_beacon(vap, IEEE80211_BEACON_CSA);
}
IEEE80211_UNLOCK(ic);
(void) rvp;
}
int
rtwn_tx_beacon_check(struct rtwn_softc *sc, struct rtwn_vap *uvp)
{
int ntries, error;
for (ntries = 0; ntries < 5; ntries++) {
rtwn_reset_beacon_valid(sc, uvp->id);
error = rtwn_tx_beacon(sc, uvp);
if (error != 0)
continue;
error = rtwn_check_beacon_valid(sc, uvp->id);
if (error == 0)
break;
}
if (ntries == 5) {
device_printf(sc->sc_dev,
"%s: cannot push beacon into chip, error %d!\n",
__func__, error);
return (error);
}
return (0);
}

View File

@ -0,0 +1,28 @@
/*-
* 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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_BEACON_H
#define IF_RTWN_BEACON_H
void rtwn_switch_bcnq(struct rtwn_softc *, int);
int rtwn_setup_beacon(struct rtwn_softc *, struct ieee80211_node *);
void rtwn_update_beacon(struct ieee80211vap *, int);
void rtwn_tx_beacon_csa(void *arg, int);
int rtwn_tx_beacon_check(struct rtwn_softc *, struct rtwn_vap *);
#endif /* IF_RTWN_BEACON_H */

View File

@ -0,0 +1,130 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <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/if_rtwn_calib.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/if_rtwn_task.h>
static void
rtwn_temp_calib(struct rtwn_softc *sc)
{
uint8_t temp;
RTWN_ASSERT_LOCKED(sc);
if (!(sc->sc_flags & RTWN_TEMP_MEASURED)) {
/* Start measuring temperature. */
RTWN_DPRINTF(sc, RTWN_DEBUG_TEMP,
"%s: start measuring temperature\n", __func__);
rtwn_temp_measure(sc);
sc->sc_flags |= RTWN_TEMP_MEASURED;
return;
}
sc->sc_flags &= ~RTWN_TEMP_MEASURED;
/* Read measured temperature. */
temp = rtwn_temp_read(sc);
if (temp == 0) { /* Read failed, skip. */
RTWN_DPRINTF(sc, RTWN_DEBUG_TEMP,
"%s: temperature read failed, skipping\n", __func__);
return;
}
RTWN_DPRINTF(sc, RTWN_DEBUG_TEMP,
"temperature: previous %u, current %u\n",
sc->thcal_temp, temp);
/*
* Redo LC/IQ calibration if temperature changed significantly since
* last calibration.
*/
if (sc->thcal_temp == 0xff) {
/* efuse value is absent; do LCK at initial status. */
rtwn_lc_calib(sc);
sc->thcal_temp = temp;
} else if (abs(temp - sc->thcal_temp) > sc->temp_delta) {
RTWN_DPRINTF(sc, RTWN_DEBUG_TEMP,
"%s: LC/IQ calib triggered by temp: %u -> %u\n",
__func__, sc->thcal_temp, temp);
rtwn_lc_calib(sc);
rtwn_iq_calib(sc);
/* Record temperature of last calibration. */
sc->thcal_temp = temp;
}
}
static void
rtwn_calib_cb(struct rtwn_softc *sc, union sec_param *data)
{
/* Do temperature compensation. */
rtwn_temp_calib(sc);
#ifndef RTWN_WITHOUT_UCODE
if (sc->sc_ratectl == RTWN_RATECTL_FW) {
/* Refresh per-node RSSI. */
rtwn_set_rssi(sc);
}
#endif
if (sc->vaps_running > sc->monvaps_running)
callout_reset(&sc->sc_calib_to, 2*hz, rtwn_calib_to, sc);
}
void
rtwn_calib_to(void *arg)
{
struct rtwn_softc *sc = arg;
/* Do it in a process context. */
rtwn_cmd_sleepable(sc, NULL, 0, rtwn_calib_cb);
}

View File

@ -0,0 +1,24 @@
/*-
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_CALIB_H
#define IF_RTWN_CALIB_H
void rtwn_calib_to(void *);
#endif /* IF_RTWN_CALIB_H */

View File

@ -0,0 +1,366 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <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_cam.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/if_rtwn_task.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
void
rtwn_init_cam(struct rtwn_softc *sc)
{
/* Invalidate all CAM entries. */
rtwn_write_4(sc, R92C_CAMCMD,
R92C_CAMCMD_POLLING | R92C_CAMCMD_CLR);
}
static int
rtwn_cam_write(struct rtwn_softc *sc, uint32_t addr, uint32_t data)
{
int error;
error = rtwn_write_4(sc, R92C_CAMWRITE, data);
if (error != 0)
return (error);
error = rtwn_write_4(sc, R92C_CAMCMD,
R92C_CAMCMD_POLLING | R92C_CAMCMD_WRITE |
SM(R92C_CAMCMD_ADDR, addr));
return (error);
}
void
rtwn_init_seccfg(struct rtwn_softc *sc)
{
uint16_t seccfg;
/* Select decryption / encryption flags. */
seccfg = 0;
switch (sc->sc_hwcrypto) {
case RTWN_CRYPTO_SW:
break; /* nothing to do */
case RTWN_CRYPTO_PAIR:
/* NB: TXUCKEY_DEF / RXUCKEY_DEF are required for RTL8192C */
seccfg = R92C_SECCFG_TXUCKEY_DEF | R92C_SECCFG_RXUCKEY_DEF |
R92C_SECCFG_TXENC_ENA | R92C_SECCFG_RXDEC_ENA |
R92C_SECCFG_MC_SRCH_DIS;
break;
case RTWN_CRYPTO_FULL:
seccfg = R92C_SECCFG_TXUCKEY_DEF | R92C_SECCFG_RXUCKEY_DEF |
R92C_SECCFG_TXENC_ENA | R92C_SECCFG_RXDEC_ENA |
R92C_SECCFG_TXBCKEY_DEF | R92C_SECCFG_RXBCKEY_DEF;
break;
default:
KASSERT(0, ("%s: case %d was not handled\n", __func__,
sc->sc_hwcrypto));
break;
}
RTWN_DPRINTF(sc, RTWN_DEBUG_KEY, "%s: seccfg %04X, hwcrypto %d\n",
__func__, seccfg, sc->sc_hwcrypto);
rtwn_write_2(sc, R92C_SECCFG, seccfg);
}
int
rtwn_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
{
struct rtwn_softc *sc = vap->iv_ic->ic_softc;
int i, start;
if (&vap->iv_nw_keys[0] <= k &&
k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) {
#if __FreeBSD_version > 1200018
*keyix = ieee80211_crypto_get_key_wepidx(vap, k);
#else
*keyix = k - vap->iv_nw_keys;
#endif
if (sc->sc_hwcrypto != RTWN_CRYPTO_FULL)
k->wk_flags |= IEEE80211_KEY_SWCRYPT;
else {
RTWN_LOCK(sc);
if (isset(sc->keys_bmap, *keyix)) {
device_printf(sc->sc_dev,
"%s: group key slot %d is already used!\n",
__func__, *keyix);
/* XXX recover? */
RTWN_UNLOCK(sc);
return (0);
}
setbit(sc->keys_bmap, *keyix);
RTWN_UNLOCK(sc);
}
goto end;
}
start = sc->cam_entry_limit;
switch (sc->sc_hwcrypto) {
case RTWN_CRYPTO_SW:
k->wk_flags |= IEEE80211_KEY_SWCRYPT;
*keyix = 0;
goto end;
case RTWN_CRYPTO_PAIR:
/* all slots for pairwise keys. */
start = 0;
RTWN_LOCK(sc);
if (sc->sc_flags & RTWN_FLAG_CAM_FIXED)
start = 4;
RTWN_UNLOCK(sc);
break;
case RTWN_CRYPTO_FULL:
/* first 4 - for group keys, others for pairwise. */
start = 4;
break;
default:
KASSERT(0, ("%s: case %d was not handled!\n",
__func__, sc->sc_hwcrypto));
break;
}
RTWN_LOCK(sc);
for (i = start; i < sc->cam_entry_limit; i++) {
if (isclr(sc->keys_bmap, i)) {
setbit(sc->keys_bmap, i);
*keyix = i;
break;
}
}
RTWN_UNLOCK(sc);
if (i == sc->cam_entry_limit) {
#if __FreeBSD_version > 1200008
/* XXX check and remove keys with the same MAC address */
k->wk_flags |= IEEE80211_KEY_SWCRYPT;
*keyix = 0;
#else
device_printf(sc->sc_dev,
"%s: no free space in the key table\n", __func__);
return (0);
#endif
}
end:
*rxkeyix = *keyix;
return (1);
}
static int
rtwn_key_set_cb0(struct rtwn_softc *sc, const struct ieee80211_key *k)
{
uint8_t algo, keyid;
int i, error;
if (sc->sc_hwcrypto == RTWN_CRYPTO_FULL &&
k->wk_keyix < IEEE80211_WEP_NKID)
keyid = k->wk_keyix;
else
keyid = 0;
/* Map net80211 cipher to HW crypto algorithm. */
switch (k->wk_cipher->ic_cipher) {
case IEEE80211_CIPHER_WEP:
if (k->wk_keylen < 8)
algo = R92C_CAM_ALGO_WEP40;
else
algo = R92C_CAM_ALGO_WEP104;
break;
case IEEE80211_CIPHER_TKIP:
algo = R92C_CAM_ALGO_TKIP;
break;
case IEEE80211_CIPHER_AES_CCM:
algo = R92C_CAM_ALGO_AES;
break;
default:
device_printf(sc->sc_dev, "%s: unknown cipher %u\n",
__func__, k->wk_cipher->ic_cipher);
return (EINVAL);
}
RTWN_DPRINTF(sc, RTWN_DEBUG_KEY,
"%s: keyix %u, keyid %u, algo %u/%u, flags %04X, len %u, "
"macaddr %s\n", __func__, k->wk_keyix, keyid,
k->wk_cipher->ic_cipher, algo, k->wk_flags, k->wk_keylen,
ether_sprintf(k->wk_macaddr));
/* Clear high bits. */
rtwn_cam_write(sc, R92C_CAM_CTL6(k->wk_keyix), 0);
rtwn_cam_write(sc, R92C_CAM_CTL7(k->wk_keyix), 0);
/* Write key. */
for (i = 0; i < 4; i++) {
error = rtwn_cam_write(sc, R92C_CAM_KEY(k->wk_keyix, i),
le32dec(&k->wk_key[i * 4]));
if (error != 0)
goto fail;
}
/* Write CTL0 last since that will validate the CAM entry. */
error = rtwn_cam_write(sc, R92C_CAM_CTL1(k->wk_keyix),
le32dec(&k->wk_macaddr[2]));
if (error != 0)
goto fail;
error = rtwn_cam_write(sc, R92C_CAM_CTL0(k->wk_keyix),
SM(R92C_CAM_ALGO, algo) |
SM(R92C_CAM_KEYID, keyid) |
SM(R92C_CAM_MACLO, le16dec(&k->wk_macaddr[0])) |
R92C_CAM_VALID);
if (error != 0)
goto fail;
return (0);
fail:
device_printf(sc->sc_dev, "%s fails, error %d\n", __func__, error);
return (error);
}
static void
rtwn_key_set_cb(struct rtwn_softc *sc, union sec_param *data)
{
const struct ieee80211_key *k = &data->key;
(void) rtwn_key_set_cb0(sc, k);
}
int
rtwn_init_static_keys(struct rtwn_softc *sc, struct rtwn_vap *rvp)
{
int i, error;
if (sc->sc_hwcrypto != RTWN_CRYPTO_FULL)
return (0); /* nothing to do */
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
const struct ieee80211_key *k = rvp->keys[i];
if (k != NULL) {
error = rtwn_key_set_cb0(sc, k);
if (error != 0)
return (error);
}
}
return (0);
}
static void
rtwn_key_del_cb(struct rtwn_softc *sc, union sec_param *data)
{
struct ieee80211_key *k = &data->key;
int i;
RTWN_DPRINTF(sc, RTWN_DEBUG_KEY,
"%s: keyix %u, flags %04X, macaddr %s\n", __func__,
k->wk_keyix, k->wk_flags, ether_sprintf(k->wk_macaddr));
rtwn_cam_write(sc, R92C_CAM_CTL0(k->wk_keyix), 0);
rtwn_cam_write(sc, R92C_CAM_CTL1(k->wk_keyix), 0);
/* Clear key. */
for (i = 0; i < 4; i++)
rtwn_cam_write(sc, R92C_CAM_KEY(k->wk_keyix, i), 0);
clrbit(sc->keys_bmap, k->wk_keyix);
}
static int
rtwn_process_key(struct ieee80211vap *vap, const struct ieee80211_key *k,
int set)
{
struct rtwn_softc *sc = vap->iv_ic->ic_softc;
if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
/* Not for us. */
return (1);
}
if (&vap->iv_nw_keys[0] <= k &&
k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) {
#if __FreeBSD_version <= 1200008
struct ieee80211_key *k1 = &vap->iv_nw_keys[k->wk_keyix];
if (sc->sc_hwcrypto != RTWN_CRYPTO_FULL) {
k1->wk_flags |= IEEE80211_KEY_SWCRYPT;
return (k->wk_cipher->ic_setkey(k1));
} else {
#else
if (sc->sc_hwcrypto == RTWN_CRYPTO_FULL) {
#endif
struct rtwn_vap *rvp = RTWN_VAP(vap);
RTWN_LOCK(sc);
rvp->keys[k->wk_keyix] = (set ? k : NULL);
if ((sc->sc_flags & RTWN_RUNNING) == 0) {
if (!set)
clrbit(sc->keys_bmap, k->wk_keyix);
RTWN_UNLOCK(sc);
return (1);
}
RTWN_UNLOCK(sc);
}
}
return (!rtwn_cmd_sleepable(sc, k, sizeof(*k),
set ? rtwn_key_set_cb : rtwn_key_del_cb));
}
int
rtwn_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
{
return (rtwn_process_key(vap, k, 1));
}
int
rtwn_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
{
return (rtwn_process_key(vap, k, 0));
}

View File

@ -0,0 +1,30 @@
/*-
* 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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_CAM_H
#define IF_RTWN_CAM_H
void rtwn_init_cam(struct rtwn_softc *);
void rtwn_init_seccfg(struct rtwn_softc *);
int rtwn_key_alloc(struct ieee80211vap *, struct ieee80211_key *,
ieee80211_keyix *, ieee80211_keyix *);
int rtwn_key_set(struct ieee80211vap *, const struct ieee80211_key *);
int rtwn_init_static_keys(struct rtwn_softc *, struct rtwn_vap *);
int rtwn_key_delete(struct ieee80211vap *, const struct ieee80211_key *);
#endif /* IF_RTWN_CAM_H */

View File

@ -0,0 +1,60 @@
/* $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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_DEBUG_H
#define IF_RTWN_DEBUG_H
#include <rtems/bsd/local/opt_rtwn.h>
#ifdef RTWN_DEBUG
enum {
RTWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
RTWN_DEBUG_XMIT_DESC = 0x00000002, /* xmit descriptors */
RTWN_DEBUG_RECV = 0x00000004, /* basic recv operation */
RTWN_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */
RTWN_DEBUG_STATE = 0x00000010, /* 802.11 state transitions */
RTWN_DEBUG_RA = 0x00000020, /* f/w rate adaptation setup */
RTWN_DEBUG_USB = 0x00000040, /* usb requests */
RTWN_DEBUG_FIRMWARE = 0x00000080, /* firmware(9) loading debug */
RTWN_DEBUG_BEACON = 0x00000100, /* beacon handling */
RTWN_DEBUG_INTR = 0x00000200, /* ISR */
RTWN_DEBUG_TEMP = 0x00000400, /* temperature calibration */
RTWN_DEBUG_ROM = 0x00000800, /* various ROM info */
RTWN_DEBUG_KEY = 0x00001000, /* crypto keys management */
RTWN_DEBUG_TXPWR = 0x00002000, /* dump Tx power values */
RTWN_DEBUG_RSSI = 0x00004000, /* dump RSSI lookups */
RTWN_DEBUG_RESET = 0x00008000, /* initialization progress */
RTWN_DEBUG_CALIB = 0x00010000, /* calibration progress */
RTWN_DEBUG_RADAR = 0x00020000, /* radar detection status */
RTWN_DEBUG_ANY = 0xffffffff
};
#define RTWN_DPRINTF(_sc, _m, ...) do { \
if ((_sc)->sc_debug & (_m)) \
device_printf((_sc)->sc_dev, __VA_ARGS__); \
} while(0)
#else
#define RTWN_DPRINTF(_sc, _m, ...) do { (void) _sc; } while (0)
#endif
#endif /* IF_RTWN_DEBUG_H */

View File

@ -0,0 +1,267 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <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_efuse.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
static int
rtwn_efuse_switch_power(struct rtwn_softc *sc)
{
uint32_t reg;
int error;
error = rtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON);
if (error != 0)
return (error);
reg = rtwn_read_2(sc, R92C_SYS_FUNC_EN);
if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
error = rtwn_write_2(sc, R92C_SYS_FUNC_EN,
reg | R92C_SYS_FUNC_EN_ELDR);
if (error != 0)
return (error);
}
reg = rtwn_read_2(sc, R92C_SYS_CLKR);
if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
(R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
error = rtwn_write_2(sc, R92C_SYS_CLKR,
reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
if (error != 0)
return (error);
}
return (0);
}
int
rtwn_efuse_read_next(struct rtwn_softc *sc, uint8_t *val)
{
uint32_t reg;
int ntries, error;
if (sc->next_rom_addr >= sc->efuse_maxlen)
return (EFAULT);
reg = rtwn_read_4(sc, R92C_EFUSE_CTRL);
reg = RW(reg, R92C_EFUSE_CTRL_ADDR, sc->next_rom_addr);
reg &= ~R92C_EFUSE_CTRL_VALID;
error = rtwn_write_4(sc, R92C_EFUSE_CTRL, reg);
if (error != 0)
return (error);
/* Wait for read operation to complete. */
for (ntries = 0; ntries < 100; ntries++) {
reg = rtwn_read_4(sc, R92C_EFUSE_CTRL);
if (reg & R92C_EFUSE_CTRL_VALID)
break;
rtwn_delay(sc, 10);
}
if (ntries == 100) {
device_printf(sc->sc_dev,
"could not read efuse byte at address 0x%x\n",
sc->next_rom_addr);
return (ETIMEDOUT);
}
*val = MS(reg, R92C_EFUSE_CTRL_DATA);
sc->next_rom_addr++;
return (0);
}
static int
rtwn_efuse_read_data(struct rtwn_softc *sc, uint8_t *rom, uint8_t off,
uint8_t msk)
{
uint8_t reg;
int addr, i, error;
for (i = 0; i < 4; i++) {
if (msk & (1 << i))
continue;
addr = off * 8 + i * 2;
if (addr + 1 >= sc->efuse_maplen)
return (EFAULT);
error = rtwn_efuse_read_next(sc, &reg);
if (error != 0)
return (error);
RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "rom[0x%03X] == 0x%02X\n",
addr, reg);
rom[addr] = reg;
error = rtwn_efuse_read_next(sc, &reg);
if (error != 0)
return (error);
RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "rom[0x%03X] == 0x%02X\n",
addr + 1, reg);
rom[addr + 1] = reg;
}
return (0);
}
#ifdef RTWN_DEBUG
static void
rtwn_dump_rom_contents(struct rtwn_softc *sc, uint8_t *rom, uint16_t size)
{
int i;
/* Dump ROM contents. */
device_printf(sc->sc_dev, "%s:", __func__);
for (i = 0; i < size; i++) {
if (i % 32 == 0)
printf("\n%03X: ", i);
else if (i % 4 == 0)
printf(" ");
printf("%02X", rom[i]);
}
printf("\n");
}
#endif
static int
rtwn_efuse_read(struct rtwn_softc *sc, uint8_t *rom, uint16_t size)
{
#define RTWN_CHK(res) do { \
if ((error = res) != 0) \
goto end; \
} while(0)
uint8_t msk, off, reg;
int error;
/* Read full ROM image. */
sc->next_rom_addr = 0;
memset(rom, 0xff, size);
RTWN_CHK(rtwn_efuse_read_next(sc, &reg));
while (reg != 0xff) {
/* check for extended header */
if ((sc->sc_flags & RTWN_FLAG_EXT_HDR) &&
(reg & 0x1f) == 0x0f) {
off = reg >> 5;
RTWN_CHK(rtwn_efuse_read_next(sc, &reg));
if ((reg & 0x0f) != 0x0f)
off = ((reg & 0xf0) >> 1) | off;
else
continue;
} else
off = reg >> 4;
msk = reg & 0xf;
RTWN_CHK(rtwn_efuse_read_data(sc, rom, off, msk));
RTWN_CHK(rtwn_efuse_read_next(sc, &reg));
}
end:
#ifdef RTWN_DEBUG
if (sc->sc_debug & RTWN_DEBUG_ROM)
rtwn_dump_rom_contents(sc, rom, size);
#endif
/* Device-specific. */
rtwn_efuse_postread(sc);
if (error != 0) {
device_printf(sc->sc_dev, "%s: error while reading ROM\n",
__func__);
}
return (error);
#undef RTWN_CHK
}
static int
rtwn_efuse_read_prepare(struct rtwn_softc *sc, uint8_t *rom, uint16_t size)
{
int error;
error = rtwn_efuse_switch_power(sc);
if (error != 0)
goto fail;
error = rtwn_efuse_read(sc, rom, size);
fail:
rtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_OFF);
return (error);
}
int
rtwn_read_rom(struct rtwn_softc *sc)
{
uint8_t *rom;
int error;
rom = malloc(sc->efuse_maplen, M_TEMP, M_WAITOK);
/* Read full ROM image. */
RTWN_LOCK(sc);
error = rtwn_efuse_read_prepare(sc, rom, sc->efuse_maplen);
RTWN_UNLOCK(sc);
if (error != 0)
goto fail;
/* Parse & save data in softc. */
rtwn_parse_rom(sc, rom);
fail:
free(rom, M_TEMP);
return (error);
}

View File

@ -0,0 +1,25 @@
/*-
* 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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_EFUSE_H
#define IF_RTWN_EFUSE_H
int rtwn_efuse_read_next(struct rtwn_softc *, uint8_t *);
int rtwn_read_rom(struct rtwn_softc *);
#endif /* IF_RTWN_EFUSE_H */

View File

@ -0,0 +1,226 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <sys/firmware.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_fw.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#ifndef RTWN_WITHOUT_UCODE
static int
rtwn_fw_loadpage(struct rtwn_softc *sc, int page, const uint8_t *buf,
int len)
{
uint32_t reg;
uint16_t off;
int mlen, error;
reg = rtwn_read_4(sc, R92C_MCUFWDL);
reg = RW(reg, R92C_MCUFWDL_PAGE, page);
rtwn_write_4(sc, R92C_MCUFWDL, reg);
error = 0;
off = R92C_FW_START_ADDR;
while (len > 0) {
if (len > R92C_FW_MAX_BLOCK_SIZE)
mlen = R92C_FW_MAX_BLOCK_SIZE;
else if (len > 4)
mlen = 4;
else
mlen = 1;
error = rtwn_fw_write_block(sc, buf, off, mlen);
if (error != 0)
break;
off += mlen;
buf += mlen;
len -= mlen;
}
if (error != 0) {
RTWN_DPRINTF(sc, RTWN_DEBUG_FIRMWARE,
"%s: could not load firmware page %d (offset %u)\n",
__func__, page, off);
}
return (error);
}
static int
rtwn_fw_checksum_report(struct rtwn_softc *sc)
{
int ntries;
for (ntries = 0; ntries < 25; ntries++) {
if (rtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_CHKSUM_RPT)
break;
rtwn_delay(sc, 10000);
}
if (ntries == 25) {
RTWN_DPRINTF(sc, RTWN_DEBUG_FIRMWARE,
"timeout waiting for checksum report\n");
return (ETIMEDOUT);
}
return (0);
}
int
rtwn_load_firmware(struct rtwn_softc *sc)
{
const struct firmware *fw;
const struct r92c_fw_hdr *hdr;
const u_char *ptr;
size_t len;
int ntries, error;
/* Read firmware image from the filesystem. */
RTWN_UNLOCK(sc);
fw = firmware_get(sc->fwname);
RTWN_LOCK(sc);
if (fw == NULL) {
device_printf(sc->sc_dev,
"failed loadfirmware of file %s\n", sc->fwname);
return (ENOENT);
}
len = fw->datasize;
if (len < sizeof(*hdr) || len > sc->fwsize_limit) {
device_printf(sc->sc_dev, "wrong firmware size (%zu)\n", len);
error = EINVAL;
goto fail;
}
ptr = fw->data;
hdr = (const struct r92c_fw_hdr *)ptr;
/* Check if there is a valid FW header and skip it. */
if ((le16toh(hdr->signature) >> 4) == sc->fwsig) {
sc->fwver = le16toh(hdr->version);
RTWN_DPRINTF(sc, RTWN_DEBUG_FIRMWARE,
"FW V%u.%u %02u-%02u %02u:%02u\n",
le16toh(hdr->version), le16toh(hdr->subversion),
hdr->month, hdr->date, hdr->hour, hdr->minute);
ptr += sizeof(*hdr);
len -= sizeof(*hdr);
}
if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL) {
rtwn_write_1(sc, R92C_MCUFWDL, 0);
rtwn_fw_reset(sc, RTWN_FW_RESET_DOWNLOAD);
}
/* Enable firmware download. */
rtwn_fw_download_enable(sc, 1);
error = 0; /* compiler warning */
for (ntries = 0; ntries < 3; ntries++) {
const u_char *curr_ptr = ptr;
const int maxpages = len / R92C_FW_PAGE_SIZE;
int page;
/* Reset the FWDL checksum. */
rtwn_setbits_1(sc, R92C_MCUFWDL, 0, R92C_MCUFWDL_CHKSUM_RPT);
for (page = 0; page < maxpages; page++) {
error = rtwn_fw_loadpage(sc, page, curr_ptr,
R92C_FW_PAGE_SIZE);
if (error != 0)
break;
curr_ptr += R92C_FW_PAGE_SIZE;
}
if (page != maxpages)
continue;
if (len % R92C_FW_PAGE_SIZE != 0) {
error = rtwn_fw_loadpage(sc, page, curr_ptr,
len % R92C_FW_PAGE_SIZE);
if (error != 0)
continue;
}
/* Wait for checksum report. */
error = rtwn_fw_checksum_report(sc);
if (error == 0)
break;
}
if (ntries == 3) {
device_printf(sc->sc_dev,
"%s: failed to upload firmware %s (error %d)\n",
__func__, sc->fwname, error);
goto fail;
}
/* Disable firmware download. */
rtwn_fw_download_enable(sc, 0);
rtwn_setbits_4(sc, R92C_MCUFWDL, R92C_MCUFWDL_WINTINI_RDY,
R92C_MCUFWDL_RDY);
rtwn_fw_reset(sc, RTWN_FW_RESET_CHECKSUM);
/* Wait for firmware readiness. */
for (ntries = 0; ntries < 20; ntries++) {
if (rtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
break;
rtwn_delay(sc, 10000);
}
if (ntries == 20) {
device_printf(sc->sc_dev,
"timeout waiting for firmware readiness\n");
error = ETIMEDOUT;
goto fail;
}
fail:
firmware_put(fw, FIRMWARE_UNLOAD);
return (error);
}
#endif

View File

@ -0,0 +1,59 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef IF_RTWN_FW_H
#define IF_RTWN_FW_H
/*
* Firmware base address.
*/
#define R92C_FW_START_ADDR 0x1000
#define R92C_FW_PAGE_SIZE 4096
#define R92C_FW_MAX_BLOCK_SIZE 196
/*
* Firmware image header.
*/
struct r92c_fw_hdr {
/* QWORD0 */
uint16_t signature;
uint8_t category;
uint8_t function;
uint16_t version;
uint16_t subversion;
/* QWORD1 */
uint8_t month;
uint8_t date;
uint8_t hour;
uint8_t minute;
uint16_t ramcodesize;
uint16_t reserved2;
/* QWORD2 */
uint32_t svnidx;
uint32_t reserved3;
/* QWORD3 */
uint32_t reserved4;
uint32_t reserved5;
} __packed;
int rtwn_load_firmware(struct rtwn_softc *);
#endif /* IF_RTWN_FW_H */

View File

@ -0,0 +1,69 @@
/*-
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_NOP_H
#define IF_RTWN_NOP_H
static __inline void
rtwn_nop_softc(struct rtwn_softc *sc)
{
}
static __inline int
rtwn_nop_int_softc(struct rtwn_softc *sc)
{
return (0);
}
static __inline int
rtwn_nop_int_softc_mbuf(struct rtwn_softc *sc, struct mbuf *m)
{
return (0);
}
static __inline void
rtwn_nop_softc_int(struct rtwn_softc *sc, int id)
{
}
static __inline void
rtwn_nop_softc_uint32(struct rtwn_softc *sc, uint32_t reg)
{
}
static __inline void
rtwn_nop_softc_chan(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
}
static __inline void
rtwn_nop_softc_vap(struct rtwn_softc *sc, struct ieee80211vap *vap)
{
}
static __inline void
rtwn_nop_softc_uint8_int(struct rtwn_softc *sc, uint8_t *buf, int len)
{
}
static __inline void
rtwn_nop_void_int(void *buf, int is5ghz)
{
}
#endif /* IF_RTWN_NOP_H */

View File

@ -0,0 +1,94 @@
/* $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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_RIDX_H
#define IF_RTWN_RIDX_H
/* HW rate indices. */
#define RTWN_RIDX_CCK1 0
#define RTWN_RIDX_CCK2 1
#define RTWN_RIDX_CCK55 2
#define RTWN_RIDX_CCK11 3
#define RTWN_RIDX_OFDM6 4
#define RTWN_RIDX_OFDM9 5
#define RTWN_RIDX_OFDM12 6
#define RTWN_RIDX_OFDM18 7
#define RTWN_RIDX_OFDM24 8
#define RTWN_RIDX_OFDM36 9
#define RTWN_RIDX_OFDM48 10
#define RTWN_RIDX_OFDM54 11
#define RTWN_RIDX_MCS(i) (12 + (i))
#define RTWN_RIDX_COUNT 28
#define RTWN_RIDX_UNKNOWN (uint8_t)-1
#define RTWN_RATE_IS_CCK(rate) ((rate) <= RTWN_RIDX_CCK11)
#define RTWN_RATE_IS_OFDM(rate) \
((rate) >= RTWN_RIDX_OFDM6 && (rate) != RTWN_RIDX_UNKNOWN)
static const uint8_t ridx2rate[] =
{ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
static __inline uint8_t
rate2ridx(uint8_t rate)
{
if (rate & IEEE80211_RATE_MCS) {
/* 11n rates start at idx 12 */
return ((rate & 0xf) + 12);
}
switch (rate) {
/* 11g */
case 12: return 4;
case 18: return 5;
case 24: return 6;
case 36: return 7;
case 48: return 8;
case 72: return 9;
case 96: return 10;
case 108: return 11;
/* 11b */
case 2: return 0;
case 4: return 1;
case 11: return 2;
case 22: return 3;
default: return RTWN_RIDX_UNKNOWN;
}
}
/* XXX move to net80211 */
static __inline__ uint8_t
rtwn_ctl_mcsrate(const struct ieee80211_rate_table *rt, uint8_t ridx)
{
uint8_t cix, rate;
/* Check if we are using MCS rate. */
KASSERT(ridx >= RTWN_RIDX_MCS(0) && ridx != RTWN_RIDX_UNKNOWN,
("bad mcs rate index %d", ridx));
rate = (ridx - RTWN_RIDX_MCS(0)) | IEEE80211_RATE_MCS;
cix = rt->info[rt->rateCodeToIndex[rate]].ctlRateIndex;
KASSERT(cix != (uint8_t)-1, ("rate %d (%d) has no info", rate, ridx));
return rt->info[cix].dot11Rate;
}
#endif /* IF_RTWN_RIDX_H */

View File

@ -0,0 +1,466 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <net/if.h>
#include <net/if_var.h>
#include <net/ethernet.h>
#include <net/if_dl.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/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
void
rtwn_get_rates(struct rtwn_softc *sc, const struct ieee80211_rateset *rs,
const struct ieee80211_htrateset *rs_ht, uint32_t *rates_p,
int *maxrate_p, int basic_rates)
{
uint32_t rates;
uint8_t ridx;
int i, maxrate;
/* Get rates mask. */
rates = 0;
maxrate = 0;
/* This is for 11bg */
for (i = 0; i < rs->rs_nrates; i++) {
/* Convert 802.11 rate to HW rate index. */
ridx = rate2ridx(IEEE80211_RV(rs->rs_rates[i]));
if (ridx == RTWN_RIDX_UNKNOWN) /* Unknown rate, skip. */
continue;
if (((rs->rs_rates[i] & IEEE80211_RATE_BASIC) != 0) ||
!basic_rates) {
rates |= 1 << ridx;
if (ridx > maxrate)
maxrate = ridx;
}
}
/* If we're doing 11n, enable 11n rates */
if (rs_ht != NULL && !basic_rates) {
for (i = 0; i < rs_ht->rs_nrates; i++) {
if ((rs_ht->rs_rates[i] & 0x7f) > 0xf)
continue;
/* 11n rates start at index 12 */
ridx = RTWN_RIDX_MCS((rs_ht->rs_rates[i]) & 0xf);
rates |= (1 << ridx);
/* Guard against the rate table being oddly ordered */
if (ridx > maxrate)
maxrate = ridx;
}
}
RTWN_DPRINTF(sc, RTWN_DEBUG_RA,
"%s: rates 0x%08X, maxrate %d\n", __func__, rates, maxrate);
if (rates_p != NULL)
*rates_p = rates;
if (maxrate_p != NULL)
*maxrate_p = maxrate;
}
void
rtwn_set_basicrates(struct rtwn_softc *sc, uint32_t rates)
{
RTWN_DPRINTF(sc, RTWN_DEBUG_RA, "%s: rates 0x%08X\n", __func__, rates);
rtwn_setbits_4(sc, R92C_RRSR, R92C_RRSR_RATE_BITMAP_M, rates);
}
static void
rtwn_update_avgrssi(struct rtwn_softc *sc, struct rtwn_node *un, int rate)
{
int pwdb;
/* Convert antenna signal to percentage. */
if (un->last_rssi <= -100 || un->last_rssi >= 20)
pwdb = 0;
else if (un->last_rssi >= 0)
pwdb = 100;
else
pwdb = 100 + un->last_rssi;
if (RTWN_RATE_IS_CCK(rate)) {
/* CCK gain is smaller than OFDM/MCS gain. */
pwdb += 6;
if (pwdb > 100)
pwdb = 100;
if (pwdb <= 14)
pwdb -= 4;
else if (pwdb <= 26)
pwdb -= 8;
else if (pwdb <= 34)
pwdb -= 6;
else if (pwdb <= 42)
pwdb -= 2;
}
if (un->avg_pwdb == -1) /* Init. */
un->avg_pwdb = pwdb;
else if (un->avg_pwdb < pwdb)
un->avg_pwdb = ((un->avg_pwdb * 19 + pwdb) / 20) + 1;
else
un->avg_pwdb = ((un->avg_pwdb * 19 + pwdb) / 20);
RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI,
"MACID %d, PWDB %d, EMA %d\n", un->id, pwdb, un->avg_pwdb);
}
static int8_t
rtwn_get_rssi(struct rtwn_softc *sc, int rate, void *physt)
{
int8_t rssi;
if (RTWN_RATE_IS_CCK(rate))
rssi = rtwn_get_rssi_cck(sc, physt);
else /* OFDM/HT. */
rssi = rtwn_get_rssi_ofdm(sc, physt);
return (rssi);
}
static uint32_t
rtwn_get_tsf_low(struct rtwn_softc *sc, int id)
{
return (rtwn_read_4(sc, R92C_TSFTR(id)));
}
static uint32_t
rtwn_get_tsf_high(struct rtwn_softc *sc, int id)
{
return (rtwn_read_4(sc, R92C_TSFTR(id) + 4));
}
static void
rtwn_get_tsf(struct rtwn_softc *sc, uint64_t *buf, int id)
{
/* NB: we cannot read it at once. */
*buf = rtwn_get_tsf_high(sc, id);
*buf <<= 32;
*buf += rtwn_get_tsf_low(sc, id);
}
struct ieee80211_node *
rtwn_rx_common(struct rtwn_softc *sc, struct mbuf *m, void *desc,
int8_t *rssi)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct ieee80211_frame_min *wh;
struct rtwn_node *un;
struct r92c_rx_stat *stat;
uint32_t rxdw0, rxdw3;
int cipher, infosz, pktlen, rate, shift;
stat = desc;
rxdw0 = le32toh(stat->rxdw0);
rxdw3 = le32toh(stat->rxdw3);
cipher = MS(rxdw0, R92C_RXDW0_CIPHER);
infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
shift = MS(rxdw0, R92C_RXDW0_SHIFT);
rate = MS(rxdw3, R92C_RXDW3_RATE);
wh = (struct ieee80211_frame_min *)(mtodo(m, shift + infosz));
if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
cipher != R92C_CAM_ALGO_NONE)
m->m_flags |= M_WEP;
if (pktlen >= sizeof(*wh))
ni = ieee80211_find_rxnode(ic, wh);
else
ni = NULL;
un = RTWN_NODE(ni);
/* Get RSSI from PHY status descriptor if present. */
if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
*rssi = rtwn_get_rssi(sc, rate, mtod(m, void *));
RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI, "%s: rssi %d, ridx %d\n",
__func__, *rssi, rate);
sc->last_rssi = *rssi;
if (un != NULL) {
un->last_rssi = *rssi;
/* Update our average RSSI. */
rtwn_update_avgrssi(sc, un, rate);
}
} else
*rssi = (un != NULL) ? un->last_rssi : sc->last_rssi;
if (ieee80211_radiotap_active(ic)) {
struct rtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
int id = RTWN_VAP_ID_INVALID;
if (ni != NULL)
id = RTWN_VAP(ni->ni_vap)->id;
if (id == RTWN_VAP_ID_INVALID)
id = 0;
tap->wr_flags = rtwn_rx_radiotap_flags(sc, desc);
tap->wr_tsft = rtwn_get_tsf_high(sc, id);
if (le32toh(stat->tsf_low) > rtwn_get_tsf_low(sc, id))
tap->wr_tsft--;
tap->wr_tsft = (uint64_t)htole32(tap->wr_tsft) << 32;
tap->wr_tsft += stat->tsf_low;
/* XXX 20/40? */
/* Map HW rate index to 802.11 rate. */
if (rate < RTWN_RIDX_MCS(0))
tap->wr_rate = ridx2rate[rate];
else /* MCS0~15. */
tap->wr_rate = IEEE80211_RATE_MCS | (rate - 12);
tap->wr_dbm_antsignal = *rssi;
tap->wr_dbm_antnoise = RTWN_NOISE_FLOOR;
}
/* Drop PHY descriptor. */
m_adj(m, infosz + shift);
return (ni);
}
void
rtwn_adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype,
const struct ieee80211_rx_stats *rxs,
int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct rtwn_softc *sc = vap->iv_ic->ic_softc;
struct rtwn_vap *uvp = RTWN_VAP(vap);
uint64_t ni_tstamp, curr_tstamp;
uvp->recv_mgmt(ni, m, subtype, rxs, rssi, nf);
if (vap->iv_state == IEEE80211_S_RUN &&
(subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) {
ni_tstamp = le64toh(ni->ni_tstamp.tsf);
RTWN_LOCK(sc);
rtwn_get_tsf(sc, &curr_tstamp, uvp->id);
RTWN_UNLOCK(sc);
if (ni_tstamp >= curr_tstamp)
(void) ieee80211_ibss_merge(ni);
}
}
static uint8_t
rtwn_get_multi_pos(const uint8_t maddr[])
{
uint64_t mask = 0x00004d101df481b4;
uint8_t pos = 0x27; /* initial value */
int i, j;
for (i = 0; i < IEEE80211_ADDR_LEN; i++)
for (j = (i == 0) ? 1 : 0; j < 8; j++)
if ((maddr[i] >> j) & 1)
pos ^= (mask >> (i * 8 + j - 1));
pos &= 0x3f;
return (pos);
}
void
rtwn_set_multi(struct rtwn_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
uint32_t mfilt[2];
RTWN_ASSERT_LOCKED(sc);
/* general structure was copied from ath(4). */
if (ic->ic_allmulti == 0) {
struct ieee80211vap *vap;
struct ifnet *ifp;
struct ifmultiaddr *ifma;
/*
* Merge multicast addresses to form the hardware filter.
*/
mfilt[0] = mfilt[1] = 0;
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
ifp = vap->iv_ifp;
if_maddr_rlock(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
caddr_t dl;
uint8_t pos;
dl = LLADDR((struct sockaddr_dl *)
ifma->ifma_addr);
pos = rtwn_get_multi_pos(dl);
mfilt[pos / 32] |= (1 << (pos % 32));
}
if_maddr_runlock(ifp);
}
} else
mfilt[0] = mfilt[1] = ~0;
rtwn_write_4(sc, R92C_MAR + 0, mfilt[0]);
rtwn_write_4(sc, R92C_MAR + 4, mfilt[1]);
RTWN_DPRINTF(sc, RTWN_DEBUG_STATE, "%s: MC filter %08x:%08x\n",
__func__, mfilt[0], mfilt[1]);
}
static void
rtwn_rxfilter_update_mgt(struct rtwn_softc *sc)
{
uint16_t filter;
filter = 0x7f7f;
if (sc->bcn_vaps == 0) { /* STA and/or MONITOR mode vaps */
filter &= ~(
R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_ASSOC_REQ) |
R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_REASSOC_REQ) |
R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_PROBE_REQ));
}
if (sc->ap_vaps == sc->nvaps - sc->mon_vaps) { /* AP vaps only */
filter &= ~(
R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_ASSOC_RESP) |
R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_REASSOC_RESP));
}
rtwn_write_2(sc, R92C_RXFLTMAP0, filter);
}
void
rtwn_rxfilter_update(struct rtwn_softc *sc)
{
RTWN_ASSERT_LOCKED(sc);
/* Filter for management frames. */
rtwn_rxfilter_update_mgt(sc);
/* Update Rx filter. */
rtwn_set_promisc(sc);
}
void
rtwn_rxfilter_init(struct rtwn_softc *sc)
{
RTWN_ASSERT_LOCKED(sc);
/* Setup multicast filter. */
rtwn_set_multi(sc);
/* Reject all control frames. */
rtwn_write_2(sc, R92C_RXFLTMAP1, 0x0000);
/* Reject all data frames. */
rtwn_write_2(sc, R92C_RXFLTMAP2, 0x0000);
/* Append generic Rx filter bits. */
sc->rcr |= R92C_RCR_AM | R92C_RCR_AB | R92C_RCR_APM |
R92C_RCR_HTC_LOC_CTRL | R92C_RCR_APP_PHYSTS |
R92C_RCR_APP_ICV | R92C_RCR_APP_MIC;
/* Update dynamic Rx filter parts. */
rtwn_rxfilter_update(sc);
}
void
rtwn_rxfilter_set(struct rtwn_softc *sc)
{
if (!(sc->sc_flags & RTWN_RCR_LOCKED))
rtwn_write_4(sc, R92C_RCR, sc->rcr);
}
void
rtwn_set_rx_bssid_all(struct rtwn_softc *sc, int enable)
{
if (enable)
sc->rcr &= ~R92C_RCR_CBSSID_BCN;
else
sc->rcr |= R92C_RCR_CBSSID_BCN;
rtwn_rxfilter_set(sc);
}
void
rtwn_set_promisc(struct rtwn_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
uint32_t mask_all, mask_min;
RTWN_ASSERT_LOCKED(sc);
mask_all = R92C_RCR_ACF | R92C_RCR_ADF | R92C_RCR_AMF | R92C_RCR_AAP;
mask_min = R92C_RCR_APM;
if (sc->bcn_vaps == 0)
mask_min |= R92C_RCR_CBSSID_BCN;
if (sc->ap_vaps == 0)
mask_min |= R92C_RCR_CBSSID_DATA;
if (ic->ic_promisc == 0 && sc->mon_vaps == 0) {
if (sc->bcn_vaps != 0)
mask_all |= R92C_RCR_CBSSID_BCN;
if (sc->ap_vaps != 0) /* for Null data frames */
mask_all |= R92C_RCR_CBSSID_DATA;
sc->rcr &= ~mask_all;
sc->rcr |= mask_min;
} else {
sc->rcr &= ~mask_min;
sc->rcr |= mask_all;
}
rtwn_rxfilter_set(sc);
}

View File

@ -0,0 +1,39 @@
/*-
* 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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_RX_H
#define IF_RTWN_RX_H
#define RTWN_NOISE_FLOOR -95
void rtwn_get_rates(struct rtwn_softc *, const struct ieee80211_rateset *,
const struct ieee80211_htrateset *, uint32_t *, int *, int);
void rtwn_set_basicrates(struct rtwn_softc *, uint32_t);
struct ieee80211_node * rtwn_rx_common(struct rtwn_softc *, struct mbuf *,
void *, int8_t *);
void rtwn_adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
const struct ieee80211_rx_stats *, int, int);
void rtwn_set_multi(struct rtwn_softc *);
void rtwn_rxfilter_update(struct rtwn_softc *);
void rtwn_rxfilter_init(struct rtwn_softc *);
void rtwn_rxfilter_set(struct rtwn_softc *);
void rtwn_set_rx_bssid_all(struct rtwn_softc *, int);
void rtwn_set_promisc(struct rtwn_softc *);
#endif /* IF_RTWN_RX_H */

View File

@ -0,0 +1,124 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <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/if_rtwn_task.h>
static void
rtwn_cmdq_cb(void *arg, int pending)
{
struct rtwn_softc *sc = arg;
struct rtwn_cmdq *item;
/*
* Device must be powered on (via rtwn_power_on())
* before any command may be sent.
*/
RTWN_LOCK(sc);
if (!(sc->sc_flags & RTWN_RUNNING)) {
RTWN_UNLOCK(sc);
return;
}
RTWN_CMDQ_LOCK(sc);
while (sc->cmdq[sc->cmdq_first].func != NULL) {
item = &sc->cmdq[sc->cmdq_first];
sc->cmdq_first = (sc->cmdq_first + 1) % RTWN_CMDQ_SIZE;
RTWN_CMDQ_UNLOCK(sc);
item->func(sc, &item->data);
RTWN_CMDQ_LOCK(sc);
memset(item, 0, sizeof (*item));
}
RTWN_CMDQ_UNLOCK(sc);
RTWN_UNLOCK(sc);
}
void
rtwn_cmdq_init(struct rtwn_softc *sc)
{
RTWN_CMDQ_LOCK_INIT(sc);
TASK_INIT(&sc->cmdq_task, 0, rtwn_cmdq_cb, sc);
}
void
rtwn_cmdq_destroy(struct rtwn_softc *sc)
{
if (RTWN_CMDQ_LOCK_INITIALIZED(sc))
RTWN_CMDQ_LOCK_DESTROY(sc);
}
int
rtwn_cmd_sleepable(struct rtwn_softc *sc, const void *ptr, size_t len,
CMD_FUNC_PROTO)
{
struct ieee80211com *ic = &sc->sc_ic;
KASSERT(len <= sizeof(union sec_param), ("buffer overflow"));
RTWN_CMDQ_LOCK(sc);
if (sc->sc_detached) {
RTWN_CMDQ_UNLOCK(sc);
return (ESHUTDOWN);
}
if (sc->cmdq[sc->cmdq_last].func != NULL) {
device_printf(sc->sc_dev, "%s: cmdq overflow\n", __func__);
RTWN_CMDQ_UNLOCK(sc);
return (EAGAIN);
}
if (ptr != NULL)
memcpy(&sc->cmdq[sc->cmdq_last].data, ptr, len);
sc->cmdq[sc->cmdq_last].func = func;
sc->cmdq_last = (sc->cmdq_last + 1) % RTWN_CMDQ_SIZE;
RTWN_CMDQ_UNLOCK(sc);
ieee80211_runtask(ic, &sc->cmdq_task);
return (0);
}

View File

@ -0,0 +1,27 @@
/*-
* 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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_TASK_H
#define IF_RTWN_TASK_H
void rtwn_cmdq_init(struct rtwn_softc *);
void rtwn_cmdq_destroy(struct rtwn_softc *);
int rtwn_cmd_sleepable(struct rtwn_softc *, const void *, size_t,
CMD_FUNC_PROTO);
#endif /* IF_RTWN_TASK_H */

View File

@ -0,0 +1,348 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <net/if.h>
#include <net/if_var.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>
#ifdef IEEE80211_SUPPORT_SUPERG
#include <net80211/ieee80211_superg.h>
#endif
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/if_rtwn_beacon.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/if_rtwn_ridx.h>
#include <dev/rtwn/if_rtwn_tx.h>
void
rtwn_drain_mbufq(struct rtwn_softc *sc)
{
struct mbuf *m;
struct ieee80211_node *ni;
RTWN_ASSERT_LOCKED(sc);
while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
ieee80211_free_node(ni);
m_freem(m);
}
}
#ifdef IEEE80211_SUPPORT_SUPERG
void
rtwn_ff_flush_all(struct rtwn_softc *sc, union sec_param *data)
{
struct ieee80211com *ic = &sc->sc_ic;
RTWN_UNLOCK(sc);
ieee80211_ff_flush_all(ic);
RTWN_LOCK(sc);
}
#endif
static uint8_t
rtwn_get_cipher(u_int ic_cipher)
{
uint8_t cipher;
switch (ic_cipher) {
case IEEE80211_CIPHER_NONE:
cipher = RTWN_TXDW1_CIPHER_NONE;
break;
case IEEE80211_CIPHER_WEP:
case IEEE80211_CIPHER_TKIP:
cipher = RTWN_TXDW1_CIPHER_RC4;
break;
case IEEE80211_CIPHER_AES_CCM:
cipher = RTWN_TXDW1_CIPHER_AES;
break;
default:
KASSERT(0, ("%s: unknown cipher %d\n", __func__,
ic_cipher));
return (RTWN_TXDW1_CIPHER_SM4);
}
return (cipher);
}
static int
rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m)
{
const struct ieee80211_txparam *tp;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_key *k = NULL;
struct ieee80211_channel *chan;
struct ieee80211_frame *wh;
struct rtwn_tx_desc_common *txd;
struct rtwn_tx_buf buf;
uint8_t rate, ridx, type;
u_int cipher;
int ismcast, maxretry;
RTWN_ASSERT_LOCKED(sc);
wh = mtod(m, struct ieee80211_frame *);
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
ni->ni_chan : ic->ic_curchan;
tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
maxretry = tp->maxretry;
/* Choose a TX rate index. */
if (type == IEEE80211_FC0_TYPE_MGT)
rate = tp->mgmtrate;
else if (ismcast)
rate = tp->mcastrate;
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = tp->ucastrate;
else if (m->m_flags & M_EAPOL)
rate = tp->mgmtrate;
else {
if (sc->sc_ratectl == RTWN_RATECTL_NET80211) {
/* XXX pass pktlen */
(void) ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
} else {
if (ni->ni_flags & IEEE80211_NODE_HT)
rate = IEEE80211_RATE_MCS | 0x4; /* MCS4 */
else if (ic->ic_curmode != IEEE80211_MODE_11B)
rate = ridx2rate[RTWN_RIDX_OFDM36];
else
rate = ridx2rate[RTWN_RIDX_CCK55];
}
}
ridx = rate2ridx(rate);
cipher = IEEE80211_CIPHER_NONE;
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_crypto_encap(ni, m);
if (k == NULL) {
device_printf(sc->sc_dev,
"ieee80211_crypto_encap returns NULL.\n");
return (ENOBUFS);
}
if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT))
cipher = k->wk_cipher->ic_cipher;
/* in case packet header moved, reset pointer */
wh = mtod(m, struct ieee80211_frame *);
}
/* Fill Tx descriptor. */
txd = (struct rtwn_tx_desc_common *)&buf;
memset(txd, 0, sc->txdesc_len);
txd->txdw1 = htole32(SM(RTWN_TXDW1_CIPHER, rtwn_get_cipher(cipher)));
rtwn_fill_tx_desc(sc, ni, m, txd, ridx, maxretry);
if (ieee80211_radiotap_active_vap(vap)) {
struct rtwn_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = rtwn_tx_radiotap_flags(sc, txd);
if (k != NULL)
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
ieee80211_radiotap_tx(vap, m);
}
return (rtwn_tx_start(sc, ni, m, (uint8_t *)txd, type, 0));
}
static int
rtwn_tx_raw(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m, const struct ieee80211_bpf_params *params)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_key *k = NULL;
struct ieee80211_frame *wh;
struct rtwn_tx_desc_common *txd;
struct rtwn_tx_buf buf;
uint8_t type;
u_int cipher;
/* Encrypt the frame if need be. */
cipher = IEEE80211_CIPHER_NONE;
if (params->ibp_flags & IEEE80211_BPF_CRYPTO) {
/* Retrieve key for TX. */
k = ieee80211_crypto_encap(ni, m);
if (k == NULL) {
device_printf(sc->sc_dev,
"ieee80211_crypto_encap returns NULL.\n");
return (ENOBUFS);
}
if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT))
cipher = k->wk_cipher->ic_cipher;
}
wh = mtod(m, struct ieee80211_frame *);
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
/* Fill Tx descriptor. */
txd = (struct rtwn_tx_desc_common *)&buf;
memset(txd, 0, sc->txdesc_len);
txd->txdw1 = htole32(SM(RTWN_TXDW1_CIPHER, rtwn_get_cipher(cipher)));
rtwn_fill_tx_desc_raw(sc, ni, m, txd, params);
if (ieee80211_radiotap_active_vap(vap)) {
struct rtwn_tx_radiotap_header *tap = &sc->sc_txtap;
tap->wt_flags = rtwn_tx_radiotap_flags(sc, txd);
if (k != NULL)
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
ieee80211_radiotap_tx(vap, m);
}
return (rtwn_tx_start(sc, ni, m, (uint8_t *)txd, type, 0));
}
int
rtwn_transmit(struct ieee80211com *ic, struct mbuf *m)
{
struct rtwn_softc *sc = ic->ic_softc;
int error;
RTWN_LOCK(sc);
if ((sc->sc_flags & RTWN_RUNNING) == 0) {
RTWN_UNLOCK(sc);
return (ENXIO);
}
error = mbufq_enqueue(&sc->sc_snd, m);
if (error) {
RTWN_UNLOCK(sc);
return (error);
}
rtwn_start(sc);
RTWN_UNLOCK(sc);
return (0);
}
void
rtwn_start(struct rtwn_softc *sc)
{
struct ieee80211_node *ni;
struct mbuf *m;
RTWN_ASSERT_LOCKED(sc);
while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
if (sc->qfullmsk != 0) {
mbufq_prepend(&sc->sc_snd, m);
break;
}
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT,
"%s: called; m %p, ni %p\n", __func__, m, ni);
if (rtwn_tx_data(sc, ni, m) != 0) {
if_inc_counter(ni->ni_vap->iv_ifp,
IFCOUNTER_OERRORS, 1);
m_freem(m);
#ifdef D4054
ieee80211_tx_watchdog_refresh(ni->ni_ic, -1, 0);
#endif
ieee80211_free_node(ni);
break;
}
}
}
int
rtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
struct rtwn_softc *sc = ic->ic_softc;
int error;
RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT, "%s: called; m %p, ni %p\n",
__func__, m, ni);
/* prevent management frames from being sent if we're not ready */
RTWN_LOCK(sc);
if (!(sc->sc_flags & RTWN_RUNNING)) {
error = ENETDOWN;
goto end;
}
if (sc->qfullmsk != 0) {
error = ENOBUFS;
goto end;
}
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
* precisely how to send the frame.
*/
error = rtwn_tx_data(sc, ni, m);
} else {
/*
* Caller supplied explicit parameters to use in
* sending the frame.
*/
error = rtwn_tx_raw(sc, ni, m, params);
}
end:
if (error != 0) {
if (m->m_flags & M_TXCB)
ieee80211_process_callback(ni, m, 1);
m_freem(m);
}
RTWN_UNLOCK(sc);
return (error);
}

View File

@ -0,0 +1,31 @@
/*-
* 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.
*
* $FreeBSD$
*/
#ifndef IF_RTWN_TX_H
#define IF_RTWN_TX_H
void rtwn_drain_mbufq(struct rtwn_softc *);
#ifdef IEEE80211_SUPPORT_SUPERG
void rtwn_ff_flush_all(struct rtwn_softc *, union sec_param *);
#endif
int rtwn_transmit(struct ieee80211com *, struct mbuf *);
void rtwn_start(struct rtwn_softc *);
int rtwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
#endif /* IF_RTWN_TX_H */

View File

@ -0,0 +1,118 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#define R92C_MIN_TX_PWR 0x00
#define R92C_MAX_TX_PWR 0x3f
#define R92C_H2C_NBOX 4
/* Common part of Tx descriptor (named only!). */
struct rtwn_tx_desc_common {
uint16_t pktlen;
uint8_t offset;
uint8_t flags0;
#define RTWN_FLAGS0_OWN 0x80
uint32_t txdw1;
/* NB: qsel is shared too; however, it looks better at the lower level */
#define RTWN_TXDW1_CIPHER_M 0x00c00000
#define RTWN_TXDW1_CIPHER_S 22
#define RTWN_TXDW1_CIPHER_NONE 0
#define RTWN_TXDW1_CIPHER_RC4 1
#define RTWN_TXDW1_CIPHER_SM4 2
#define RTWN_TXDW1_CIPHER_AES 3
uint32_t reserved[5];
union txdw7_shared {
uint16_t usb_checksum;
uint16_t pci_txbufsize;
} txdw7;
} __packed __attribute__((aligned(4)));
/*
* Macros to access subfields in registers.
*/
/* Mask and Shift (getter). */
#define MS(val, field) \
(((val) & field##_M) >> field##_S)
/* Shift and Mask (setter). */
#define SM(field, val) \
(((val) << field##_S) & field##_M)
/* Rewrite. */
#define RW(var, field, val) \
(((var) & ~field##_M) | SM(field, val))
#define RTWN_MAX_CONDITIONS 3
/*
* Structure for MAC initialization values.
*/
struct rtwn_mac_prog {
uint16_t reg;
uint8_t val;
};
/*
* Structure for baseband initialization values.
*/
struct rtwn_bb_prog {
int count;
const uint16_t *reg;
const uint32_t *val;
const uint8_t cond[RTWN_MAX_CONDITIONS];
const struct rtwn_bb_prog *next;
};
struct rtwn_agc_prog {
int count;
const uint32_t *val;
const uint8_t cond[RTWN_MAX_CONDITIONS];
const struct rtwn_agc_prog *next;
};
/*
* Structure for RF initialization values.
*/
struct rtwn_rf_prog {
int count;
const uint8_t *reg;
const uint32_t *val;
const uint8_t cond[RTWN_MAX_CONDITIONS];
const struct rtwn_rf_prog *next;
};
/* XXX move to net80211. */
static __inline int
rtwn_chan2centieee(const struct ieee80211_channel *c)
{
int chan;
chan = c->ic_ieee;
if (c->ic_extieee != 0)
chan = (chan + c->ic_extieee) / 2;
return (chan);
}

View File

@ -0,0 +1,624 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef IF_RTWNVAR_H
#define IF_RTWNVAR_H
#include <rtems/bsd/local/opt_rtwn.h>
#define RTWN_TX_DESC_SIZE 64
#define RTWN_TXBUFSZ (16 * 1024)
#define RTWN_BCN_MAX_SIZE 512
#define RTWN_CAM_ENTRY_LIMIT 64
#define RTWN_MACID_BC 1 /* Broadcast. */
#define RTWN_MACID_UNDEFINED 0x7fff
#define RTWN_MACID_VALID 0x8000
#define RTWN_MACID_LIMIT 128
#define RTWN_TX_TIMEOUT 5000 /* ms */
#define RTWN_MAX_EPOUT 4
#define RTWN_PORT_COUNT 2
#define RTWN_LED_LINK 0
#define RTWN_LED_DATA 1
struct rtwn_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
uint64_t wr_tsft;
uint8_t wr_flags;
uint8_t wr_rate;
uint16_t wr_chan_freq;
uint16_t wr_chan_flags;
int8_t wr_dbm_antsignal;
int8_t wr_dbm_antnoise;
} __packed __aligned(8);
#define RTWN_RX_RADIOTAP_PRESENT \
(1 << IEEE80211_RADIOTAP_TSFT | \
1 << IEEE80211_RADIOTAP_FLAGS | \
1 << IEEE80211_RADIOTAP_RATE | \
1 << IEEE80211_RADIOTAP_CHANNEL | \
1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL | \
1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)
struct rtwn_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
uint8_t wt_flags;
uint16_t wt_chan_freq;
uint16_t wt_chan_flags;
} __packed __aligned(8);
#define RTWN_TX_RADIOTAP_PRESENT \
(1 << IEEE80211_RADIOTAP_FLAGS | \
1 << IEEE80211_RADIOTAP_CHANNEL)
struct rtwn_tx_buf {
uint8_t txd[RTWN_TX_DESC_SIZE];
} __attribute__((aligned(4)));
struct rtwn_softc;
union sec_param {
struct ieee80211_key key;
int macid;
};
#define CMD_FUNC_PROTO void (*func)(struct rtwn_softc *, \
union sec_param *)
struct rtwn_cmdq {
union sec_param data;
CMD_FUNC_PROTO;
};
#define RTWN_CMDQ_SIZE 16
struct rtwn_node {
struct ieee80211_node ni; /* must be the first */
int id;
int8_t last_rssi;
int avg_pwdb;
};
#define RTWN_NODE(ni) ((struct rtwn_node *)(ni))
struct rtwn_vap {
struct ieee80211vap vap;
int id;
#define RTWN_VAP_ID_INVALID -1
int curr_mode;
struct rtwn_tx_buf bcn_desc;
struct mbuf *bcn_mbuf;
struct timeout_task tx_beacon_csa;
struct callout tsf_sync_adhoc;
struct task tsf_sync_adhoc_task;
const struct ieee80211_key *keys[IEEE80211_WEP_NKID];
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
void (*recv_mgmt)(struct ieee80211_node *,
struct mbuf *, int,
const struct ieee80211_rx_stats *,
int, int);
};
#define RTWN_VAP(vap) ((struct rtwn_vap *)(vap))
/*
* Rx data types.
*/
enum {
RTWN_RX_DATA,
RTWN_RX_TX_REPORT,
RTWN_RX_OTHER
};
/*
* Firmware reset reasons.
*/
enum {
RTWN_FW_RESET_DOWNLOAD,
RTWN_FW_RESET_CHECKSUM,
RTWN_FW_RESET_SHUTDOWN
};
/*
* Rate control algorithm selection.
*/
enum {
RTWN_RATECTL_NONE,
RTWN_RATECTL_NET80211,
RTWN_RATECTL_FW,
RTWN_RATECTL_MAX
};
/*
* Control h/w crypto usage.
*/
enum {
RTWN_CRYPTO_SW,
RTWN_CRYPTO_PAIR,
RTWN_CRYPTO_FULL,
RTWN_CRYPTO_MAX,
};
struct rtwn_softc {
struct ieee80211com sc_ic;
struct mbufq sc_snd;
device_t sc_dev;
#if 1
int sc_ht40;
#endif
uint32_t sc_debug;
int sc_hwcrypto;
int sc_ratectl_sysctl;
int sc_ratectl;
uint8_t sc_detached;
uint8_t sc_flags;
/* Device flags */
#define RTWN_FLAG_CCK_HIPWR 0x01
#define RTWN_FLAG_EXT_HDR 0x02
#define RTWN_FLAG_CAM_FIXED 0x04
/* Driver state */
#define RTWN_STARTED 0x08
#define RTWN_RUNNING 0x10
#define RTWN_FW_LOADED 0x20
#define RTWN_TEMP_MEASURED 0x40
#define RTWN_RCR_LOCKED 0x80
#define RTWN_CHIP_HAS_BCNQ1(_sc) \
((_sc)->bcn_status_reg[0] != (_sc)->bcn_status_reg[1])
void *sc_priv;
const char *name;
int sc_ant;
int8_t last_rssi;
uint8_t thcal_temp;
int cur_bcnq_id;
int nvaps;
int ap_vaps;
int bcn_vaps;
int mon_vaps;
int vaps_running;
int monvaps_running;
uint16_t next_rom_addr;
uint8_t keys_bmap[howmany(RTWN_CAM_ENTRY_LIMIT, NBBY)];
struct rtwn_vap *vaps[RTWN_PORT_COUNT];
struct ieee80211_node *node_list[RTWN_MACID_LIMIT];
struct mtx nt_mtx;
struct callout sc_calib_to;
struct callout sc_pwrmode_init;
#ifndef D4054
struct callout sc_watchdog_to;
int sc_tx_timer;
#endif
struct mtx sc_mtx;
struct rtwn_cmdq cmdq[RTWN_CMDQ_SIZE];
struct mtx cmdq_mtx;
struct task cmdq_task;
uint8_t cmdq_first;
uint8_t cmdq_last;
struct wmeParams cap_wmeParams[WME_NUM_AC];
struct rtwn_rx_radiotap_header sc_rxtap;
struct rtwn_tx_radiotap_header sc_txtap;
int ntxchains;
int nrxchains;
int ledlink;
uint8_t thermal_meter;
int sc_tx_n_active;
uint8_t qfullmsk;
/* Firmware-specific */
const char *fwname;
uint16_t fwver;
uint16_t fwsig;
int fwcur;
void (*sc_node_free)(struct ieee80211_node *);
void (*sc_scan_curchan)(struct ieee80211_scan_state *,
unsigned long);
/* Interface-specific. */
int (*sc_write_1)(struct rtwn_softc *, uint16_t,
uint8_t);
int (*sc_write_2)(struct rtwn_softc *, uint16_t,
uint16_t);
int (*sc_write_4)(struct rtwn_softc *, uint16_t,
uint32_t);
uint8_t (*sc_read_1)(struct rtwn_softc *, uint16_t);
uint16_t (*sc_read_2)(struct rtwn_softc *, uint16_t);
uint32_t (*sc_read_4)(struct rtwn_softc *, uint16_t);
/* XXX eliminate */
void (*sc_delay)(struct rtwn_softc *, int);
int (*sc_tx_start)(struct rtwn_softc *,
struct ieee80211_node *, struct mbuf *, uint8_t *,
uint8_t, int);
void (*sc_start_xfers)(struct rtwn_softc *);
void (*sc_reset_lists)(struct rtwn_softc *,
struct ieee80211vap *);
void (*sc_abort_xfers)(struct rtwn_softc *);
int (*sc_fw_write_block)(struct rtwn_softc *,
const uint8_t *, uint16_t, int);
uint16_t (*sc_get_qmap)(struct rtwn_softc *);
void (*sc_set_desc_addr)(struct rtwn_softc *);
void (*sc_drop_incorrect_tx)(struct rtwn_softc *);
void (*sc_beacon_update_begin)(struct rtwn_softc *,
struct ieee80211vap *);
void (*sc_beacon_update_end)(struct rtwn_softc *,
struct ieee80211vap *);
void (*sc_beacon_unload)(struct rtwn_softc *, int);
/* XXX drop checks for PCIe? */
int bcn_check_interval;
/* Device-specific. */
uint32_t (*sc_rf_read)(struct rtwn_softc *, int, uint8_t);
void (*sc_rf_write)(struct rtwn_softc *, int, uint8_t,
uint32_t);
int (*sc_check_condition)(struct rtwn_softc *,
const uint8_t[]);
void (*sc_efuse_postread)(struct rtwn_softc *);
void (*sc_parse_rom)(struct rtwn_softc *, uint8_t *);
void (*sc_set_led)(struct rtwn_softc *, int, int);
int (*sc_power_on)(struct rtwn_softc *);
void (*sc_power_off)(struct rtwn_softc *);
#ifndef RTWN_WITHOUT_UCODE
void (*sc_fw_reset)(struct rtwn_softc *, int);
void (*sc_fw_download_enable)(struct rtwn_softc *, int);
#endif
int (*sc_set_page_size)(struct rtwn_softc *);
void (*sc_lc_calib)(struct rtwn_softc *);
void (*sc_iq_calib)(struct rtwn_softc *);
void (*sc_read_chipid_vendor)(struct rtwn_softc *,
uint32_t);
void (*sc_adj_devcaps)(struct rtwn_softc *);
void (*sc_vap_preattach)(struct rtwn_softc *,
struct ieee80211vap *);
void (*sc_postattach)(struct rtwn_softc *);
void (*sc_detach_private)(struct rtwn_softc *);
void (*sc_fill_tx_desc)(struct rtwn_softc *,
struct ieee80211_node *, struct mbuf *,
void *, uint8_t, int);
void (*sc_fill_tx_desc_raw)(struct rtwn_softc *,
struct ieee80211_node *, struct mbuf *,
void *, const struct ieee80211_bpf_params *);
void (*sc_fill_tx_desc_null)(struct rtwn_softc *,
void *, int, int, int);
void (*sc_dump_tx_desc)(struct rtwn_softc *, const void *);
uint8_t (*sc_tx_radiotap_flags)(const void *);
uint8_t (*sc_rx_radiotap_flags)(const void *);
void (*sc_beacon_init)(struct rtwn_softc *, void *, int);
void (*sc_beacon_enable)(struct rtwn_softc *, int, int);
void (*sc_beacon_set_rate)(void *, int);
void (*sc_beacon_select)(struct rtwn_softc *, int);
void (*sc_set_chan)(struct rtwn_softc *,
struct ieee80211_channel *);
void (*sc_set_media_status)(struct rtwn_softc *, int);
#ifndef RTWN_WITHOUT_UCODE
int (*sc_set_rsvd_page)(struct rtwn_softc *, int, int,
int);
int (*sc_set_pwrmode)(struct rtwn_softc *,
struct ieee80211vap *, int);
void (*sc_set_rssi)(struct rtwn_softc *);
#endif
int8_t (*sc_get_rssi_cck)(struct rtwn_softc *, void *);
int8_t (*sc_get_rssi_ofdm)(struct rtwn_softc *, void *);
int (*sc_classify_intr)(struct rtwn_softc *, void *, int);
void (*sc_handle_tx_report)(struct rtwn_softc *, uint8_t *,
int);
void (*sc_handle_c2h_report)(struct rtwn_softc *,
uint8_t *, int);
int (*sc_check_frame)(struct rtwn_softc *, struct mbuf *);
void (*sc_temp_measure)(struct rtwn_softc *);
uint8_t (*sc_temp_read)(struct rtwn_softc *);
void (*sc_init_tx_agg)(struct rtwn_softc *);
void (*sc_init_rx_agg)(struct rtwn_softc *);
void (*sc_init_intr)(struct rtwn_softc *);
void (*sc_init_ampdu)(struct rtwn_softc *);
void (*sc_init_edca)(struct rtwn_softc *);
void (*sc_init_bb)(struct rtwn_softc *);
void (*sc_init_rf)(struct rtwn_softc *);
void (*sc_init_antsel)(struct rtwn_softc *);
void (*sc_post_init)(struct rtwn_softc *);
int (*sc_init_bcnq1_boundary)(struct rtwn_softc *);
const uint8_t *chan_list_5ghz[3];
int chan_num_5ghz[3];
const struct rtwn_mac_prog *mac_prog;
int mac_size;
const struct rtwn_bb_prog *bb_prog;
int bb_size;
const struct rtwn_agc_prog *agc_prog;
int agc_size;
const struct rtwn_rf_prog *rf_prog;
int page_count;
int pktbuf_count;
int ackto;
int npubqpages;
int nhqpages;
int nnqpages;
int nlqpages;
int page_size;
int txdesc_len;
int efuse_maxlen;
int efuse_maplen;
uint16_t rx_dma_size;
int macid_limit;
int cam_entry_limit;
int fwsize_limit;
int temp_delta;
uint16_t bcn_status_reg[RTWN_PORT_COUNT];
uint32_t rcr; /* Rx filter */
};
MALLOC_DECLARE(M_RTWN_PRIV);
#define RTWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
#define RTWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
#define RTWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
#define RTWN_CMDQ_LOCK_INIT(sc) \
mtx_init(&(sc)->cmdq_mtx, "cmdq lock", NULL, MTX_DEF)
#define RTWN_CMDQ_LOCK(sc) mtx_lock(&(sc)->cmdq_mtx)
#define RTWN_CMDQ_UNLOCK(sc) mtx_unlock(&(sc)->cmdq_mtx)
#define RTWN_CMDQ_LOCK_INITIALIZED(sc) mtx_initialized(&(sc)->cmdq_mtx)
#define RTWN_CMDQ_LOCK_DESTROY(sc) mtx_destroy(&(sc)->cmdq_mtx)
#define RTWN_NT_LOCK_INIT(sc) \
mtx_init(&(sc)->nt_mtx, "node table lock", NULL, MTX_DEF)
#define RTWN_NT_LOCK(sc) mtx_lock(&(sc)->nt_mtx)
#define RTWN_NT_UNLOCK(sc) mtx_unlock(&(sc)->nt_mtx)
#define RTWN_NT_LOCK_INITIALIZED(sc) mtx_initialized(&(sc)->nt_mtx)
#define RTWN_NT_LOCK_DESTROY(sc) mtx_destroy(&(sc)->nt_mtx)
void rtwn_sysctlattach(struct rtwn_softc *);
int rtwn_attach(struct rtwn_softc *);
void rtwn_detach(struct rtwn_softc *);
void rtwn_resume(struct rtwn_softc *);
void rtwn_suspend(struct rtwn_softc *);
/* Interface-specific. */
#define rtwn_write_1(_sc, _addr, _val) \
(((_sc)->sc_write_1)((_sc), (_addr), (_val)))
#define rtwn_write_2(_sc, _addr, _val) \
(((_sc)->sc_write_2)((_sc), (_addr), (_val)))
#define rtwn_write_4(_sc, _addr, _val) \
(((_sc)->sc_write_4)((_sc), (_addr), (_val)))
#define rtwn_read_1(_sc, _addr) \
(((_sc)->sc_read_1)((_sc), (_addr)))
#define rtwn_read_2(_sc, _addr) \
(((_sc)->sc_read_2)((_sc), (_addr)))
#define rtwn_read_4(_sc, _addr) \
(((_sc)->sc_read_4)((_sc), (_addr)))
#define rtwn_delay(_sc, _usec) \
(((_sc)->sc_delay)((_sc), (_usec)))
#define rtwn_tx_start(_sc, _ni, _m, _desc, _type, _id) \
(((_sc)->sc_tx_start)((_sc), (_ni), (_m), (_desc), (_type), (_id)))
#define rtwn_start_xfers(_sc) \
(((_sc)->sc_start_xfers)((_sc)))
#define rtwn_reset_lists(_sc, _vap) \
(((_sc)->sc_reset_lists)((_sc), (_vap)))
#define rtwn_abort_xfers(_sc) \
(((_sc)->sc_abort_xfers)((_sc)))
#define rtwn_fw_write_block(_sc, _buf, _reg, _len) \
(((_sc)->sc_fw_write_block)((_sc), (_buf), (_reg), (_len)))
#define rtwn_get_qmap(_sc) \
(((_sc)->sc_get_qmap)((_sc)))
#define rtwn_set_desc_addr(_sc) \
(((_sc)->sc_set_desc_addr)((_sc)))
#define rtwn_drop_incorrect_tx(_sc) \
(((_sc)->sc_drop_incorrect_tx)((_sc)))
#define rtwn_beacon_update_begin(_sc, _vap) \
(((_sc)->sc_beacon_update_begin)((_sc), (_vap)))
#define rtwn_beacon_update_end(_sc, _vap) \
(((_sc)->sc_beacon_update_end)((_sc), (_vap)))
#define rtwn_beacon_unload(_sc, _id) \
(((_sc)->sc_beacon_unload)((_sc), (_id)))
/* Aliases. */
#define rtwn_bb_write rtwn_write_4
#define rtwn_bb_read rtwn_read_4
#define rtwn_bb_setbits rtwn_setbits_4
/* Device-specific. */
#define rtwn_rf_read(_sc, _chain, _addr) \
(((_sc)->sc_rf_read)((_sc), (_chain), (_addr)))
#define rtwn_rf_write(_sc, _chain, _addr, _val) \
(((_sc)->sc_rf_write)((_sc), (_chain), (_addr), (_val)))
#define rtwn_check_condition(_sc, _cond) \
(((_sc)->sc_check_condition)((_sc), (_cond)))
#define rtwn_efuse_postread(_sc) \
(((_sc)->sc_efuse_postread)((_sc)))
#define rtwn_parse_rom(_sc, _rom) \
(((_sc)->sc_parse_rom)((_sc), (_rom)))
#define rtwn_set_led(_sc, _led, _on) \
(((_sc)->sc_set_led)((_sc), (_led), (_on)))
#define rtwn_get_rssi_cck(_sc, _physt) \
(((_sc)->sc_get_rssi_cck)((_sc), (_physt)))
#define rtwn_get_rssi_ofdm(_sc, _physt) \
(((_sc)->sc_get_rssi_ofdm)((_sc), (_physt)))
#define rtwn_power_on(_sc) \
(((_sc)->sc_power_on)((_sc)))
#define rtwn_power_off(_sc) \
(((_sc)->sc_power_off)((_sc)))
#ifndef RTWN_WITHOUT_UCODE
#define rtwn_fw_reset(_sc, _reason) \
(((_sc)->sc_fw_reset)((_sc), (_reason)))
#define rtwn_fw_download_enable(_sc, _enable) \
(((_sc)->sc_fw_download_enable)((_sc), (_enable)))
#endif
#define rtwn_set_page_size(_sc) \
(((_sc)->sc_set_page_size)((_sc)))
#define rtwn_lc_calib(_sc) \
(((_sc)->sc_lc_calib)((_sc)))
#define rtwn_iq_calib(_sc) \
(((_sc)->sc_iq_calib)((_sc)))
#define rtwn_read_chipid_vendor(_sc, _reg) \
(((_sc)->sc_read_chipid_vendor)((_sc), (_reg)))
#define rtwn_adj_devcaps(_sc) \
(((_sc)->sc_adj_devcaps)((_sc)))
#define rtwn_vap_preattach(_sc, _vap) \
(((_sc)->sc_vap_preattach)((_sc), (_vap)))
#define rtwn_postattach(_sc) \
(((_sc)->sc_postattach)((_sc)))
#define rtwn_detach_private(_sc) \
(((_sc)->sc_detach_private)((_sc)))
#define rtwn_fill_tx_desc(_sc, _ni, _m, \
_buf, _ridx, _maxretry) \
(((_sc)->sc_fill_tx_desc)((_sc), (_ni), \
(_m), (_buf), (_ridx), (_maxretry)))
#define rtwn_fill_tx_desc_raw(_sc, _ni, _m, \
_buf, _params) \
(((_sc)->sc_fill_tx_desc_raw)((_sc), (_ni), \
(_m), (_buf), (_params)))
#define rtwn_fill_tx_desc_null(_sc, _buf, _11b, _qos, _id) \
(((_sc)->sc_fill_tx_desc_null)((_sc), \
(_buf), (_11b), (_qos), (_id)))
#define rtwn_dump_tx_desc(_sc, _desc) \
(((_sc)->sc_dump_tx_desc)((_sc), (_desc)))
#define rtwn_tx_radiotap_flags(_sc, _buf) \
(((_sc)->sc_tx_radiotap_flags)((_buf)))
#define rtwn_rx_radiotap_flags(_sc, _buf) \
(((_sc)->sc_rx_radiotap_flags)((_buf)))
#define rtwn_set_chan(_sc, _c) \
(((_sc)->sc_set_chan)((_sc), (_c)))
#ifndef RTWN_WITHOUT_UCODE
#define rtwn_set_rsvd_page(_sc, _resp, _null, _qos_null) \
(((_sc)->sc_set_rsvd_page)((_sc), \
(_resp), (_null), (_qos_null)))
#define rtwn_set_pwrmode(_sc, _vap, _off) \
(((_sc)->sc_set_pwrmode)((_sc), (_vap), (_off)))
#define rtwn_set_rssi(_sc) \
(((_sc)->sc_set_rssi)((_sc)))
#endif
#define rtwn_classify_intr(_sc, _buf, _len) \
(((_sc)->sc_classify_intr)((_sc), (_buf), (_len)))
#define rtwn_handle_tx_report(_sc, _buf, _len) \
(((_sc)->sc_handle_tx_report)((_sc), (_buf), (_len)))
#define rtwn_handle_c2h_report(_sc, _buf, _len) \
(((_sc)->sc_handle_c2h_report)((_sc), (_buf), (_len)))
#define rtwn_check_frame(_sc, _m) \
(((_sc)->sc_check_frame)((_sc), (_m)))
#define rtwn_beacon_init(_sc, _buf, _id) \
(((_sc)->sc_beacon_init)((_sc), (_buf), (_id)))
#define rtwn_beacon_enable(_sc, _id, _enable) \
(((_sc)->sc_beacon_enable)((_sc), (_id), (_enable)))
#define rtwn_beacon_set_rate(_sc, _buf, _is5ghz) \
(((_sc)->sc_beacon_set_rate)((_buf), (_is5ghz)))
#define rtwn_beacon_select(_sc, _id) \
(((_sc)->sc_beacon_select)((_sc), (_id)))
#define rtwn_temp_measure(_sc) \
(((_sc)->sc_temp_measure)((_sc)))
#define rtwn_temp_read(_sc) \
(((_sc)->sc_temp_read)((_sc)))
#define rtwn_init_tx_agg(_sc) \
(((_sc)->sc_init_tx_agg)((_sc)))
#define rtwn_init_rx_agg(_sc) \
(((_sc)->sc_init_rx_agg)((_sc)))
#define rtwn_init_intr(_sc) \
(((_sc)->sc_init_intr)((_sc)))
#define rtwn_init_ampdu(_sc) \
(((_sc)->sc_init_ampdu)((_sc)))
#define rtwn_init_edca(_sc) \
(((_sc)->sc_init_edca)((_sc)))
#define rtwn_init_bb(_sc) \
(((_sc)->sc_init_bb)((_sc)))
#define rtwn_init_rf(_sc) \
(((_sc)->sc_init_rf)((_sc)))
#define rtwn_init_antsel(_sc) \
(((_sc)->sc_init_antsel)((_sc)))
#define rtwn_post_init(_sc) \
(((_sc)->sc_post_init)((_sc)))
#define rtwn_init_bcnq1_boundary(_sc) \
(((_sc)->sc_init_bcnq1_boundary)((_sc)))
/*
* Methods to access subfields in registers.
*/
static __inline int
rtwn_setbits_1(struct rtwn_softc *sc, uint16_t addr, uint8_t clr,
uint8_t set)
{
return (rtwn_write_1(sc, addr,
(rtwn_read_1(sc, addr) & ~clr) | set));
}
static __inline int
rtwn_setbits_1_shift(struct rtwn_softc *sc, uint16_t addr, uint32_t clr,
uint32_t set, int shift)
{
return (rtwn_setbits_1(sc, addr + shift, clr >> shift * NBBY,
set >> shift * NBBY));
}
static __inline int
rtwn_setbits_2(struct rtwn_softc *sc, uint16_t addr, uint16_t clr,
uint16_t set)
{
return (rtwn_write_2(sc, addr,
(rtwn_read_2(sc, addr) & ~clr) | set));
}
static __inline int
rtwn_setbits_4(struct rtwn_softc *sc, uint16_t addr, uint32_t clr,
uint32_t set)
{
return (rtwn_write_4(sc, addr,
(rtwn_read_4(sc, addr) & ~clr) | set));
}
static __inline void
rtwn_rf_setbits(struct rtwn_softc *sc, int chain, uint8_t addr,
uint32_t clr, uint32_t set)
{
rtwn_rf_write(sc, chain, addr,
(rtwn_rf_read(sc, chain, addr) & ~clr) | set);
}
#endif /* IF_RTWNVAR_H */

View File

@ -0,0 +1,784 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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) 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 <rtems/bsd/sys/param.h>
#include <sys/sysctl.h>
#include <rtems/bsd/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/module.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/linker.h>
#include <sys/kdb.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include <dev/rtwn/if_rtwnreg.h>
#include <dev/rtwn/if_rtwnvar.h>
#include <dev/rtwn/if_rtwn_nop.h>
#include <dev/rtwn/if_rtwn_debug.h>
#include <dev/rtwn/pci/rtwn_pci_var.h>
#include <dev/rtwn/pci/rtwn_pci_attach.h>
#include <dev/rtwn/pci/rtwn_pci_reg.h>
#include <dev/rtwn/pci/rtwn_pci_rx.h>
#include <dev/rtwn/pci/rtwn_pci_tx.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h>
static device_probe_t rtwn_pci_probe;
static device_attach_t rtwn_pci_attach;
static device_detach_t rtwn_pci_detach;
static device_shutdown_t rtwn_pci_shutdown;
static device_suspend_t rtwn_pci_suspend;
static device_resume_t rtwn_pci_resume;
static int rtwn_pci_alloc_rx_list(struct rtwn_softc *);
static void rtwn_pci_reset_rx_list(struct rtwn_softc *);
static void rtwn_pci_free_rx_list(struct rtwn_softc *);
static int rtwn_pci_alloc_tx_list(struct rtwn_softc *, int);
static void rtwn_pci_reset_tx_ring_stopped(struct rtwn_softc *, int);
static void rtwn_pci_reset_beacon_ring(struct rtwn_softc *, int);
static void rtwn_pci_reset_tx_list(struct rtwn_softc *,
struct ieee80211vap *, int);
static void rtwn_pci_free_tx_list(struct rtwn_softc *, int);
static void rtwn_pci_reset_lists(struct rtwn_softc *,
struct ieee80211vap *);
static int rtwn_pci_fw_write_block(struct rtwn_softc *,
const uint8_t *, uint16_t, int);
static uint16_t rtwn_pci_get_qmap(struct rtwn_softc *);
static void rtwn_pci_set_desc_addr(struct rtwn_softc *);
static void rtwn_pci_beacon_update_begin(struct rtwn_softc *,
struct ieee80211vap *);
static void rtwn_pci_beacon_update_end(struct rtwn_softc *,
struct ieee80211vap *);
static void rtwn_pci_attach_methods(struct rtwn_softc *);
static int matched_chip = RTWN_CHIP_MAX_PCI;
static int
rtwn_pci_probe(device_t dev)
{
const struct rtwn_pci_ident *ident;
for (ident = rtwn_pci_ident_table; ident->name != NULL; ident++) {
if (pci_get_vendor(dev) == ident->vendor &&
pci_get_device(dev) == ident->device) {
matched_chip = ident->chip;
device_set_desc(dev, ident->name);
return (BUS_PROBE_DEFAULT);
}
}
return (ENXIO);
}
static int
rtwn_pci_alloc_rx_list(struct rtwn_softc *sc)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_rx_ring *rx_ring = &pc->rx_ring;
struct rtwn_rx_data *rx_data;
bus_size_t size;
int i, error;
/* Allocate Rx descriptors. */
size = sizeof(struct r92ce_rx_stat) * RTWN_PCI_RX_LIST_COUNT;
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
size, 1, size, 0, NULL, NULL, &rx_ring->desc_dmat);
if (error != 0) {
device_printf(sc->sc_dev, "could not create rx desc DMA tag\n");
goto fail;
}
error = bus_dmamem_alloc(rx_ring->desc_dmat, (void **)&rx_ring->desc,
BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
&rx_ring->desc_map);
if (error != 0) {
device_printf(sc->sc_dev, "could not allocate rx desc\n");
goto fail;
}
error = bus_dmamap_load(rx_ring->desc_dmat, rx_ring->desc_map,
rx_ring->desc, size, rtwn_pci_dma_map_addr, &rx_ring->paddr, 0);
if (error != 0) {
device_printf(sc->sc_dev, "could not load rx desc DMA map\n");
goto fail;
}
bus_dmamap_sync(rx_ring->desc_dmat, rx_ring->desc_map,
BUS_DMASYNC_PREWRITE);
/* Create RX buffer DMA tag. */
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
MJUMPAGESIZE, 1, MJUMPAGESIZE, 0, NULL, NULL, &rx_ring->data_dmat);
if (error != 0) {
device_printf(sc->sc_dev, "could not create rx buf DMA tag\n");
goto fail;
}
/* Allocate Rx buffers. */
for (i = 0; i < RTWN_PCI_RX_LIST_COUNT; i++) {
rx_data = &rx_ring->rx_data[i];
error = bus_dmamap_create(rx_ring->data_dmat, 0, &rx_data->map);
if (error != 0) {
device_printf(sc->sc_dev,
"could not create rx buf DMA map\n");
goto fail;
}
rx_data->m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
MJUMPAGESIZE);
if (rx_data->m == NULL) {
device_printf(sc->sc_dev,
"could not allocate rx mbuf\n");
error = ENOMEM;
goto fail;
}
error = bus_dmamap_load(rx_ring->data_dmat, rx_data->map,
mtod(rx_data->m, void *), MJUMPAGESIZE,
rtwn_pci_dma_map_addr, &rx_data->paddr, BUS_DMA_NOWAIT);
if (error != 0) {
device_printf(sc->sc_dev,
"could not load rx buf DMA map");
goto fail;
}
rtwn_pci_setup_rx_desc(pc, &rx_ring->desc[i], rx_data->paddr,
MJUMPAGESIZE, i);
}
rx_ring->cur = 0;
return (0);
fail:
rtwn_pci_free_rx_list(sc);
return (error);
}
static void
rtwn_pci_reset_rx_list(struct rtwn_softc *sc)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_rx_ring *rx_ring = &pc->rx_ring;
struct rtwn_rx_data *rx_data;
int i;
for (i = 0; i < RTWN_PCI_RX_LIST_COUNT; i++) {
rx_data = &rx_ring->rx_data[i];
rtwn_pci_setup_rx_desc(pc, &rx_ring->desc[i],
rx_data->paddr, MJUMPAGESIZE, i);
}
rx_ring->cur = 0;
}
static void
rtwn_pci_free_rx_list(struct rtwn_softc *sc)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_rx_ring *rx_ring = &pc->rx_ring;
struct rtwn_rx_data *rx_data;
int i;
if (rx_ring->desc_dmat != NULL) {
if (rx_ring->desc != NULL) {
bus_dmamap_sync(rx_ring->desc_dmat,
rx_ring->desc_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(rx_ring->desc_dmat,
rx_ring->desc_map);
bus_dmamem_free(rx_ring->desc_dmat, rx_ring->desc,
rx_ring->desc_map);
rx_ring->desc = NULL;
}
bus_dma_tag_destroy(rx_ring->desc_dmat);
rx_ring->desc_dmat = NULL;
}
for (i = 0; i < RTWN_PCI_RX_LIST_COUNT; i++) {
rx_data = &rx_ring->rx_data[i];
if (rx_data->m != NULL) {
bus_dmamap_sync(rx_ring->data_dmat,
rx_data->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(rx_ring->data_dmat, rx_data->map);
m_freem(rx_data->m);
rx_data->m = NULL;
}
bus_dmamap_destroy(rx_ring->data_dmat, rx_data->map);
rx_data->map = NULL;
}
if (rx_ring->data_dmat != NULL) {
bus_dma_tag_destroy(rx_ring->data_dmat);
rx_ring->data_dmat = NULL;
}
}
static int
rtwn_pci_alloc_tx_list(struct rtwn_softc *sc, int qid)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_tx_ring *tx_ring = &pc->tx_ring[qid];
bus_size_t size;
int i, error;
size = sc->txdesc_len * RTWN_PCI_TX_LIST_COUNT;
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), PAGE_SIZE, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
size, 1, size, 0, NULL, NULL, &tx_ring->desc_dmat);
if (error != 0) {
device_printf(sc->sc_dev, "could not create tx ring DMA tag\n");
goto fail;
}
error = bus_dmamem_alloc(tx_ring->desc_dmat, &tx_ring->desc,
BUS_DMA_NOWAIT | BUS_DMA_ZERO, &tx_ring->desc_map);
if (error != 0) {
device_printf(sc->sc_dev, "can't map tx ring DMA memory\n");
goto fail;
}
error = bus_dmamap_load(tx_ring->desc_dmat, tx_ring->desc_map,
tx_ring->desc, size, rtwn_pci_dma_map_addr, &tx_ring->paddr,
BUS_DMA_NOWAIT);
if (error != 0) {
device_printf(sc->sc_dev, "could not load desc DMA map\n");
goto fail;
}
bus_dmamap_sync(tx_ring->desc_dmat, tx_ring->desc_map,
BUS_DMASYNC_PREWRITE);
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
MJUMPAGESIZE, 1, MJUMPAGESIZE, 0, NULL, NULL, &tx_ring->data_dmat);
if (error != 0) {
device_printf(sc->sc_dev, "could not create tx buf DMA tag\n");
goto fail;
}
for (i = 0; i < RTWN_PCI_TX_LIST_COUNT; i++) {
struct rtwn_tx_data *tx_data = &tx_ring->tx_data[i];
void *tx_desc = (uint8_t *)tx_ring->desc + sc->txdesc_len * i;
uint32_t next_desc_addr = tx_ring->paddr +
sc->txdesc_len * ((i + 1) % RTWN_PCI_TX_LIST_COUNT);
rtwn_pci_setup_tx_desc(pc, tx_desc, next_desc_addr);
error = bus_dmamap_create(tx_ring->data_dmat, 0, &tx_data->map);
if (error != 0) {
device_printf(sc->sc_dev,
"could not create tx buf DMA map\n");
return (error);
}
tx_data->m = NULL;
tx_data->ni = NULL;
}
return (0);
fail:
rtwn_pci_free_tx_list(sc, qid);
return (error);
}
static void
rtwn_pci_reset_tx_ring_stopped(struct rtwn_softc *sc, int qid)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_tx_ring *ring = &pc->tx_ring[qid];
int i;
for (i = 0; i < RTWN_PCI_TX_LIST_COUNT; i++) {
struct rtwn_tx_data *data = &ring->tx_data[i];
void *desc = (uint8_t *)ring->desc + sc->txdesc_len * i;
rtwn_pci_copy_tx_desc(pc, desc, NULL);
if (data->m != NULL) {
bus_dmamap_sync(ring->data_dmat, data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(ring->data_dmat, data->map);
m_freem(data->m);
data->m = NULL;
}
if (data->ni != NULL) {
ieee80211_free_node(data->ni);
data->ni = NULL;
}
}
bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
BUS_DMASYNC_POSTWRITE);
sc->qfullmsk &= ~(1 << qid);
ring->queued = 0;
ring->last = ring->cur = 0;
}
/*
* Clear entry 0 (or 1) in the beacon queue (other are not used).
*/
static void
rtwn_pci_reset_beacon_ring(struct rtwn_softc *sc, int id)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_tx_ring *ring = &pc->tx_ring[RTWN_PCI_BEACON_QUEUE];
struct rtwn_tx_data *data = &ring->tx_data[id];
struct rtwn_tx_desc_common *txd = (struct rtwn_tx_desc_common *)
((uint8_t *)ring->desc + id * sc->txdesc_len);
bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_POSTREAD);
if (txd->flags0 & RTWN_FLAGS0_OWN) {
/* Clear OWN bit. */
txd->flags0 &= ~RTWN_FLAGS0_OWN;
bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
BUS_DMASYNC_PREWRITE);
/* Unload mbuf. */
bus_dmamap_sync(ring->data_dmat, data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(ring->data_dmat, data->map);
}
}
/*
* Drop stale entries from Tx ring before the vap will be deleted.
* In case if vap is NULL just free everything and reset cur / last pointers.
*/
static void
rtwn_pci_reset_tx_list(struct rtwn_softc *sc, struct ieee80211vap *vap,
int qid)
{
int i;
if (vap == NULL) {
if (qid != RTWN_PCI_BEACON_QUEUE) {
/*
* Device was stopped; just clear all entries.
*/
rtwn_pci_reset_tx_ring_stopped(sc, qid);
} else {
for (i = 0; i < RTWN_PORT_COUNT; i++)
rtwn_pci_reset_beacon_ring(sc, i);
}
} else if (qid == RTWN_PCI_BEACON_QUEUE &&
(vap->iv_opmode == IEEE80211_M_HOSTAP ||
vap->iv_opmode == IEEE80211_M_IBSS)) {
struct rtwn_vap *uvp = RTWN_VAP(vap);
rtwn_pci_reset_beacon_ring(sc, uvp->id);
} else {
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_tx_ring *ring = &pc->tx_ring[qid];
for (i = 0; i < RTWN_PCI_TX_LIST_COUNT; i++) {
struct rtwn_tx_data *data = &ring->tx_data[i];
if (data->ni != NULL && data->ni->ni_vap == vap) {
/*
* NB: if some vap is still running
* rtwn_pci_tx_done() will free the mbuf;
* otherwise, rtwn_stop() will reset all rings
* after device shutdown.
*/
ieee80211_free_node(data->ni);
data->ni = NULL;
}
}
}
}
static void
rtwn_pci_free_tx_list(struct rtwn_softc *sc, int qid)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_tx_ring *tx_ring = &pc->tx_ring[qid];
struct rtwn_tx_data *tx_data;
int i;
if (tx_ring->desc_dmat != NULL) {
if (tx_ring->desc != NULL) {
bus_dmamap_sync(tx_ring->desc_dmat,
tx_ring->desc_map, BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(tx_ring->desc_dmat,
tx_ring->desc_map);
bus_dmamem_free(tx_ring->desc_dmat, tx_ring->desc,
tx_ring->desc_map);
}
bus_dma_tag_destroy(tx_ring->desc_dmat);
}
for (i = 0; i < RTWN_PCI_TX_LIST_COUNT; i++) {
tx_data = &tx_ring->tx_data[i];
if (tx_data->m != NULL) {
bus_dmamap_sync(tx_ring->data_dmat, tx_data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(tx_ring->data_dmat, tx_data->map);
m_freem(tx_data->m);
tx_data->m = NULL;
}
}
if (tx_ring->data_dmat != NULL) {
bus_dma_tag_destroy(tx_ring->data_dmat);
tx_ring->data_dmat = NULL;
}
sc->qfullmsk &= ~(1 << qid);
tx_ring->queued = 0;
tx_ring->last = tx_ring->cur = 0;
}
static void
rtwn_pci_reset_lists(struct rtwn_softc *sc, struct ieee80211vap *vap)
{
int i;
for (i = 0; i < RTWN_PCI_NTXQUEUES; i++)
rtwn_pci_reset_tx_list(sc, vap, i);
if (vap == NULL) {
sc->qfullmsk = 0;
rtwn_pci_reset_rx_list(sc);
}
}
static int
rtwn_pci_fw_write_block(struct rtwn_softc *sc, const uint8_t *buf,
uint16_t reg, int mlen)
{
int i;
for (i = 0; i < mlen; i++)
rtwn_pci_write_1(sc, reg++, buf[i]);
/* NB: cannot fail */
return (0);
}
static uint16_t
rtwn_pci_get_qmap(struct rtwn_softc *sc)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
KASSERT(pc->pc_qmap != 0, ("%s: qmap is not set!\n", __func__));
return (pc->pc_qmap);
}
static void
rtwn_pci_set_desc_addr(struct rtwn_softc *sc)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
RTWN_DPRINTF(sc, RTWN_DEBUG_RESET, "%s: addresses:\n"
"bk: %08jX, be: %08jX, vi: %08jX, vo: %08jX\n"
"bcn: %08jX, mgt: %08jX, high: %08jX, rx: %08jX\n",
__func__, (uintmax_t)pc->tx_ring[RTWN_PCI_BK_QUEUE].paddr,
(uintmax_t)pc->tx_ring[RTWN_PCI_BE_QUEUE].paddr,
(uintmax_t)pc->tx_ring[RTWN_PCI_VI_QUEUE].paddr,
(uintmax_t)pc->tx_ring[RTWN_PCI_VO_QUEUE].paddr,
(uintmax_t)pc->tx_ring[RTWN_PCI_BEACON_QUEUE].paddr,
(uintmax_t)pc->tx_ring[RTWN_PCI_MGNT_QUEUE].paddr,
(uintmax_t)pc->tx_ring[RTWN_PCI_HIGH_QUEUE].paddr,
(uintmax_t)pc->rx_ring.paddr);
/* Set Tx Configuration Register. */
rtwn_pci_write_4(sc, R92C_TCR, pc->tcr);
/* Configure Tx DMA. */
rtwn_pci_write_4(sc, R92C_BKQ_DESA,
pc->tx_ring[RTWN_PCI_BK_QUEUE].paddr);
rtwn_pci_write_4(sc, R92C_BEQ_DESA,
pc->tx_ring[RTWN_PCI_BE_QUEUE].paddr);
rtwn_pci_write_4(sc, R92C_VIQ_DESA,
pc->tx_ring[RTWN_PCI_VI_QUEUE].paddr);
rtwn_pci_write_4(sc, R92C_VOQ_DESA,
pc->tx_ring[RTWN_PCI_VO_QUEUE].paddr);
rtwn_pci_write_4(sc, R92C_BCNQ_DESA,
pc->tx_ring[RTWN_PCI_BEACON_QUEUE].paddr);
rtwn_pci_write_4(sc, R92C_MGQ_DESA,
pc->tx_ring[RTWN_PCI_MGNT_QUEUE].paddr);
rtwn_pci_write_4(sc, R92C_HQ_DESA,
pc->tx_ring[RTWN_PCI_HIGH_QUEUE].paddr);
/* Configure Rx DMA. */
rtwn_pci_write_4(sc, R92C_RX_DESA, pc->rx_ring.paddr);
}
static void
rtwn_pci_beacon_update_begin(struct rtwn_softc *sc, struct ieee80211vap *vap)
{
struct rtwn_vap *rvp = RTWN_VAP(vap);
RTWN_ASSERT_LOCKED(sc);
rtwn_beacon_enable(sc, rvp->id, 0);
}
static void
rtwn_pci_beacon_update_end(struct rtwn_softc *sc, struct ieee80211vap *vap)
{
struct rtwn_vap *rvp = RTWN_VAP(vap);
RTWN_ASSERT_LOCKED(sc);
if (rvp->curr_mode != R92C_MSR_NOLINK)
rtwn_beacon_enable(sc, rvp->id, 1);
}
static void
rtwn_pci_attach_methods(struct rtwn_softc *sc)
{
sc->sc_write_1 = rtwn_pci_write_1;
sc->sc_write_2 = rtwn_pci_write_2;
sc->sc_write_4 = rtwn_pci_write_4;
sc->sc_read_1 = rtwn_pci_read_1;
sc->sc_read_2 = rtwn_pci_read_2;
sc->sc_read_4 = rtwn_pci_read_4;
sc->sc_delay = rtwn_pci_delay;
sc->sc_tx_start = rtwn_pci_tx_start;
sc->sc_reset_lists = rtwn_pci_reset_lists;
sc->sc_abort_xfers = rtwn_nop_softc;
sc->sc_fw_write_block = rtwn_pci_fw_write_block;
sc->sc_get_qmap = rtwn_pci_get_qmap;
sc->sc_set_desc_addr = rtwn_pci_set_desc_addr;
sc->sc_drop_incorrect_tx = rtwn_nop_softc;
sc->sc_beacon_update_begin = rtwn_pci_beacon_update_begin;
sc->sc_beacon_update_end = rtwn_pci_beacon_update_end;
sc->sc_beacon_unload = rtwn_pci_reset_beacon_ring;
sc->bcn_check_interval = 25000;
}
static int
rtwn_pci_attach(device_t dev)
{
struct rtwn_pci_softc *pc = device_get_softc(dev);
struct rtwn_softc *sc = &pc->pc_sc;
struct ieee80211com *ic = &sc->sc_ic;
uint32_t lcsr;
int cap_off, i, error, rid;
if (matched_chip >= RTWN_CHIP_MAX_PCI)
return (ENXIO);
/*
* Get the offset of the PCI Express Capability Structure in PCI
* Configuration Space.
*/
error = pci_find_cap(dev, PCIY_EXPRESS, &cap_off);
if (error != 0) {
device_printf(dev, "PCIe capability structure not found!\n");
return (error);
}
/* Enable bus-mastering. */
pci_enable_busmaster(dev);
rid = PCIR_BAR(2);
pc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (pc->mem == NULL) {
device_printf(dev, "can't map mem space\n");
return (ENOMEM);
}
pc->pc_st = rman_get_bustag(pc->mem);
pc->pc_sh = rman_get_bushandle(pc->mem);
/* Install interrupt handler. */
rid = 1;
if (pci_alloc_msi(dev, &rid) == 0)
rid = 1;
else
rid = 0;
pc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE |
(rid != 0 ? 0 : RF_SHAREABLE));
if (pc->irq == NULL) {
device_printf(dev, "can't map interrupt\n");
goto detach;
}
/* Disable PCIe Active State Power Management (ASPM). */
lcsr = pci_read_config(dev, cap_off + PCIER_LINK_CTL, 4);
lcsr &= ~PCIEM_LINK_CTL_ASPMC;
pci_write_config(dev, cap_off + PCIER_LINK_CTL, lcsr, 4);
sc->sc_dev = dev;
ic->ic_name = device_get_nameunit(dev);
/* Need to be initialized early. */
rtwn_sysctlattach(sc);
mtx_init(&sc->sc_mtx, ic->ic_name, MTX_NETWORK_LOCK, MTX_DEF);
rtwn_pci_attach_methods(sc);
/* XXX something similar to USB_GET_DRIVER_INFO() */
rtwn_pci_attach_private(pc, matched_chip);
/* Allocate Tx/Rx buffers. */
error = rtwn_pci_alloc_rx_list(sc);
if (error != 0) {
device_printf(dev,
"could not allocate Rx buffers, error %d\n",
error);
goto detach;
}
for (i = 0; i < RTWN_PCI_NTXQUEUES; i++) {
error = rtwn_pci_alloc_tx_list(sc, i);
if (error != 0) {
device_printf(dev,
"could not allocate Tx buffers, error %d\n",
error);
goto detach;
}
}
/* Generic attach. */
error = rtwn_attach(sc);
if (error != 0)
goto detach;
/*
* Hook our interrupt after all initialization is complete.
*/
error = bus_setup_intr(dev, pc->irq, INTR_TYPE_NET | INTR_MPSAFE,
NULL, rtwn_pci_intr, sc, &pc->pc_ih);
if (error != 0) {
device_printf(dev, "can't establish interrupt, error %d\n",
error);
goto detach;
}
return (0);
detach:
rtwn_pci_detach(dev); /* failure */
return (ENXIO);
}
static int
rtwn_pci_detach(device_t dev)
{
struct rtwn_pci_softc *pc = device_get_softc(dev);
struct rtwn_softc *sc = &pc->pc_sc;
int i;
/* Generic detach. */
rtwn_detach(sc);
/* Uninstall interrupt handler. */
if (pc->irq != NULL) {
bus_teardown_intr(dev, pc->irq, pc->pc_ih);
bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(pc->irq),
pc->irq);
pci_release_msi(dev);
}
/* Free Tx/Rx buffers. */
for (i = 0; i < RTWN_PCI_NTXQUEUES; i++)
rtwn_pci_free_tx_list(sc, i);
rtwn_pci_free_rx_list(sc);
if (pc->mem != NULL)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(pc->mem), pc->mem);
rtwn_detach_private(sc);
mtx_destroy(&sc->sc_mtx);
return (0);
}
static int
rtwn_pci_shutdown(device_t self)
{
struct rtwn_pci_softc *pc = device_get_softc(self);
ieee80211_stop_all(&pc->pc_sc.sc_ic);
return (0);
}
static int
rtwn_pci_suspend(device_t self)
{
struct rtwn_pci_softc *pc = device_get_softc(self);
rtwn_suspend(&pc->pc_sc);
return (0);
}
static int
rtwn_pci_resume(device_t self)
{
struct rtwn_pci_softc *pc = device_get_softc(self);
rtwn_resume(&pc->pc_sc);
return (0);
}
static device_method_t rtwn_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, rtwn_pci_probe),
DEVMETHOD(device_attach, rtwn_pci_attach),
DEVMETHOD(device_detach, rtwn_pci_detach),
DEVMETHOD(device_shutdown, rtwn_pci_shutdown),
DEVMETHOD(device_suspend, rtwn_pci_suspend),
DEVMETHOD(device_resume, rtwn_pci_resume),
DEVMETHOD_END
};
static driver_t rtwn_pci_driver = {
"rtwn",
rtwn_pci_methods,
sizeof(struct rtwn_pci_softc)
};
static devclass_t rtwn_pci_devclass;
DRIVER_MODULE(rtwn_pci, pci, rtwn_pci_driver, rtwn_pci_devclass, NULL, NULL);
MODULE_VERSION(rtwn_pci, 1);
MODULE_DEPEND(rtwn_pci, pci, 1, 1, 1);
MODULE_DEPEND(rtwn_pci, wlan, 1, 1, 1);
MODULE_DEPEND(rtwn_pci, rtwn, 2, 2, 2);

View File

@ -0,0 +1,48 @@
/*-
* Copyright (c) 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.
*
* $FreeBSD$
*/
void r92ce_attach(struct rtwn_pci_softc *);
enum {
RTWN_CHIP_RTL8192CE,
RTWN_CHIP_MAX_PCI
};
struct rtwn_pci_ident {
uint16_t vendor;
uint16_t device;
const char *name;
int chip;
};
static const struct rtwn_pci_ident rtwn_pci_ident_table[] = {
{ 0x10ec, 0x8176, "Realtek RTL8188CE", RTWN_CHIP_RTL8192CE },
{ 0, 0, NULL, RTWN_CHIP_MAX_PCI }
};
typedef void (*chip_pci_attach)(struct rtwn_pci_softc *);
static const chip_pci_attach rtwn_chip_pci_attach[RTWN_CHIP_MAX_PCI] = {
[RTWN_CHIP_RTL8192CE] = r92ce_attach
};
static __inline void
rtwn_pci_attach_private(struct rtwn_pci_softc *pc, int chip)
{
rtwn_chip_pci_attach[chip](pc);
}

View File

@ -0,0 +1,125 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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/pci/rtwn_pci_var.h>
#include <dev/rtwn/pci/rtwn_pci_reg.h>
int
rtwn_pci_write_1(struct rtwn_softc *sc, uint16_t addr, uint8_t val)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
bus_space_write_1(pc->pc_st, pc->pc_sh, addr, val);
return (0);
}
int
rtwn_pci_write_2(struct rtwn_softc *sc, uint16_t addr, uint16_t val)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
val = htole16(val);
bus_space_write_2(pc->pc_st, pc->pc_sh, addr, val);
return (0);
}
int
rtwn_pci_write_4(struct rtwn_softc *sc, uint16_t addr, uint32_t val)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
val = htole32(val);
bus_space_write_4(pc->pc_st, pc->pc_sh, addr, val);
return (0);
}
uint8_t
rtwn_pci_read_1(struct rtwn_softc *sc, uint16_t addr)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
return (bus_space_read_1(pc->pc_st, pc->pc_sh, addr));
}
uint16_t
rtwn_pci_read_2(struct rtwn_softc *sc, uint16_t addr)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
uint16_t val;
val = bus_space_read_2(pc->pc_st, pc->pc_sh, addr);
return le16toh(val);
}
uint32_t
rtwn_pci_read_4(struct rtwn_softc *sc, uint16_t addr)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
uint32_t val;
val = bus_space_read_4(pc->pc_st, pc->pc_sh, addr);
return le32toh(val);
}
void
rtwn_pci_delay(struct rtwn_softc *sc, int usec)
{
if (usec < 1000)
DELAY(usec);
else {
(void) mtx_sleep(sc, &sc->sc_mtx, 0, "rtwn_pci",
MAX(msecs_to_ticks(usec / 1000), 1));
}
}

View File

@ -0,0 +1,30 @@
/*-
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef RTWN_PCI_REG_H
#define RTWN_PCI_REG_H
int rtwn_pci_write_1(struct rtwn_softc *, uint16_t, uint8_t);
int rtwn_pci_write_2(struct rtwn_softc *, uint16_t, uint16_t);
int rtwn_pci_write_4(struct rtwn_softc *, uint16_t, uint32_t);
uint8_t rtwn_pci_read_1(struct rtwn_softc *, uint16_t);
uint16_t rtwn_pci_read_2(struct rtwn_softc *, uint16_t);
uint32_t rtwn_pci_read_4(struct rtwn_softc *, uint16_t);
void rtwn_pci_delay(struct rtwn_softc *, int);
#endif /* RTWN_PCI_REG_H */

View File

@ -0,0 +1,329 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.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_rx.h>
#include <dev/rtwn/if_rtwn_task.h>
#include <dev/rtwn/if_rtwn_tx.h>
#include <dev/rtwn/pci/rtwn_pci_var.h>
#include <dev/rtwn/pci/rtwn_pci_rx.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h>
void
rtwn_pci_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs,
int error)
{
if (error != 0)
return;
KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
*(bus_addr_t *)arg = segs[0].ds_addr;
}
void
rtwn_pci_setup_rx_desc(struct rtwn_pci_softc *pc, struct r92ce_rx_stat *desc,
bus_addr_t addr, size_t len, int idx)
{
memset(desc, 0, sizeof(*desc));
desc->rxdw0 = htole32(SM(R92C_RXDW0_PKTLEN, len) |
((idx == RTWN_PCI_RX_LIST_COUNT - 1) ? R92C_RXDW0_EOR : 0));
desc->rxbufaddr = htole32(addr);
bus_space_barrier(pc->pc_st, pc->pc_sh, 0, pc->pc_mapsize,
BUS_SPACE_BARRIER_WRITE);
desc->rxdw0 |= htole32(R92C_RXDW0_OWN);
}
static void
rtwn_pci_rx_frame(struct rtwn_softc *sc, struct r92ce_rx_stat *rx_desc,
int desc_idx)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_rx_ring *ring = &pc->rx_ring;
struct rtwn_rx_data *rx_data = &ring->rx_data[desc_idx];
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
uint32_t rxdw0;
struct mbuf *m, *m1;
int8_t rssi = 0, nf;
int infosz, pktlen, shift, error;
/* Dump Rx descriptor. */
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV_DESC,
"%s: dw: 0 %08X, 1 %08X, 2 %08X, 3 %08X, 4 %08X, tsfl %08X, "
"addr: %08X (64: %08X)\n",
__func__, le32toh(rx_desc->rxdw0), le32toh(rx_desc->rxdw1),
le32toh(rx_desc->rxdw2), le32toh(rx_desc->rxdw3),
le32toh(rx_desc->rxdw4), le32toh(rx_desc->tsf_low),
le32toh(rx_desc->rxbufaddr), le32toh(rx_desc->rxbufaddr64));
rxdw0 = le32toh(rx_desc->rxdw0);
if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) {
/*
* This should not happen since we setup our Rx filter
* to not receive these frames.
*/
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
"%s: RX flags error (%s)\n", __func__,
rxdw0 & R92C_RXDW0_CRCERR ? "CRC" : "ICV");
goto fail;
}
pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
if (__predict_false(pktlen < sizeof(struct ieee80211_frame_ack) ||
pktlen > MJUMPAGESIZE)) {
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
"%s: frame is too short/long: %d\n", __func__, pktlen);
goto fail;
}
infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
shift = MS(rxdw0, R92C_RXDW0_SHIFT);
m1 = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
if (__predict_false(m1 == NULL)) {
device_printf(sc->sc_dev, "%s: could not allocate RX mbuf\n",
__func__);
goto fail;
}
bus_dmamap_sync(ring->data_dmat, rx_data->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(ring->data_dmat, rx_data->map);
error = bus_dmamap_load(ring->data_dmat, rx_data->map, mtod(m1, void *),
MJUMPAGESIZE, rtwn_pci_dma_map_addr, &rx_data->paddr, 0);
if (error != 0) {
m_freem(m1);
error = bus_dmamap_load(ring->data_dmat, rx_data->map,
mtod(rx_data->m, void *), MJUMPAGESIZE,
rtwn_pci_dma_map_addr, &rx_data->paddr, BUS_DMA_NOWAIT);
if (error != 0)
panic("%s: could not load old RX mbuf",
device_get_name(sc->sc_dev));
/* Physical address may have changed. */
rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr,
MJUMPAGESIZE, desc_idx);
goto fail;
}
/* Finalize mbuf. */
m = rx_data->m;
rx_data->m = m1;
m->m_pkthdr.len = m->m_len = pktlen + infosz + shift;
nf = RTWN_NOISE_FLOOR;
ni = rtwn_rx_common(sc, m, rx_desc, &rssi);
RTWN_DPRINTF(sc, RTWN_DEBUG_RECV,
"%s: Rx frame len %d, infosz %d, shift %d, rssi %d\n",
__func__, pktlen, infosz, shift, rssi);
/* Update RX descriptor. */
rtwn_pci_setup_rx_desc(pc, rx_desc, rx_data->paddr, MJUMPAGESIZE,
desc_idx);
/* Send the frame to the 802.11 layer. */
RTWN_UNLOCK(sc);
if (ni != NULL) {
(void)ieee80211_input(ni, m, rssi - nf, nf);
/* Node is no longer needed. */
ieee80211_free_node(ni);
} else
(void)ieee80211_input_all(ic, m, rssi - nf, nf);
RTWN_LOCK(sc);
return;
fail:
counter_u64_add(ic->ic_ierrors, 1);
}
static void
rtwn_pci_tx_done(struct rtwn_softc *sc, int qid)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_tx_ring *ring = &pc->tx_ring[qid];
struct rtwn_tx_desc_common *desc;
struct rtwn_tx_data *data;
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: qid %d, last %d, cur %d\n",
__func__, qid, ring->last, ring->cur);
bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_POSTREAD);
while(ring->last != ring->cur) {
data = &ring->tx_data[ring->last];
desc = (struct rtwn_tx_desc_common *)
((uint8_t *)ring->desc + sc->txdesc_len * ring->last);
KASSERT(data->m != NULL, ("no mbuf"));
if (desc->flags0 & RTWN_FLAGS0_OWN)
break;
/* Unmap and free mbuf. */
bus_dmamap_sync(ring->data_dmat, data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(ring->data_dmat, data->map);
if (data->ni != NULL) { /* not a beacon frame */
ieee80211_tx_complete(data->ni, data->m, 0);
data->ni = NULL;
ring->queued--;
KASSERT(ring->queued >= 0,
("ring->queued (qid %d) underflow!\n", qid));
} else
m_freem(data->m);
data->m = NULL;
ring->last = (ring->last + 1) % RTWN_PCI_TX_LIST_COUNT;
#ifndef D4054
if (ring->queued > 0)
sc->sc_tx_timer = 5;
else
sc->sc_tx_timer = 0;
#endif
}
if ((sc->qfullmsk & (1 << qid)) != 0 &&
ring->queued < (RTWN_PCI_TX_LIST_COUNT - 1)) {
sc->qfullmsk &= ~(1 << qid);
rtwn_start(sc);
}
#ifdef IEEE80211_SUPPORT_SUPERG
/*
* If the TX active queue drops below a certain
* threshold, ensure we age fast-frames out so they're
* transmitted.
*/
if (sc->sc_ratectl != RTWN_RATECTL_NET80211 && ring->queued <= 1) {
/*
* XXX TODO: just make this a callout timer schedule
* so we can flush the FF staging queue if we're
* approaching idle.
*/
rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
}
#endif
}
static void
rtwn_pci_rx_done(struct rtwn_softc *sc)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_rx_ring *ring = &pc->rx_ring;
bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_POSTREAD);
for (;;) {
struct r92ce_rx_stat *rx_desc = &ring->desc[ring->cur];
if (le32toh(rx_desc->rxdw0) & R92C_RXDW0_OWN)
break;
rtwn_pci_rx_frame(sc, rx_desc, ring->cur);
if (!(sc->sc_flags & RTWN_RUNNING))
return;
ring->cur = (ring->cur + 1) % RTWN_PCI_RX_LIST_COUNT;
}
/* Finished receive; age anything left on the FF queue by a little bump */
/*
* XXX TODO: just make this a callout timer schedule so we can
* flush the FF staging queue if we're approaching idle.
*/
#ifdef IEEE80211_SUPPORT_SUPERG
if (!(sc->sc_flags & RTWN_FW_LOADED) ||
sc->sc_ratectl != RTWN_RATECTL_NET80211)
rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
#endif
}
void
rtwn_pci_intr(void *arg)
{
struct rtwn_softc *sc = arg;
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
int i, status, tx_rings;
RTWN_LOCK(sc);
status = rtwn_classify_intr(sc, &tx_rings, 0);
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: status %08X, tx_rings %08X\n",
__func__, status, tx_rings);
if (status == 0 && tx_rings == 0)
goto unlock;
if (status & RTWN_PCI_INTR_RX) {
rtwn_pci_rx_done(sc);
if (!(sc->sc_flags & RTWN_RUNNING))
goto unlock;
}
if (tx_rings != 0)
for (i = 0; i < RTWN_PCI_NTXQUEUES; i++)
if (tx_rings & (1 << i))
rtwn_pci_tx_done(sc, i);
if (sc->sc_flags & RTWN_RUNNING)
rtwn_pci_enable_intr(pc);
unlock:
RTWN_UNLOCK(sc);
}

View File

@ -0,0 +1,27 @@
/*-
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef RTWN_PCI_RX_H
#define RTWN_PCI_RX_H
void rtwn_pci_dma_map_addr(void *, bus_dma_segment_t *, int, int);
void rtwn_pci_setup_rx_desc(struct rtwn_pci_softc *,
struct r92ce_rx_stat *, bus_addr_t, size_t, int);
void rtwn_pci_intr(void *);
#endif /* RTWN_PCI_RX_H */

View File

@ -0,0 +1,274 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <net/if.h>
#include <net/if_var.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/pci/rtwn_pci_var.h>
#include <dev/rtwn/pci/rtwn_pci_tx.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
static struct mbuf *
rtwn_mbuf_defrag(struct mbuf *m0, int how)
{
struct mbuf *m = NULL;
KASSERT(m0->m_flags & M_PKTHDR,
("M_PKTHDR flag is absent (m %p)!", m0));
/* NB: we need _exactly_ one mbuf (no less, no more). */
if (m0->m_pkthdr.len > MJUMPAGESIZE) {
/* XXX MJUM9BYTES? */
return (NULL);
} else if (m0->m_pkthdr.len > MCLBYTES) {
m = m_getjcl(how, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
if (m == NULL)
return (NULL);
if (m_dup_pkthdr(m, m0, how) == 0) {
m_freem(m);
return (NULL);
}
m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
m->m_len = m->m_pkthdr.len;
m_freem(m0);
return (m);
} else
return (m_defrag(m0, how));
}
static int
rtwn_pci_tx_start_frame(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m, uint8_t *tx_desc, uint8_t type)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_tx_ring *ring;
struct rtwn_tx_data *data;
struct rtwn_tx_desc_common *txd;
bus_dma_segment_t segs[1];
uint8_t qid;
int nsegs, error;
RTWN_ASSERT_LOCKED(sc);
switch (type) {
case IEEE80211_FC0_TYPE_CTL:
case IEEE80211_FC0_TYPE_MGT:
qid = RTWN_PCI_MGNT_QUEUE;
break;
default:
qid = M_WME_GETAC(m);
break;
}
ring = &pc->tx_ring[qid];
data = &ring->tx_data[ring->cur];
if (data->m != NULL) {
RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT,
"%s: ring #%u is full (m %p)\n", __func__, qid, data->m);
return (ENOBUFS);
}
txd = (struct rtwn_tx_desc_common *)
((uint8_t *)ring->desc + sc->txdesc_len * ring->cur);
if (txd->flags0 & RTWN_FLAGS0_OWN) {
device_printf(sc->sc_dev,
"%s: OWN bit is set (tx desc %d, ring %u)!\n",
__func__, ring->cur, qid);
return (ENOBUFS);
}
/* Copy Tx descriptor. */
rtwn_pci_copy_tx_desc(pc, txd, tx_desc);
txd->pktlen = htole16(m->m_pkthdr.len);
txd->offset = sc->txdesc_len;
error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs,
&nsegs, BUS_DMA_NOWAIT);
if (error != 0 && error != EFBIG) {
device_printf(sc->sc_dev, "can't map mbuf (error %d)\n",
error);
return (error);
}
if (error != 0) {
struct mbuf *mnew;
mnew = rtwn_mbuf_defrag(m, M_NOWAIT);
if (mnew == NULL) {
device_printf(sc->sc_dev, "can't defragment mbuf\n");
return (ENOBUFS);
}
m = mnew;
error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m,
segs, &nsegs, BUS_DMA_NOWAIT);
if (error != 0) {
device_printf(sc->sc_dev,
"can't map mbuf (error %d)\n", error);
if (ni != NULL) {
if_inc_counter(ni->ni_vap->iv_ifp,
IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
}
m_freem(m);
return (0); /* XXX */
}
}
rtwn_pci_tx_postsetup(pc, txd, segs);
txd->flags0 |= RTWN_FLAGS0_OWN;
/* Dump Tx descriptor. */
rtwn_dump_tx_desc(sc, txd);
bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
data->m = m;
data->ni = ni;
ring->cur = (ring->cur + 1) % RTWN_PCI_TX_LIST_COUNT;
ring->queued++;
if (ring->queued >= (RTWN_PCI_TX_LIST_COUNT - 1))
sc->qfullmsk |= (1 << qid);
#ifndef D4054
sc->sc_tx_timer = 5;
#endif
/* Kick TX. */
rtwn_write_2(sc, R92C_PCIE_CTRL_REG, (1 << qid));
return (0);
}
static int
rtwn_pci_tx_start_beacon(struct rtwn_softc *sc, struct mbuf *m,
uint8_t *tx_desc, int id)
{
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
struct rtwn_tx_ring *ring;
struct rtwn_tx_data *data;
struct rtwn_tx_desc_common *txd;
bus_dma_segment_t segs[1];
int nsegs, error, own;
RTWN_ASSERT_LOCKED(sc);
KASSERT(id == 0 || id == 1, ("bogus vap id %d\n", id));
ring = &pc->tx_ring[RTWN_PCI_BEACON_QUEUE];
data = &ring->tx_data[id];
txd = (struct rtwn_tx_desc_common *)
((uint8_t *)ring->desc + id * sc->txdesc_len);
bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
BUS_DMASYNC_POSTREAD);
own = !!(txd->flags0 & RTWN_FLAGS0_OWN);
error = 0;
if (!own || txd->pktlen != htole16(m->m_pkthdr.len)) {
if (!own) {
/* Copy Tx descriptor. */
rtwn_pci_copy_tx_desc(pc, txd, tx_desc);
txd->offset = sc->txdesc_len;
} else {
/* Reload mbuf. */
bus_dmamap_unload(ring->data_dmat, data->map);
}
error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
if (error != 0) {
device_printf(sc->sc_dev,
"can't map beacon (error %d)\n", error);
txd->flags0 &= ~RTWN_FLAGS0_OWN;
goto end;
}
txd->pktlen = htole16(m->m_pkthdr.len);
rtwn_pci_tx_postsetup(pc, txd, segs);
txd->flags0 |= RTWN_FLAGS0_OWN;
end:
bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
BUS_DMASYNC_PREWRITE);
}
/* Dump Tx descriptor. */
rtwn_dump_tx_desc(sc, txd);
bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
return (0);
}
int
rtwn_pci_tx_start(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m, uint8_t *tx_desc, uint8_t type, int id)
{
int error = 0;
RTWN_ASSERT_LOCKED(sc);
if (ni == NULL) /* beacon frame */
error = rtwn_pci_tx_start_beacon(sc, m, tx_desc, id);
else
error = rtwn_pci_tx_start_frame(sc, ni, m, tx_desc, type);
return (error);
}

View File

@ -0,0 +1,25 @@
/*-
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef RTWN_PCI_TX_H
#define RTWN_PCI_TX_H
int rtwn_pci_tx_start(struct rtwn_softc *, struct ieee80211_node *,
struct mbuf *, uint8_t *, uint8_t, int);
#endif /* RTWN_PCI_TX_H */

View File

@ -0,0 +1,140 @@
/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef RTWN_PCI_VAR_H
#define RTWN_PCI_VAR_H
#include <dev/rtwn/rtl8192c/pci/r92ce_rx_desc.h>
#define RTWN_PCI_RX_LIST_COUNT 256
#define RTWN_PCI_TX_LIST_COUNT 256
struct rtwn_rx_data {
bus_dmamap_t map;
struct mbuf *m;
bus_addr_t paddr;
};
struct rtwn_rx_ring {
struct r92ce_rx_stat *desc;
bus_addr_t paddr;
bus_dma_tag_t desc_dmat;
bus_dmamap_t desc_map;
bus_dma_tag_t data_dmat;
bus_dma_segment_t seg;
struct rtwn_rx_data rx_data[RTWN_PCI_RX_LIST_COUNT];
int cur;
};
struct rtwn_tx_data {
bus_dmamap_t map;
struct mbuf *m;
struct ieee80211_node *ni;
};
struct rtwn_tx_ring {
bus_addr_t paddr;
bus_dma_tag_t desc_dmat;
bus_dmamap_t desc_map;
bus_dma_tag_t data_dmat;
bus_dma_segment_t seg;
void *desc;
struct rtwn_tx_data tx_data[RTWN_PCI_TX_LIST_COUNT];
int queued;
int cur;
int last;
};
/*
* TX queue indices.
*/
enum {
RTWN_PCI_BK_QUEUE,
RTWN_PCI_BE_QUEUE,
RTWN_PCI_VI_QUEUE,
RTWN_PCI_VO_QUEUE,
RTWN_PCI_BEACON_QUEUE,
RTWN_PCI_TXCMD_QUEUE,
RTWN_PCI_MGNT_QUEUE,
RTWN_PCI_HIGH_QUEUE,
RTWN_PCI_HCCA_QUEUE,
RTWN_PCI_NTXQUEUES
};
/*
* Interrupt events.
*/
enum {
RTWN_PCI_INTR_RX_ERROR = 0x00000001,
RTWN_PCI_INTR_RX_OVERFLOW = 0x00000002,
RTWN_PCI_INTR_RX_DESC_UNAVAIL = 0x00000004,
RTWN_PCI_INTR_RX_DONE = 0x00000008,
RTWN_PCI_INTR_TX_ERROR = 0x00000010,
RTWN_PCI_INTR_TX_OVERFLOW = 0x00000020,
RTWN_PCI_INTR_TX_REPORT = 0x00000040,
RTWN_PCI_INTR_PS_TIMEOUT = 0x00000080
};
/* Shortcuts */
/* Vendor driver treats RX errors like ROK... */
#define RTWN_PCI_INTR_RX \
(RTWN_PCI_INTR_RX_OVERFLOW | RTWN_PCI_INTR_RX_DESC_UNAVAIL | \
RTWN_PCI_INTR_RX_DONE)
struct rtwn_pci_softc {
struct rtwn_softc pc_sc; /* must be the first */
struct resource *irq;
struct resource *mem;
bus_space_tag_t pc_st;
bus_space_handle_t pc_sh;
void *pc_ih;
bus_size_t pc_mapsize;
struct rtwn_rx_ring rx_ring;
struct rtwn_tx_ring tx_ring[RTWN_PCI_NTXQUEUES];
/* must be set by the driver. */
uint16_t pc_qmap;
uint32_t tcr;
void (*pc_setup_tx_desc)(struct rtwn_pci_softc *,
void *, uint32_t);
void (*pc_tx_postsetup)(struct rtwn_pci_softc *,
void *, bus_dma_segment_t *);
void (*pc_copy_tx_desc)(void *, const void *);
void (*pc_enable_intr)(struct rtwn_pci_softc *);
};
#define RTWN_PCI_SOFTC(sc) ((struct rtwn_pci_softc *)(sc))
#define rtwn_pci_setup_tx_desc(_pc, _desc, _addr) \
(((_pc)->pc_setup_tx_desc)((_pc), (_desc), (_addr)))
#define rtwn_pci_tx_postsetup(_pc, _txd, _segs) \
(((_pc)->pc_tx_postsetup)((_pc), (_txd), (_segs)))
#define rtwn_pci_copy_tx_desc(_pc, _dest, _src) \
(((_pc)->pc_copy_tx_desc)((_dest), (_src)))
#define rtwn_pci_enable_intr(_pc) \
(((_pc)->pc_enable_intr)((_pc)))
#endif /* RTWN_PCI_VAR_H */

View File

@ -0,0 +1,94 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef RTL8188E_H
#define RTL8188E_H
/*
* Global definitions.
*/
#define R88E_PUBQ_NPAGES 142
#define R88E_TXPKTBUF_COUNT 177
#define R88E_TX_PAGE_COUNT 169
#define R88E_MACID_MAX 63
#define R88E_RX_DMA_BUFFER_SIZE 0x2400
#define R88E_INTR_MSG_LEN 60
#define R88E_CALIB_THRESHOLD 4
/*
* Function declarations.
*/
/* r88e_beacon.c */
void r88e_beacon_enable(struct rtwn_softc *, int, int);
/* r88e_calib.c */
void r88e_iq_calib(struct rtwn_softc *);
void r88e_temp_measure(struct rtwn_softc *);
uint8_t r88e_temp_read(struct rtwn_softc *);
/* r88e_chan.c */
void r88e_get_txpower(struct rtwn_softc *, int,
struct ieee80211_channel *, uint16_t[]);
void r88e_set_bw20(struct rtwn_softc *, uint8_t);
void r88e_set_gain(struct rtwn_softc *, uint8_t);
/* r88e_fw.c */
#ifndef RTWN_WITHOUT_UCODE
int r88e_fw_cmd(struct rtwn_softc *, uint8_t, const void *, int);
void r88e_fw_reset(struct rtwn_softc *, int);
void r88e_fw_download_enable(struct rtwn_softc *, int);
#endif
void r88e_macid_enable_link(struct rtwn_softc *, int, int);
void r88e_set_media_status(struct rtwn_softc *, int);
#ifndef RTWN_WITHOUT_UCODE
int r88e_set_rsvd_page(struct rtwn_softc *, int, int, int);
int r88e_set_pwrmode(struct rtwn_softc *, struct ieee80211vap *, int);
#endif
/* r88e_init.c */
void r88e_init_bb(struct rtwn_softc *);
void r88e_init_rf(struct rtwn_softc *);
int r88e_power_on(struct rtwn_softc *);
/* r88e_led.c */
void r88e_set_led(struct rtwn_softc *, int, int);
/* r88e_rf.c */
void r88e_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t);
/* r88e_rom.c */
void r88e_parse_rom(struct rtwn_softc *, uint8_t *);
/* r88e_rx.c */
void r88e_ratectl_tx_complete(struct rtwn_softc *, uint8_t *, int);
void r88e_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
int8_t r88e_get_rssi_cck(struct rtwn_softc *, void *);
int8_t r88e_get_rssi_ofdm(struct rtwn_softc *, void *);
/* r88e_tx.c */
void r88e_tx_enable_ampdu(void *, int);
void r88e_tx_setup_hwseq(void *);
void r88e_tx_setup_macid(void *, int);
#endif /* RTL8188E_H */

View File

@ -0,0 +1,64 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
void
r88e_beacon_enable(struct rtwn_softc *sc, int id, int enable)
{
if (enable) {
rtwn_setbits_1(sc, R92C_MBID_NUM, 0, R88E_MBID_TXBCN_RPT(id));
rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
0, R92C_BCN_CTRL_EN_BCN);
} else {
rtwn_setbits_1(sc, R92C_MBID_NUM, R88E_MBID_TXBCN_RPT(id), 0);
rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
R92C_BCN_CTRL_EN_BCN, 0);
}
}

View File

@ -0,0 +1,69 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
void
r88e_iq_calib(struct rtwn_softc *sc)
{
/* XXX TODO */
}
void
r88e_temp_measure(struct rtwn_softc *sc)
{
rtwn_rf_write(sc, 0, R88E_RF_T_METER, R88E_RF_T_METER_START);
}
uint8_t
r88e_temp_read(struct rtwn_softc *sc)
{
return (MS(rtwn_rf_read(sc, 0, R88E_RF_T_METER),
R88E_RF_T_METER_VAL));
}

View File

@ -0,0 +1,169 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_priv.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
static int
r88e_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 <= 13) group = 4;
else if (chan <= 14) group = 5;
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);
}
void
r88e_get_txpower(struct rtwn_softc *sc, int chain,
struct ieee80211_channel *c, uint16_t power[RTWN_RIDX_COUNT])
{
struct r92c_softc *rs = sc->sc_priv;
const struct rtwn_r88e_txpwr *rt = rs->rs_txpwr;
const struct rtwn_r88e_txagc *base = rs->rs_txagc;
uint16_t cckpow, ofdmpow, bw20pow, htpow;
int max_mcs, ridx, group;
/* Determine channel group. */
group = r88e_get_power_group(sc, c);
if (group == -1) { /* shouldn't happen */
device_printf(sc->sc_dev, "%s: incorrect channel\n", __func__);
return;
}
/* XXX net80211 regulatory */
max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
KASSERT(max_mcs <= RTWN_RIDX_COUNT, ("increase ridx limit\n"));
memset(power, 0, max_mcs * sizeof(power[0]));
if (rs->regulatory == 0) {
for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
power[ridx] = base->pwr[0][ridx];
}
for (ridx = RTWN_RIDX_OFDM6; ridx < RTWN_RIDX_COUNT; ridx++) {
if (rs->regulatory == 3)
power[ridx] = base->pwr[0][ridx];
else if (rs->regulatory == 1) {
if (!IEEE80211_IS_CHAN_HT40(c))
power[ridx] = base->pwr[group][ridx];
} else if (rs->regulatory != 2)
power[ridx] = base->pwr[0][ridx];
}
/* Compute per-CCK rate Tx power. */
cckpow = rt->cck_tx_pwr[group];
for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
power[ridx] += cckpow;
htpow = rt->ht40_tx_pwr[group];
/* Compute per-OFDM rate Tx power. */
ofdmpow = htpow + rt->ofdm_tx_pwr_diff;
for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
power[ridx] += ofdmpow;
bw20pow = htpow + rt->bw20_tx_pwr_diff;
for (ridx = RTWN_RIDX_MCS(0); ridx <= max_mcs; ridx++)
power[ridx] += bw20pow;
/* 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;
}
}
void
r88e_set_bw20(struct rtwn_softc *sc, uint8_t chan)
{
struct r92c_softc *rs = sc->sc_priv;
rtwn_setbits_1(sc, R92C_BWOPMODE, 0, R92C_BWOPMODE_20MHZ);
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. */
rtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
(rs->rf_chnlbw[0] & ~0xfff) | chan | R88E_RF_CHNLBW_BW20);
}
void
r88e_set_gain(struct rtwn_softc *sc, uint8_t gain)
{
rtwn_bb_setbits(sc, R92C_OFDM0_AGCCORE1(0),
R92C_OFDM0_AGCCORE1_GAIN_M, gain);
}

View File

@ -0,0 +1,227 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8188e/r88e_fw_cmd.h>
#ifndef RTWN_WITHOUT_UCODE
int
r88e_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len)
{
struct r88e_fw_cmd cmd;
int ntries, error;
if (!(sc->sc_flags & RTWN_FW_LOADED)) {
RTWN_DPRINTF(sc, RTWN_DEBUG_FIRMWARE, "%s: firmware "
"was not loaded; command (id %d) will be discarded\n",
__func__, id);
return (0);
}
/* Wait for current FW box to be empty. */
for (ntries = 0; ntries < 50; ntries++) {
if (!(rtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur)))
break;
rtwn_delay(sc, 2000);
}
if (ntries == 100) {
device_printf(sc->sc_dev,
"could not send firmware command\n");
return (ETIMEDOUT);
}
memset(&cmd, 0, sizeof(cmd));
cmd.id = id;
KASSERT(len <= sizeof(cmd.msg),
("%s: firmware command too long (%d > %zu)\n",
__func__, len, sizeof(cmd.msg)));
memcpy(cmd.msg, buf, len);
/* Write the first word last since that will trigger the FW. */
if (len > 3) {
error = rtwn_write_4(sc, R88E_HMEBOX_EXT(sc->fwcur),
*(uint32_t *)((uint8_t *)&cmd + 4));
if (error != 0)
return (error);
}
error = rtwn_write_4(sc, R92C_HMEBOX(sc->fwcur), *(uint32_t *)&cmd);
if (error != 0)
return (error);
sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
return (0);
}
void
r88e_fw_reset(struct rtwn_softc *sc, int reason)
{
uint16_t reg;
reg = rtwn_read_2(sc, R92C_SYS_FUNC_EN);
rtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
rtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN);
}
void
r88e_fw_download_enable(struct rtwn_softc *sc, int enable)
{
if (enable) {
/* MCU firmware download enable. */
rtwn_setbits_1(sc, R92C_MCUFWDL, 0, R92C_MCUFWDL_EN);
/* 8051 reset. */
rtwn_setbits_1_shift(sc, R92C_MCUFWDL, R92C_MCUFWDL_ROM_DLEN,
0, 2);
} else {
/* MCU download disable. */
rtwn_setbits_1(sc, R92C_MCUFWDL, R92C_MCUFWDL_EN, 0);
/* Reserved for f/w extension. */
rtwn_write_1(sc, R92C_MCUFWDL + 1, 0);
}
}
#endif
void
r88e_macid_enable_link(struct rtwn_softc *sc, int id, int enable)
{
uint32_t reg;
reg = R88E_MACID_NO_LINK;
if (id > 32)
reg += 4;
if (enable)
rtwn_setbits_4(sc, reg, 1 << (id % 32), 0);
else
rtwn_setbits_4(sc, reg, 0, 1 << (id % 32));
/* XXX max macid for tx reports */
}
void
r88e_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);
r88e_macid_enable_link(sc, status.macid,
(macid & RTWN_MACID_VALID) != 0);
#ifndef RTWN_WITHOUT_UCODE
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__);
}
#endif
}
#ifndef RTWN_WITHOUT_UCODE
int
r88e_set_rsvd_page(struct rtwn_softc *sc, int probe_resp, int null,
int qos_null)
{
struct r88e_fw_cmd_rsvdpage rsvd;
rsvd.probe_resp = probe_resp;
rsvd.ps_poll = 0;
rsvd.null_data = null;
rsvd.null_data_qos = qos_null;
rsvd.null_data_qos_bt = 0;
return (r88e_fw_cmd(sc, R88E_CMD_RSVD_PAGE, &rsvd, sizeof(rsvd)));
}
int
r88e_set_pwrmode(struct rtwn_softc *sc, struct ieee80211vap *vap,
int off)
{
struct r88e_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;
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,84 @@
/*-
* Copyright (c) 2015 Kevin Lo <kevlo@FreeBSD.org>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R88E_FW_CMD_H
#define R88E_FW_CMD_H
/*
* Host to firmware commands.
*/
struct r88e_fw_cmd {
uint8_t id;
#define R88E_CMD_RSVD_PAGE 0x00
#define R88E_CMD_MSR_RPT 0x01
#define R88E_CMD_SET_PWRMODE 0x20
uint8_t msg[7];
} __packed __attribute__((aligned(4)));
/* Structure for R88E_CMD_RSVD_PAGE. */
struct r88e_fw_cmd_rsvdpage {
uint8_t probe_resp;
uint8_t ps_poll;
uint8_t null_data;
uint8_t null_data_qos;
uint8_t null_data_qos_bt;
} __packed;
/* Structure for R88E_CMD_MSR_RPT. */
struct r88e_fw_cmd_msrrpt {
uint8_t msrb0;
#define R88E_MSRRPT_B0_DISASSOC 0x00
#define R88E_MSRRPT_B0_ASSOC 0x01
uint8_t macid;
} __packed;
/* Structure for R88E_CMD_SET_PWRMODE. */
struct r88e_fw_cmd_pwrmode {
uint8_t mode;
#define R88E_PWRMODE_CAM 0
#define R88E_PWRMODE_LEG 1
#define R88E_PWRMODE_UAPSD 2
uint8_t pwrb1;
#define R88E_PWRMODE_B1_RLBM_M 0x0f
#define R88E_PWRMODE_B1_RLBM_S 0
#define R88E_PWRMODE_B1_MODE_MIN 0
#define R88E_PWRMODE_B1_MODE_MAX 1
#define R88E_PWRMODE_B1_MODE_DTIM 2
#define R88E_PWRMODE_B1_SMART_PS_M 0xf0
#define R88E_PWRMODE_B1_SMART_PS_S 4
#define R88E_PWRMODE_B1_LEG_PSPOLL0 0
#define R88E_PWRMODE_B1_LEG_PSPOLL1 1
#define R88E_PWRMODE_B1_LEG_NULLDATA 2
#define R88E_PWRMODE_B1_WMM_PSPOLL 0
#define R88E_PWRMODE_B1_WMM_NULLDATA 1
uint8_t bcn_pass;
uint8_t queue_uapsd;
uint8_t pwr_state;
#define R88E_PWRMODE_STATE_RFOFF 0x00
#define R88E_PWRMODE_STATE_RFON 0x04
#define R88E_PWRMODE_STATE_ALLON 0x0c
} __packed;
#endif /* R88E_FW_CMD_H */

View File

@ -0,0 +1,160 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
static void
r88e_crystalcap_write(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
uint32_t reg;
uint8_t val;
val = rs->crystalcap & 0x3f;
reg = rtwn_bb_read(sc, R92C_AFE_XTAL_CTRL);
rtwn_bb_write(sc, R92C_AFE_XTAL_CTRL,
RW(reg, R92C_AFE_XTAL_CTRL_ADDR, val | val << 6));
}
void
r88e_init_bb(struct rtwn_softc *sc)
{
/* 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);
rtwn_write_1(sc, R92C_RF_CTRL,
R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
rtwn_write_1(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
r92c_init_bb_common(sc);
rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553422);
rtwn_delay(sc, 1);
rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420);
rtwn_delay(sc, 1);
r88e_crystalcap_write(sc);
}
int
r88e_power_on(struct rtwn_softc *sc)
{
#define RTWN_CHK(res) do { \
if (res != 0) \
return (EIO); \
} while(0)
int ntries;
/* 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);
}
/* Reset BB. */
RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST, 0));
RTWN_CHK(rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80));
/* Disable HWPDN. */
RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_APDM_HPDN, 0, 1));
/* Disable WL suspend. */
RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE, 0, 1));
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 LDO normal mode. */
RTWN_CHK(rtwn_setbits_1(sc, R92C_LPLDO_CTRL,
R92C_LPLDO_CTRL_SLEEP, 0));
/* 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);
#undef RTWN_CHK
}

View File

@ -0,0 +1,70 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
void
r88e_set_led(struct rtwn_softc *sc, int led, int on)
{
if (led == RTWN_LED_LINK) {
if (!on) {
rtwn_setbits_1(sc, R92C_LEDCFG2, 0x6f,
R92C_LEDCFG0_DIS);
rtwn_setbits_1(sc, R92C_MAC_PINMUX_CFG, 0x01, 0);
} else
rtwn_setbits_1(sc, R92C_LEDCFG2, 0x0f, 0x60);
sc->ledlink = on; /* Save LED state. */
}
/* XXX led #1? */
}

View File

@ -0,0 +1,273 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R88E_PRIV_H
#define R88E_PRIV_H
#include <dev/rtwn/rtl8188e/r88e_rom_defs.h>
/*
* Parsed Tx power (diff) values.
*/
struct rtwn_r88e_txpwr {
uint8_t cck_tx_pwr[R88E_GROUP_2G];
uint8_t ht40_tx_pwr[R88E_GROUP_2G - 1];
int8_t ofdm_tx_pwr_diff;
int8_t bw20_tx_pwr_diff;
};
/*
* MAC initialization values.
*/
static const struct rtwn_mac_prog rtl8188eu_mac[] = {
{ 0x026, 0x41 }, { 0x027, 0x35 }, { 0x040, 0x00 }, { 0x428, 0x0a },
{ 0x429, 0x10 }, { 0x430, 0x00 }, { 0x431, 0x01 }, { 0x432, 0x02 },
{ 0x433, 0x04 }, { 0x434, 0x05 }, { 0x435, 0x06 }, { 0x436, 0x07 },
{ 0x437, 0x08 }, { 0x438, 0x00 }, { 0x439, 0x00 }, { 0x43a, 0x01 },
{ 0x43b, 0x02 }, { 0x43c, 0x04 }, { 0x43d, 0x05 }, { 0x43e, 0x06 },
{ 0x43f, 0x07 }, { 0x440, 0x5d }, { 0x441, 0x01 }, { 0x442, 0x00 },
{ 0x444, 0x15 }, { 0x445, 0xf0 }, { 0x446, 0x0f }, { 0x447, 0x00 },
{ 0x458, 0x41 }, { 0x459, 0xa8 }, { 0x45a, 0x72 }, { 0x45b, 0xb9 },
{ 0x460, 0x66 }, { 0x461, 0x66 }, { 0x480, 0x08 }, { 0x4c8, 0xff },
{ 0x4c9, 0x08 }, { 0x4cc, 0xff }, { 0x4cd, 0xff }, { 0x4ce, 0x01 },
{ 0x4d3, 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 }, { 0x550, 0x10 }, { 0x551, 0x10 }, { 0x559, 0x02 },
{ 0x55d, 0xff }, { 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a },
{ 0x620, 0xff }, { 0x621, 0xff }, { 0x622, 0xff }, { 0x623, 0xff },
{ 0x624, 0xff }, { 0x625, 0xff }, { 0x626, 0xff }, { 0x627, 0xff },
{ 0x652, 0x20 }, { 0x63c, 0x0a }, { 0x63d, 0x0a }, { 0x63e, 0x0e },
{ 0x63f, 0x0e }, { 0x640, 0x40 }, { 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 rtl8188eu_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, 0x89c,
0x900, 0x904, 0x908, 0x90c, 0x910, 0x914, 0xa00, 0xa04,
0xa08, 0xa0c, 0xa10, 0xa14, 0xa18, 0xa1c, 0xa20, 0xa24,
0xa28, 0xa2c, 0xa70, 0xa74, 0xa78, 0xa7c, 0xa80, 0xb2c,
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, 0xd2c, 0xd30, 0xd34, 0xd38, 0xd3c,
0xd40, 0xd44, 0xd48, 0xd4c, 0xd50, 0xd54, 0xd58, 0xd5c,
0xd60, 0xd64, 0xd68, 0xd6c, 0xd70, 0xd74, 0xd78, 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, 0xee8, 0xeec, 0xf14, 0xf4c, 0xf00
};
static const uint32_t rtl8188eu_bb_vals[] = {
0x80040000, 0x00000003, 0x0000fc00, 0x0000000a, 0x10001331,
0x020c3d10, 0x02200385, 0x00000000, 0x01000100, 0x00390204,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x569a11a9, 0x01000014, 0x66f60110,
0x061f0649, 0x00000000, 0x27272700, 0x07000760, 0x25004000,
0x00000808, 0x00000000, 0xb0000c1c, 0x00000001, 0x00000000,
0xccc000c0, 0x00000800, 0xfffffffe, 0x40302010, 0x00706050,
0x00000000, 0x00000023, 0x00000000, 0x81121111, 0x00000002,
0x00000201, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e7f120f,
0x9500bb78, 0x1114d028, 0x00881117, 0x89140f00, 0x1a1b0000,
0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
0x00000900, 0x225b0606, 0x218075b1, 0x80000000, 0x48071d40,
0x03a05611, 0x000000e4, 0x6c6c6c6c, 0x08800000, 0x40000100,
0x08800000, 0x40000100, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x69e9ac47, 0x469652af, 0x49795994, 0x0a97971c,
0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f, 0x69553420,
0x43bc0094, 0x00013169, 0x00250492, 0x00000000, 0x7112848b,
0x47c00bff, 0x00000036, 0x2c7f000d, 0x020610db, 0x0000001f,
0x00b91612, 0x390000e4, 0x20f60000, 0x40000100, 0x20200000,
0x00091521, 0x00000000, 0x00121820, 0x00007f7f, 0x00000000,
0x000300a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x28000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x64b22427, 0x00766932,
0x00222222, 0x00000000, 0x37644302, 0x2f97d40c, 0x00000740,
0x00020401, 0x0000907f, 0x20010201, 0xa0633333, 0x3333bc43,
0x7a8f5b6f, 0xcc979975, 0x00000000, 0x80608000, 0x00000000,
0x00127353, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x6437140a, 0x00000000, 0x00000282, 0x30032064, 0x4653de68,
0x04518a3c, 0x00002101, 0x2a201c16, 0x1812362e, 0x322c2220,
0x000e3c24, 0x2d2d2d2d, 0x2d2d2d2d, 0x0390272d, 0x2d2d2d2d,
0x2d2d2d2d, 0x2d2d2d2d, 0x2d2d2d2d, 0x00000000, 0x1000dc1f,
0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00, 0x01004800,
0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f, 0x02140102,
0x28160d05, 0x00000008, 0x001b25a4, 0x00c00014, 0x00c00014,
0x01000014, 0x01000014, 0x01000014, 0x01000014, 0x00c00014,
0x01000014, 0x00c00014, 0x00c00014, 0x00c00014, 0x00c00014,
0x00000014, 0x00000014, 0x21555448, 0x01c00014, 0x00000003,
0x00000000, 0x00000300
};
static const struct rtwn_bb_prog rtl8188eu_bb[] = {
{
nitems(rtl8188eu_bb_regs),
rtl8188eu_bb_regs,
rtl8188eu_bb_vals,
{ 0 },
NULL
}
};
static const uint32_t rtl8188eu_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, 0xe61a0001, 0xe51b0001, 0xe41c0001, 0xe31d0001,
0xe21e0001, 0xe11f0001, 0x8a200001, 0x89210001, 0x88220001,
0x87230001, 0x86240001, 0x85250001, 0x84260001, 0x83270001,
0x82280001, 0x6b290001, 0x6a2a0001, 0x692b0001, 0x682c0001,
0x672d0001, 0x662e0001, 0x652f0001, 0x64300001, 0x63310001,
0x62320001, 0x61330001, 0x46340001, 0x45350001, 0x44360001,
0x43370001, 0x42380001, 0x41390001, 0x403a0001, 0x403b0001,
0x403c0001, 0x403d0001, 0x403e0001, 0x403f0001, 0xfb400001,
0xfb410001, 0xfb420001, 0xfb430001, 0xfb440001, 0xfb450001,
0xfb460001, 0xfb470001, 0xfb480001, 0xfa490001, 0xf94a0001,
0xf84B0001, 0xf74c0001, 0xf64d0001, 0xf54e0001, 0xf44f0001,
0xf3500001, 0xf2510001, 0xf1520001, 0xf0530001, 0xef540001,
0xee550001, 0xed560001, 0xec570001, 0xeb580001, 0xea590001,
0xe95a0001, 0xe85b0001, 0xe75c0001, 0xe65d0001, 0xe55e0001,
0xe45f0001, 0xe3600001, 0xe2610001, 0xc3620001, 0xc2630001,
0xc1640001, 0x8b650001, 0x8a660001, 0x89670001, 0x88680001,
0x87690001, 0x866a0001, 0x856b0001, 0x846c0001, 0x676d0001,
0x666e0001, 0x656f0001, 0x64700001, 0x63710001, 0x62720001,
0x61730001, 0x60740001, 0x46750001, 0x45760001, 0x44770001,
0x43780001, 0x42790001, 0x417a0001, 0x407b0001, 0x407c0001,
0x407d0001, 0x407e0001, 0x407f0001
};
static const struct rtwn_agc_prog rtl8188eu_agc[] = {
{
nitems(rtl8188eu_agc_vals),
rtl8188eu_agc_vals,
{ 0 },
NULL
}
};
/*
* RF initialization values.
*/
static const uint8_t rtl8188eu_rf_regs[] = {
0x00, 0x08, 0x18, 0x19, 0x1e, 0x1f, 0x2f, 0x3f, 0x42, 0x57,
0x58, 0x67, 0x83, 0xb0, 0xb1, 0xb2, 0xb4, 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, 0xb6, 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, 0x18, 0xfe, 0xfe,
0x1f, 0xfe, 0xfe, 0x1e, 0x1f, 0x00
};
static const uint32_t rtl8188eu_rf_vals[] = {
0x30000, 0x84000, 0x00407, 0x00012, 0x80009, 0x00880, 0x1a060,
0x00000, 0x060c0, 0xd0000, 0xbe180, 0x01552, 0x00000, 0xff8fc,
0x54400, 0xccc19, 0x43003, 0x4953e, 0x1c718, 0x060ff, 0x80001,
0x40000, 0x00400, 0xc0000, 0x02400, 0x00009, 0x40c91, 0x99999,
0x000a3, 0x88820, 0x76c06, 0x00000, 0x80000, 0x00180, 0x001a0,
0x6b27d, 0x7e49d, 0x00073, 0x51ff3, 0x00086, 0x00186,
0x00286, 0x01c25, 0x09c25, 0x11c25, 0x19c25, 0x48538, 0x00c07,
0x4bd00, 0x739d0, 0x0adf3, 0x09df0, 0x08ded, 0x07dea, 0x06de7,
0x054ee, 0x044eb, 0x034e8, 0x0246b, 0x01468, 0x0006d, 0x30159,
0x68200, 0x000ce, 0x48a00, 0x65540, 0x88000, 0x020a0, 0xf02b0,
0xef7b0, 0xd4fb0, 0xcf060, 0xb0090, 0xa0080, 0x90080, 0x8f780,
0x722b0, 0x6f7b0, 0x54fb0, 0x4f060, 0x30090, 0x20080, 0x10080,
0x0f780, 0x000a0, 0x10159, 0x0f407, 0x0c350, 0x0c350, 0x80003,
0x0c350, 0x0c350, 0x00001, 0x80000, 0x33e60
};
static const struct rtwn_rf_prog rtl8188eu_rf[] = {
{
nitems(rtl8188eu_rf_regs),
rtl8188eu_rf_regs,
rtl8188eu_rf_vals,
{ 0 },
NULL
},
{ 0, NULL, NULL, { 0 }, NULL }
};
struct rtwn_r88e_txagc {
uint8_t pwr[R88E_GROUP_2G][20]; /* RTWN_RIDX_MCS(7) + 1 */
};
/*
* Per RF chain/group/rate Tx gain values.
*/
static const struct rtwn_r88e_txagc r88e_txagc[] = {
{ { /* Chain 0. */
{ /* Group 0. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
},
{ /* Group 1. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
},
{ /* Group 2. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
},
{ /* Group 3. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
},
{ /* Group 4. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
},
{ /* Group 5. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
}
} }
};
#endif /* R88E_PRIV_H */

View File

@ -0,0 +1,91 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R88E_REG_H
#define R88E_REG_H
#include <dev/rtwn/rtl8192c/r92c_reg.h>
/*
* MAC registers.
*/
/* System Configuration. */
#define R88E_BB_PAD_CTRL 0x064
#define R88E_HIMR 0x0b0
#define R88E_HISR 0x0b4
#define R88E_HIMRE 0x0b8
#define R88E_HISRE 0x0bc
/* MAC General Configuration. */
#define R88E_32K_CTRL 0x194
#define R88E_HMEBOX_EXT(idx) (0x1f0 + (idx) * 4)
/* Protocol Configuration. */
#define R88E_TXPKTBUF_BCNQ1_BDNY 0x457
#define R88E_MACID_NO_LINK 0x484
#define R88E_TX_RPT_CTRL 0x4ec
#define R88E_TX_RPT_MACID_MAX 0x4ed
#define R88E_TX_RPT_TIME 0x4f0
#define R88E_SCH_TXCMD 0x5f8
/* Bits for R88E_HIMR. */
#define R88E_HIMR_CPWM 0x00000100
#define R88E_HIMR_CPWM2 0x00000200
#define R88E_HIMR_TBDER 0x04000000
#define R88E_HIMR_PSTIMEOUT 0x20000000
/* Bits for R88E_HIMRE.*/
#define R88E_HIMRE_RXFOVW 0x00000100
#define R88E_HIMRE_TXFOVW 0x00000200
#define R88E_HIMRE_RXERR 0x00000400
#define R88E_HIMRE_TXERR 0x00000800
/* Bits for R88E_TX_RPT_CTRL. */
#define R88E_TX_RPT1_ENA 0x01
#define R88E_TX_RPT2_ENA 0x02
/* Bits for R92C_MBID_NUM. */
#define R88E_MBID_TXBCN_RPT(id) (0x08 << (id))
/* Bits for R92C_SECCFG. */
#define R88E_SECCFG_CHK_KEYID 0x0100
/*
* Baseband registers.
*/
/* Bits for R92C_LSSI_PARAM(i). */
#define R88E_LSSI_PARAM_ADDR_M 0x0ff00000
#define R88E_LSSI_PARAM_ADDR_S 20
/*
* RF (6052) registers.
*/
#define R88E_RF_T_METER 0x42
/* Bits for R92C_RF_CHNLBW. */
#define R88E_RF_CHNLBW_BW20 0x00c00
/* Bits for R88E_RF_T_METER. */
#define R88E_RF_T_METER_VAL_M 0x0fc00
#define R88E_RF_T_METER_VAL_S 10
#define R88E_RF_T_METER_START 0x30000
#endif /* R88E_REG_H */

View File

@ -0,0 +1,62 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
void
r88e_rf_write(struct rtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
{
rtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
SM(R88E_LSSI_PARAM_ADDR, addr) |
SM(R92C_LSSI_PARAM_DATA, val));
}

View File

@ -0,0 +1,87 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_var.h>
#include <dev/rtwn/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_priv.h>
#include <dev/rtwn/rtl8188e/r88e_rom_image.h>
void
r88e_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
{
struct r92c_softc *rs = sc->sc_priv;
struct rtwn_r88e_txpwr *rt = rs->rs_txpwr;
struct r88e_rom *rom = (struct r88e_rom *)buf;
int i;
rt->bw20_tx_pwr_diff = RTWN_SIGN4TO8(MS(rom->tx_pwr_diff, HIGH_PART));
rt->ofdm_tx_pwr_diff = RTWN_SIGN4TO8(MS(rom->tx_pwr_diff, LOW_PART));
for (i = 0; i < nitems(rom->cck_tx_pwr); i++)
rt->cck_tx_pwr[i] = rom->cck_tx_pwr[i];
for (i = 0; i < nitems(rom->ht40_tx_pwr); i++)
rt->ht40_tx_pwr[i] = rom->ht40_tx_pwr[i];
rs->crystalcap = RTWN_GET_ROM_VAR(rom->crystalcap,
R88E_ROM_CRYSTALCAP_DEF);
rs->regulatory = MS(rom->rf_board_opt, R92C_ROM_RF1_REGULATORY);
rs->board_type =
MS(RTWN_GET_ROM_VAR(rom->rf_board_opt, R92C_BOARD_TYPE_DONGLE),
R92C_ROM_RF1_BOARD_TYPE);
RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "%s: regulatory type %d\n",
__func__,rs->regulatory);
sc->thermal_meter = rom->thermal_meter;
IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
}

View File

@ -0,0 +1,29 @@
/*-
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef R88E_ROM_DEFS_H
#define R88E_ROM_DEFS_H
#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
#define R88E_GROUP_2G 6
#define R88E_EFUSE_MAX_LEN 512
#define R88E_EFUSE_MAP_LEN 512
#endif /* R88E_ROM_DEFS_H */

View File

@ -0,0 +1,60 @@
/*-
* 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.
*
* $FreeBSD$
*/
#ifndef R88E_ROM_IMAGE_H
#define R88E_ROM_IMAGE_H
#include <dev/rtwn/rtl8188e/r88e_rom_defs.h>
/*
* RTL8188EU ROM image.
*/
struct r88e_rom {
uint8_t reserved1[16];
uint8_t cck_tx_pwr[R88E_GROUP_2G];
uint8_t ht40_tx_pwr[R88E_GROUP_2G - 1];
uint8_t tx_pwr_diff;
uint8_t reserved2[156];
uint8_t channel_plan;
uint8_t crystalcap;
#define R88E_ROM_CRYSTALCAP_DEF 0x20
uint8_t thermal_meter;
uint8_t reserved3[6];
uint8_t rf_board_opt;
uint8_t rf_feature_opt;
uint8_t rf_bt_opt;
uint8_t version;
uint8_t customer_id;
uint8_t reserved4[3];
uint8_t rf_ant_opt;
uint8_t reserved5[6];
uint16_t vid;
uint16_t pid;
uint8_t usb_opt;
uint8_t reserved6[2];
uint8_t macaddr[IEEE80211_ADDR_LEN];
uint8_t reserved7[2];
uint8_t string[33]; /* "realtek 802.11n NIC" */
uint8_t reserved8[256];
} __packed;
_Static_assert(sizeof(struct r88e_rom) == R88E_EFUSE_MAP_LEN,
"R88E_EFUSE_MAP_LEN must be equal to sizeof(struct r88e_rom)!");
#endif /* R88E_ROM_IMAGE_H */

View File

@ -0,0 +1,213 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8188e/r88e_rx_desc.h>
void
r88e_ratectl_tx_complete(struct rtwn_softc *sc, uint8_t *buf, int len)
{
#if __FreeBSD_version >= 1200012
struct ieee80211_ratectl_tx_status txs;
#endif
struct r88e_tx_rpt_ccx *rpt;
struct ieee80211_node *ni;
uint8_t macid;
int ntries;
/* Skip Rx descriptor. */
buf += sizeof(struct r92c_rx_stat);
len -= sizeof(struct r92c_rx_stat);
rpt = (struct r88e_tx_rpt_ccx *)buf;
if (len != sizeof(*rpt)) {
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
"%s: wrong report size (%d, must be %zu)\n",
__func__, len, sizeof(*rpt));
return;
}
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
"%s: ccx report dump: 0: %02X, 1: %02X, 2: %02X, queue time: "
"low %02X, high %02X, final ridx: %02X, 6: %02X, 7: %02X\n",
__func__, rpt->rptb0, rpt->rptb1, rpt->rptb2, rpt->queue_time_low,
rpt->queue_time_high, rpt->final_rate, rpt->rptb6, rpt->rptb7);
macid = MS(rpt->rptb1, R88E_RPTB1_MACID);
if (macid > sc->macid_limit) {
device_printf(sc->sc_dev,
"macid %u is too big; increase MACID_MAX limit\n",
macid);
return;
}
ntries = MS(rpt->rptb2, R88E_RPTB2_RETRY_CNT);
ni = sc->node_list[macid];
if (ni != NULL) {
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: frame for macid %u was"
"%s sent (%d retries)\n", __func__, macid,
(rpt->rptb1 & R88E_RPTB1_PKT_OK) ? "" : " not",
ntries);
#if __FreeBSD_version >= 1200012
txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY |
IEEE80211_RATECTL_STATUS_FINAL_RATE;
txs.long_retries = ntries;
if (rpt->final_rate > RTWN_RIDX_OFDM54) { /* MCS */
txs.final_rate =
(rpt->final_rate - 12) | IEEE80211_RATE_MCS;
} else
txs.final_rate = ridx2rate[rpt->final_rate];
if (rpt->rptb1 & R88E_RPTB1_PKT_OK)
txs.status = IEEE80211_RATECTL_TX_SUCCESS;
else if (rpt->rptb2 & R88E_RPTB2_RETRY_OVER)
txs.status = IEEE80211_RATECTL_TX_FAIL_LONG;
else if (rpt->rptb2 & R88E_RPTB2_LIFE_EXPIRE)
txs.status = IEEE80211_RATECTL_TX_FAIL_EXPIRED;
else
txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
ieee80211_ratectl_tx_complete(ni, &txs);
#else
struct ieee80211vap *vap = ni->ni_vap;
if (rpt->rptb1 & R88E_RPTB1_PKT_OK) {
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS, &ntries, NULL);
} else {
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &ntries, NULL);
}
#endif
} else {
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: macid %u, ni is NULL\n",
__func__, macid);
}
}
void
r88e_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 != R88E_INTR_MSG_LEN) {
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
"%s: wrong interrupt message size (%d, must be %d)\n",
__func__, len, R88E_INTR_MSG_LEN);
return;
}
/* XXX TODO */
}
int8_t
r88e_get_rssi_cck(struct rtwn_softc *sc, void *physt)
{
struct r88e_rx_phystat *phy = (struct r88e_rx_phystat *)physt;
int8_t lna_idx, vga_idx, rssi;
lna_idx = (phy->agc_rpt & 0xe0) >> 5;
vga_idx = (phy->agc_rpt & 0x1f);
rssi = 6 - 2 * vga_idx;
switch (lna_idx) {
case 7:
if (vga_idx > 27)
rssi = -100 + 6;
else
rssi += -100 + 2 * 27;
break;
case 6:
rssi += -48 + 2 * 2;
break;
case 5:
rssi += -42 + 2 * 7;
break;
case 4:
rssi += -36 + 2 * 7;
break;
case 3:
rssi += -24 + 2 * 7;
break;
case 2:
rssi += -6 + 2 * 5;
if (sc->sc_flags & RTWN_FLAG_CCK_HIPWR)
rssi -= 6;
break;
case 1:
rssi += 8;
break;
case 0:
rssi += 14;
break;
}
return (rssi);
}
int8_t
r88e_get_rssi_ofdm(struct rtwn_softc *sc, void *physt)
{
struct r88e_rx_phystat *phy = (struct r88e_rx_phystat *)physt;
int rssi;
/* Get average RSSI. */
rssi = ((phy->sig_qual >> 1) & 0x7f) - 110;
return (rssi);
}

View File

@ -0,0 +1,100 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R88E_RX_DESC_H
#define R88E_RX_DESC_H
#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
/* Rx MAC descriptor defines (chip-specific). */
/* Rx dword 3 */
#define R88E_RXDW3_RPT_M 0x0000c000
#define R88E_RXDW3_RPT_S 14
#define R88E_RXDW3_RPT_RX 0
#define R88E_RXDW3_RPT_TX1 1
#define R88E_RXDW3_RPT_TX2 2
#define R88E_RXDW3_RPT_HIS 3
/* Rx PHY descriptor. */
struct r88e_rx_phystat {
uint8_t path_agc[2];
uint8_t chan;
uint8_t reserved1;
uint8_t sig_qual;
uint8_t agc_rpt;
uint8_t rpt_b;
uint8_t reserved2;
uint8_t noise_power;
uint8_t path_cfotail[2];
uint8_t pcts_mask[2];
uint8_t stream_rxevm[2];
uint8_t path_rxsnr[2];
uint8_t noise_power_db_lsb;
uint8_t reserved3[3];
uint8_t stream_csi[2];
uint8_t stream_target_csi[2];
uint8_t sig_evm;
} __packed;
/* Tx report (type 1). */
struct r88e_tx_rpt_ccx {
uint8_t rptb0;
#define R88E_RPTB6_PKT_NUM_M 0x0e
#define R88E_RPTB6_PKT_NUM_S 1
#define R88E_RPTB0_INT_CCX 0x80
uint8_t rptb1;
#define R88E_RPTB1_MACID_M 0x3f
#define R88E_RPTB1_MACID_S 0
#define R88E_RPTB1_PKT_OK 0x40
#define R88E_RPTB1_BMC 0x80
uint8_t rptb2;
#define R88E_RPTB2_RETRY_CNT_M 0x3f
#define R88E_RPTB2_RETRY_CNT_S 0
#define R88E_RPTB2_LIFE_EXPIRE 0x40
#define R88E_RPTB2_RETRY_OVER 0x80
uint8_t queue_time_low;
uint8_t queue_time_high;
uint8_t final_rate;
uint8_t rptb6;
#define R88E_RPTB6_QSEL_M 0xf0
#define R88E_RPTB6_QSEL_S 4
uint8_t rptb7;
} __packed;
/* Interrupt message format. */
/* XXX recheck */
struct r88e_intr_msg {
uint8_t c2h_id;
uint8_t c2h_seq;
uint8_t c2h_evt;
uint8_t reserved1[13];
uint8_t cpwm1;
uint8_t reserved2[3];
uint8_t cpwm2;
uint8_t reserved3[27];
uint32_t hisr;
uint32_t hisr_ex;
};
#endif /* R88E_RX_DESC_H */

View File

@ -0,0 +1,81 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8188e/r88e.h>
#include <dev/rtwn/rtl8188e/r88e_tx_desc.h>
void
r88e_tx_enable_ampdu(void *buf, int enable)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
if (enable)
txd->txdw2 |= htole32(R88E_TXDW2_AGGEN);
else
txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
}
void
r88e_tx_setup_hwseq(void *buf)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
txd->txdseq |= htole16(R88E_TXDSEQ_HWSEQ_EN);
}
void
r88e_tx_setup_macid(void *buf, int id)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
txd->txdw1 |= htole32(SM(R88E_TXDW1_MACID, id));
}

View File

@ -0,0 +1,38 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R88E_TX_DESC_H
#define R88E_TX_DESC_H
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
/* Tx MAC descriptor defines (chip-specific). */
/* Tx dword 1. */
#define R88E_TXDW1_MACID_M 0x0000003f
#define R88E_TXDW1_MACID_S 0
/* Tx dword 2. */
#define R88E_TXDW2_AGGEN 0x00001000
#define R88E_TXDW2_AGGBK 0x00010000
/* Tx dword 3. */
#define R88E_TXDSEQ_HWSEQ_EN 0x8000
#endif /* R88E_TX_DESC_H */

View File

@ -0,0 +1,39 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef RTL8188EU_H
#define RTL8188EU_H
#include <dev/rtwn/rtl8188e/r88e.h>
/*
* Function declarations.
*/
/* r88eu_init.c */
void r88eu_power_off(struct rtwn_softc *);
void r88eu_init_intr(struct rtwn_softc *);
void r88eu_init_rx_agg(struct rtwn_softc *);
void r88eu_post_init(struct rtwn_softc *);
/* r88eu_rx.c */
int r88eu_classify_intr(struct rtwn_softc *, void *, int);
#endif /* RTL8188EU_H */

View File

@ -0,0 +1,218 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_nop.h>
#include <dev/rtwn/usb/rtwn_usb_var.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h>
#include <dev/rtwn/rtl8188e/r88e_priv.h>
#include <dev/rtwn/rtl8188e/usb/r88eu.h>
static struct rtwn_r88e_txpwr r88e_txpwr;
void r88eu_attach(struct rtwn_usb_softc *);
static void
r88e_postattach(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
struct ieee80211com *ic = &sc->sc_ic;
rs->rs_scan_start = ic->ic_scan_start;
ic->ic_scan_start = r92c_scan_start;
rs->rs_scan_end = ic->ic_scan_end;
ic->ic_scan_end = r92c_scan_end;
}
static void
r88eu_attach_private(struct rtwn_softc *sc)
{
struct r92c_softc *rs;
rs = malloc(sizeof(struct r92c_softc), M_RTWN_PRIV, M_WAITOK | M_ZERO);
rs->rs_txpwr = &r88e_txpwr;
rs->rs_txagc = &r88e_txagc;
rs->rs_set_bw20 = r88e_set_bw20;
rs->rs_get_txpower = r88e_get_txpower;
rs->rs_set_gain = r88e_set_gain;
rs->rs_tx_enable_ampdu = r88e_tx_enable_ampdu;
rs->rs_tx_setup_hwseq = r88e_tx_setup_hwseq;
rs->rs_tx_setup_macid = r88e_tx_setup_macid;
rs->rs_set_name = rtwn_nop_softc; /* not used */
rs->rf_read_delay[0] = 10;
rs->rf_read_delay[1] = 100;
rs->rf_read_delay[2] = 10;
sc->sc_priv = rs;
}
static void
r88eu_adj_devcaps(struct rtwn_softc *sc)
{
/* XXX TODO? */
}
void
r88eu_attach(struct rtwn_usb_softc *uc)
{
struct rtwn_softc *sc = &uc->uc_sc;
/* USB part. */
uc->uc_align_rx = r92cu_align_rx;
uc->tx_agg_desc_num = 6;
/* Common part. */
sc->sc_flags = RTWN_FLAG_EXT_HDR;
sc->sc_set_chan = r92c_set_chan;
sc->sc_fill_tx_desc = r92c_fill_tx_desc;
sc->sc_fill_tx_desc_raw = r92c_fill_tx_desc_raw;
sc->sc_fill_tx_desc_null = r92c_fill_tx_desc_null;
sc->sc_dump_tx_desc = r92cu_dump_tx_desc;
sc->sc_tx_radiotap_flags = r92c_tx_radiotap_flags;
sc->sc_rx_radiotap_flags = r92c_rx_radiotap_flags;
sc->sc_get_rssi_cck = r88e_get_rssi_cck;
sc->sc_get_rssi_ofdm = r88e_get_rssi_ofdm;
sc->sc_classify_intr = r88eu_classify_intr;
sc->sc_handle_tx_report = r88e_ratectl_tx_complete;
sc->sc_handle_c2h_report = r88e_handle_c2h_report;
sc->sc_check_frame = rtwn_nop_int_softc_mbuf;
sc->sc_rf_read = r92c_rf_read;
sc->sc_rf_write = r88e_rf_write;
sc->sc_check_condition = r92c_check_condition;
sc->sc_efuse_postread = rtwn_nop_softc;
sc->sc_parse_rom = r88e_parse_rom;
sc->sc_set_led = r88e_set_led;
sc->sc_power_on = r88e_power_on;
sc->sc_power_off = r88eu_power_off;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_fw_reset = r88e_fw_reset;
sc->sc_fw_download_enable = r88e_fw_download_enable;
#endif
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 */
sc->sc_read_chipid_vendor = rtwn_nop_softc_uint32;
sc->sc_adj_devcaps = r88eu_adj_devcaps;
sc->sc_vap_preattach = rtwn_nop_softc_vap;
sc->sc_postattach = r88e_postattach;
sc->sc_detach_private = r92c_detach_private;
sc->sc_set_media_status = r88e_set_media_status;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_set_rsvd_page = r88e_set_rsvd_page;
sc->sc_set_pwrmode = r88e_set_pwrmode;
sc->sc_set_rssi = rtwn_nop_softc; /* XXX TODO? */
#endif
sc->sc_beacon_init = r92c_beacon_init;
sc->sc_beacon_enable = r88e_beacon_enable;
sc->sc_beacon_set_rate = rtwn_nop_void_int;
sc->sc_beacon_select = rtwn_nop_softc_int;
sc->sc_temp_measure = r88e_temp_measure;
sc->sc_temp_read = r88e_temp_read;
sc->sc_init_tx_agg = r92cu_init_tx_agg;
sc->sc_init_rx_agg = r88eu_init_rx_agg;
sc->sc_init_ampdu = rtwn_nop_softc;
sc->sc_init_intr = r88eu_init_intr;
sc->sc_init_edca = r92c_init_edca;
sc->sc_init_bb = r88e_init_bb;
sc->sc_init_rf = r92c_init_rf;
sc->sc_init_antsel = rtwn_nop_softc;
sc->sc_post_init = r88eu_post_init;
sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc;
sc->mac_prog = &rtl8188eu_mac[0];
sc->mac_size = nitems(rtl8188eu_mac);
sc->bb_prog = &rtl8188eu_bb[0];
sc->bb_size = nitems(rtl8188eu_bb);
sc->agc_prog = &rtl8188eu_agc[0];
sc->agc_size = nitems(rtl8188eu_agc);
sc->rf_prog = &rtl8188eu_rf[0];
sc->name = "RTL8188EU";
sc->fwname = "rtwn-rtl8188eufw";
sc->fwsig = 0x88e;
sc->page_count = R88E_TX_PAGE_COUNT;
sc->pktbuf_count = R88E_TXPKTBUF_COUNT;
sc->ackto = 0x40;
sc->npubqpages = R88E_PUBQ_NPAGES;
sc->page_size = R92C_TX_PAGE_SIZE;
sc->txdesc_len = sizeof(struct r92cu_tx_desc);
sc->efuse_maxlen = R88E_EFUSE_MAX_LEN;
sc->efuse_maplen = R88E_EFUSE_MAP_LEN;
sc->rx_dma_size = R88E_RX_DMA_BUFFER_SIZE;
sc->macid_limit = R88E_MACID_MAX + 1;
sc->cam_entry_limit = R92C_CAM_ENTRY_COUNT;
sc->fwsize_limit = R92C_MAX_FW_SIZE;
sc->temp_delta = R88E_CALIB_THRESHOLD;
sc->bcn_status_reg[0] = R92C_TDECTRL;
sc->bcn_status_reg[1] = R92C_TDECTRL;
sc->rcr = 0;
sc->ntxchains = 1;
sc->nrxchains = 1;
r88eu_attach_private(sc);
}

View File

@ -0,0 +1,226 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_var.h>
#include <dev/rtwn/rtl8188e/usb/r88eu.h>
#include <dev/rtwn/rtl8188e/usb/r88eu_reg.h>
void
r88eu_power_off(struct rtwn_softc *sc)
{
uint8_t reg;
int error, ntries;
/* Disable any kind of TX reports. */
error = rtwn_setbits_1(sc, R88E_TX_RPT_CTRL,
R88E_TX_RPT1_ENA | R88E_TX_RPT2_ENA, 0);
if (error == ENXIO) /* hardware gone */
return;
/* Stop Rx. */
rtwn_write_1(sc, R92C_CR, 0);
/* Move card to Low Power State. */
/* Block all Tx queues. */
rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
for (ntries = 0; ntries < 10; ntries++) {
/* Should be zero if no packet is transmitting. */
if (rtwn_read_4(sc, R88E_SCH_TXCMD) == 0)
break;
rtwn_delay(sc, 5000);
}
if (ntries == 10) {
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 MAC TRX */
rtwn_write_1(sc, R92C_CR,
R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN |
R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_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, 0x20);
/* If firmware in ram code, do reset. */
#ifndef RTWN_WITHOUT_UCODE
if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY)
r88e_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
#endif
/* Reset MCU ready status. */
rtwn_write_1(sc, R92C_MCUFWDL, 0);
/* Disable 32k. */
rtwn_setbits_1(sc, R88E_32K_CTRL, 0x01, 0);
/* Move card to Disabled state. */
/* Turn off RF. */
rtwn_write_1(sc, R92C_RF_CTRL, 0);
/* LDO Sleep mode. */
rtwn_setbits_1(sc, R92C_LPLDO_CTRL, 0, R92C_LPLDO_CTRL_SLEEP);
/* 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 < 10; 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, 5000);
}
if (ntries == 10) {
device_printf(sc->sc_dev, "%s: could not turn off MAC\n",
__func__);
return;
}
/* schmit trigger */
rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80);
/* Enable WL suspend. */
rtwn_setbits_1_shift(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_AFSM_PCIE, R92C_APS_FSMCO_AFSM_HSUS, 1);
/* Enable bandgap mbias in suspend. */
rtwn_write_1(sc, R92C_APS_FSMCO + 3, 0);
/* Clear SIC_EN register. */
rtwn_setbits_1(sc, R92C_GPIO_MUXCFG + 1, 0x10, 0);
/* Set USB suspend enable local register */
rtwn_setbits_1(sc, R92C_USB_SUSPEND, 0, 0x10);
/* Reset MCU IO Wrapper. */
reg = rtwn_read_1(sc, R92C_RSV_CTRL + 1);
rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg & ~0x08);
rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg | 0x08);
/* marked as 'For Power Consumption' code. */
rtwn_write_1(sc, R92C_GPIO_OUT, rtwn_read_1(sc, R92C_GPIO_IN));
rtwn_write_1(sc, R92C_GPIO_IOSEL, 0xff);
rtwn_write_1(sc, R92C_GPIO_IO_SEL,
rtwn_read_1(sc, R92C_GPIO_IO_SEL) << 4);
rtwn_setbits_1(sc, R92C_GPIO_MOD, 0, 0x0f);
/* Set LNA, TRSW, EX_PA Pin to output mode. */
rtwn_write_4(sc, R88E_BB_PAD_CTRL, 0x00080808);
}
void
r88eu_init_intr(struct rtwn_softc *sc)
{
/* TODO: adjust */
rtwn_write_4(sc, R88E_HISR, 0xffffffff);
rtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 |
R88E_HIMR_TBDER | R88E_HIMR_PSTIMEOUT);
rtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW |
R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR | R88E_HIMRE_TXERR);
rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0,
R92C_USB_SPECIAL_OPTION_INT_BULK_SEL);
}
void
r88eu_init_rx_agg(struct rtwn_softc *sc)
{
/* XXX merge? */
rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0,
R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
/* XXX dehardcode */
rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
}
void
r88eu_post_init(struct rtwn_softc *sc)
{
/* Enable per-packet TX report. */
rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0, R88E_TX_RPT1_ENA);
/* Disable Tx if MACID is not associated. */
rtwn_write_4(sc, R88E_MACID_NO_LINK, 0xffffffff);
rtwn_write_4(sc, R88E_MACID_NO_LINK + 4, 0xffffffff);
r88e_macid_enable_link(sc, RTWN_MACID_BC, 1);
/* Perform LO and IQ calibrations. */
r88e_iq_calib(sc);
/* Perform LC calibration. */
r92c_lc_calib(sc);
rtwn_write_1(sc, R92C_USB_HRPWM, 0);
if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
/* No support (yet?) for f/w rate adaptation. */
sc->sc_ratectl = RTWN_RATECTL_NET80211;
} else
sc->sc_ratectl = sc->sc_ratectl_sysctl;
}

View File

@ -0,0 +1,27 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R88EU_REG_H
#define R88EU_REG_H
#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
#include <dev/rtwn/rtl8188e/r88e_reg.h>
#endif /* R88EU_REG_H */

View File

@ -0,0 +1,76 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_rx_desc.h>
#include <dev/rtwn/rtl8188e/usb/r88eu.h>
int
r88eu_classify_intr(struct rtwn_softc *sc, void *buf, int len)
{
struct r92c_rx_stat *stat = buf;
int report_sel = MS(le32toh(stat->rxdw3), R88E_RXDW3_RPT);
switch (report_sel) {
case R88E_RXDW3_RPT_RX:
return (RTWN_RX_DATA);
case R88E_RXDW3_RPT_TX1: /* per-packet Tx report */
case R88E_RXDW3_RPT_TX2: /* periodical Tx report */
return (RTWN_RX_TX_REPORT);
case R88E_RXDW3_RPT_HIS:
return (RTWN_RX_OTHER);
default: /* shut up the compiler */
return (RTWN_RX_DATA);
}
}

View File

@ -0,0 +1,74 @@
/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef RTL8192CE_H
#define RTL8192CE_H
#include <dev/rtwn/rtl8192c/r92c.h>
/*
* Global definitions.
*/
#define R92CE_PUBQ_NPAGES 176
#define R92CE_HPQ_NPAGES 41
#define R92CE_LPQ_NPAGES 28
#define R92CE_TX_PAGE_COUNT \
(R92CE_PUBQ_NPAGES + R92CE_HPQ_NPAGES + R92CE_LPQ_NPAGES)
/*
* Function declarations.
*/
/* r92ce_calib.c */
void r92ce_iq_calib(struct rtwn_softc *);
/* r92ce_fw.c */
#ifndef RTWN_WITHOUT_UCODE
void r92ce_fw_reset(struct rtwn_softc *, int);
#endif
/* r92ce_init.c */
void r92ce_init_intr(struct rtwn_softc *);
void r92ce_init_edca(struct rtwn_softc *);
void r92ce_init_bb(struct rtwn_softc *);
int r92ce_power_on(struct rtwn_softc *);
void r92ce_power_off(struct rtwn_softc *);
void r92ce_init_ampdu(struct rtwn_softc *);
void r92ce_post_init(struct rtwn_softc *);
/* r92ce_led.c */
void r92ce_set_led(struct rtwn_softc *, int, int);
/* r92ce_rx.c */
int r92ce_classify_intr(struct rtwn_softc *, void *, int);
void r92ce_enable_intr(struct rtwn_pci_softc *);
void r92ce_start_xfers(struct rtwn_softc *);
/* r92ce_tx.c */
void r92ce_setup_tx_desc(struct rtwn_pci_softc *, void *, uint32_t);
void r92ce_tx_postsetup(struct rtwn_pci_softc *, void *,
bus_dma_segment_t[]);
void r92ce_copy_tx_desc(void *, const void *);
void r92ce_dump_tx_desc(struct rtwn_softc *, const void *);
#endif /* RTL8192CE_H */

View File

@ -0,0 +1,265 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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_nop.h>
#include <dev/rtwn/pci/rtwn_pci_var.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_priv.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h>
static struct rtwn_r92c_txpwr r92c_txpwr;
void r92ce_attach(struct rtwn_pci_softc *);
static void
r92ce_postattach(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
struct ieee80211com *ic = &sc->sc_ic;
if (!(rs->chip & R92C_CHIP_92C) &&
rs->board_type == R92C_BOARD_TYPE_HIGHPA)
rs->rs_txagc = &rtl8188ru_txagc[0];
else
rs->rs_txagc = &rtl8192cu_txagc[0];
if ((rs->chip & (R92C_CHIP_UMC_A_CUT | R92C_CHIP_92C)) ==
R92C_CHIP_UMC_A_CUT)
sc->fwname = "rtwn-rtl8192cfwE";
else
sc->fwname = "rtwn-rtl8192cfwE_B";
sc->fwsig = 0x88c;
rs->rs_scan_start = ic->ic_scan_start;
ic->ic_scan_start = r92c_scan_start;
rs->rs_scan_end = ic->ic_scan_end;
ic->ic_scan_end = r92c_scan_end;
}
static void
r92ce_set_name(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
if (rs->chip & R92C_CHIP_92C)
sc->name = "RTL8192CE";
else
sc->name = "RTL8188CE";
}
static void
r92ce_attach_private(struct rtwn_softc *sc)
{
struct r92c_softc *rs;
rs = malloc(sizeof(struct r92c_softc), M_RTWN_PRIV, M_WAITOK | M_ZERO);
rs->rs_txpwr = &r92c_txpwr;
rs->rs_set_bw20 = r92c_set_bw20;
rs->rs_get_txpower = r92c_get_txpower;
rs->rs_set_gain = r92c_set_gain;
rs->rs_tx_enable_ampdu = r92c_tx_enable_ampdu;
rs->rs_tx_setup_hwseq = r92c_tx_setup_hwseq;
rs->rs_tx_setup_macid = r92c_tx_setup_macid;
rs->rs_set_name = r92ce_set_name;
/* XXX TODO: test with net80211 ratectl! */
#ifndef RTWN_WITHOUT_UCODE
rs->rs_c2h_timeout = hz;
callout_init_mtx(&rs->rs_c2h_report, &sc->sc_mtx, 0);
#endif
rs->rf_read_delay[0] = 1000;
rs->rf_read_delay[1] = 1000;
rs->rf_read_delay[2] = 1000;
sc->sc_priv = rs;
}
static void
r92ce_adj_devcaps(struct rtwn_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
/*
* XXX do NOT enable PMGT until RSVD_PAGE command
* will not be tested / fixed + HRPWM register must be set too.
*/
ic->ic_caps &= ~IEEE80211_C_PMGT;
}
void
r92ce_attach(struct rtwn_pci_softc *pc)
{
struct rtwn_softc *sc = &pc->pc_sc;
/* PCIe part. */
pc->pc_setup_tx_desc = r92ce_setup_tx_desc;
pc->pc_tx_postsetup = r92ce_tx_postsetup;
pc->pc_copy_tx_desc = r92ce_copy_tx_desc;
pc->pc_enable_intr = r92ce_enable_intr;
pc->pc_qmap = 0xf771;
pc->tcr =
R92C_TCR_CFENDFORM | (1 << 12) | (1 << 13);
/* Common part. */
/* RTL8192C* cannot use pairwise keys from first 4 slots */
sc->sc_flags = RTWN_FLAG_CAM_FIXED;
sc->sc_start_xfers = r92ce_start_xfers;
sc->sc_set_chan = r92c_set_chan;
sc->sc_fill_tx_desc = r92c_fill_tx_desc;
sc->sc_fill_tx_desc_raw = r92c_fill_tx_desc_raw;
sc->sc_fill_tx_desc_null = r92c_fill_tx_desc_null; /* XXX recheck */
sc->sc_dump_tx_desc = r92ce_dump_tx_desc;
sc->sc_tx_radiotap_flags = r92c_tx_radiotap_flags;
sc->sc_rx_radiotap_flags = r92c_rx_radiotap_flags;
sc->sc_get_rssi_cck = r92c_get_rssi_cck;
sc->sc_get_rssi_ofdm = r92c_get_rssi_ofdm;
sc->sc_classify_intr = r92ce_classify_intr;
sc->sc_handle_tx_report = rtwn_nop_softc_uint8_int;
sc->sc_handle_c2h_report = rtwn_nop_softc_uint8_int;
sc->sc_check_frame = rtwn_nop_int_softc_mbuf;
sc->sc_rf_read = r92c_rf_read;
sc->sc_rf_write = r92c_rf_write;
sc->sc_check_condition = r92c_check_condition;
sc->sc_efuse_postread = r92c_efuse_postread;
sc->sc_parse_rom = r92c_parse_rom;
sc->sc_set_led = r92ce_set_led;
sc->sc_power_on = r92ce_power_on;
sc->sc_power_off = r92ce_power_off;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_fw_reset = r92ce_fw_reset;
sc->sc_fw_download_enable = r92c_fw_download_enable;
#endif
sc->sc_set_page_size = r92c_set_page_size;
sc->sc_lc_calib = r92c_lc_calib;
sc->sc_iq_calib = r92ce_iq_calib;
sc->sc_read_chipid_vendor = r92c_read_chipid_vendor;
sc->sc_adj_devcaps = r92ce_adj_devcaps;
sc->sc_vap_preattach = rtwn_nop_softc_vap;
sc->sc_postattach = r92ce_postattach;
sc->sc_detach_private = r92c_detach_private;
sc->sc_set_media_status = r92c_joinbss_rpt;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_set_rsvd_page = r92c_set_rsvd_page;
sc->sc_set_pwrmode = r92c_set_pwrmode;
sc->sc_set_rssi = r92c_set_rssi;
#endif
sc->sc_beacon_init = r92c_beacon_init;
sc->sc_beacon_enable = r92c_beacon_enable;
sc->sc_beacon_set_rate = rtwn_nop_void_int;
sc->sc_beacon_select = rtwn_nop_softc_int;
sc->sc_temp_measure = r92c_temp_measure;
sc->sc_temp_read = r92c_temp_read;
sc->sc_init_tx_agg = rtwn_nop_softc;
sc->sc_init_rx_agg = rtwn_nop_softc;
sc->sc_init_ampdu = r92ce_init_ampdu;
sc->sc_init_intr = r92ce_init_intr;
sc->sc_init_edca = r92ce_init_edca;
sc->sc_init_bb = r92ce_init_bb;
sc->sc_init_rf = r92c_init_rf;
sc->sc_init_antsel = rtwn_nop_softc;
sc->sc_post_init = r92ce_post_init;
sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc;
sc->mac_prog = &rtl8192ce_mac[0];
sc->mac_size = nitems(rtl8192ce_mac);
sc->bb_prog = &rtl8192ce_bb[0];
sc->bb_size = nitems(rtl8192ce_bb);
sc->agc_prog = &rtl8192ce_agc[0];
sc->agc_size = nitems(rtl8192ce_agc);
sc->rf_prog = &rtl8192c_rf[0];
sc->page_count = R92CE_TX_PAGE_COUNT;
sc->pktbuf_count = R92C_TXPKTBUF_COUNT;
sc->ackto = 0x40;
sc->npubqpages = R92CE_PUBQ_NPAGES;
sc->nhqpages = R92CE_HPQ_NPAGES;
sc->nnqpages = 0;
sc->nlqpages = R92CE_LPQ_NPAGES;
sc->page_size = R92C_TX_PAGE_SIZE;
sc->txdesc_len = sizeof(struct r92ce_tx_desc);
sc->efuse_maxlen = R92C_EFUSE_MAX_LEN;
sc->efuse_maplen = R92C_EFUSE_MAP_LEN;
sc->rx_dma_size = R92C_RX_DMA_BUFFER_SIZE;
sc->macid_limit = R92C_MACID_MAX + 1;
sc->cam_entry_limit = R92C_CAM_ENTRY_COUNT;
sc->fwsize_limit = R92C_MAX_FW_SIZE;
sc->temp_delta = R92C_CALIB_THRESHOLD;
sc->bcn_status_reg[0] = R92C_TDECTRL;
/*
* TODO: some additional setup is required
* to maintain few beacons at the same time.
*
* XXX BCNQ1 mechanism is not needed here; move it to the USB module.
*/
sc->bcn_status_reg[1] = R92C_TDECTRL;
sc->rcr = 0;
r92ce_attach_private(sc);
}

View File

@ -0,0 +1,388 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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/pci/rtwn_pci_var.h>
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
/* Registers to save and restore during IQ calibration. */
struct r92ce_iq_cal_reg_vals {
uint32_t adda[16];
uint8_t txpause;
uint8_t bcn_ctrl[2];
uint32_t gpio_muxcfg;
uint32_t ofdm0_trxpathena;
uint32_t ofdm0_trmuxpar;
uint32_t fpga0_rfifacesw1;
};
/* XXX 92CU? */
static int
r92ce_iq_calib_chain(struct rtwn_softc *sc, int chain, uint16_t tx[2],
uint16_t rx[2])
{
uint32_t status;
int offset = chain * 0x20;
if (chain == 0) { /* IQ calibration for chain 0. */
/* IQ calibration settings for chain 0. */
rtwn_bb_write(sc, 0xe30, 0x10008c1f);
rtwn_bb_write(sc, 0xe34, 0x10008c1f);
rtwn_bb_write(sc, 0xe38, 0x82140102);
if (sc->ntxchains > 1) {
rtwn_bb_write(sc, 0xe3c, 0x28160202); /* 2T */
/* IQ calibration settings for chain 1. */
rtwn_bb_write(sc, 0xe50, 0x10008c22);
rtwn_bb_write(sc, 0xe54, 0x10008c22);
rtwn_bb_write(sc, 0xe58, 0x82140102);
rtwn_bb_write(sc, 0xe5c, 0x28160202);
} else
rtwn_bb_write(sc, 0xe3c, 0x28160502); /* 1T */
/* LO calibration settings. */
rtwn_bb_write(sc, 0xe4c, 0x001028d1);
/* We're doing LO and IQ calibration in one shot. */
rtwn_bb_write(sc, 0xe48, 0xf9000000);
rtwn_bb_write(sc, 0xe48, 0xf8000000);
} else { /* IQ calibration for chain 1. */
/* We're doing LO and IQ calibration in one shot. */
rtwn_bb_write(sc, 0xe60, 0x00000002);
rtwn_bb_write(sc, 0xe60, 0x00000000);
}
/* Give LO and IQ calibrations the time to complete. */
rtwn_delay(sc, 1000);
/* Read IQ calibration status. */
status = rtwn_bb_read(sc, 0xeac);
if (status & (1 << (28 + chain * 3)))
return (0); /* Tx failed. */
/* Read Tx IQ calibration results. */
tx[0] = (rtwn_bb_read(sc, 0xe94 + offset) >> 16) & 0x3ff;
tx[1] = (rtwn_bb_read(sc, 0xe9c + offset) >> 16) & 0x3ff;
if (tx[0] == 0x142 || tx[1] == 0x042)
return (0); /* Tx failed. */
if (status & (1 << (27 + chain * 3)))
return (1); /* Rx failed. */
/* Read Rx IQ calibration results. */
rx[0] = (rtwn_bb_read(sc, 0xea4 + offset) >> 16) & 0x3ff;
rx[1] = (rtwn_bb_read(sc, 0xeac + offset) >> 16) & 0x3ff;
if (rx[0] == 0x132 || rx[1] == 0x036)
return (1); /* Rx failed. */
return (3); /* Both Tx and Rx succeeded. */
}
static void
r92ce_iq_calib_run(struct rtwn_softc *sc, int n, uint16_t tx[2][2],
uint16_t rx[2][2], struct r92ce_iq_cal_reg_vals *vals)
{
/* Registers to save and restore during IQ calibration. */
static const uint16_t reg_adda[16] = {
0x85c, 0xe6c, 0xe70, 0xe74,
0xe78, 0xe7c, 0xe80, 0xe84,
0xe88, 0xe8c, 0xed0, 0xed4,
0xed8, 0xedc, 0xee0, 0xeec
};
int i, chain;
uint32_t hssi_param1;
if (n == 0) {
for (i = 0; i < nitems(reg_adda); i++)
vals->adda[i] = rtwn_bb_read(sc, reg_adda[i]);
vals->txpause = rtwn_read_1(sc, R92C_TXPAUSE);
vals->bcn_ctrl[0] = rtwn_read_1(sc, R92C_BCN_CTRL(0));
vals->bcn_ctrl[1] = rtwn_read_1(sc, R92C_BCN_CTRL(1));
vals->gpio_muxcfg = rtwn_read_4(sc, R92C_GPIO_MUXCFG);
}
if (sc->ntxchains == 1) {
rtwn_bb_write(sc, reg_adda[0], 0x0b1b25a0);
for (i = 1; i < nitems(reg_adda); i++)
rtwn_bb_write(sc, reg_adda[i], 0x0bdb25a0);
} else {
for (i = 0; i < nitems(reg_adda); i++)
rtwn_bb_write(sc, reg_adda[i], 0x04db25a4);
}
hssi_param1 = rtwn_bb_read(sc, R92C_HSSI_PARAM1(0));
if (!(hssi_param1 & R92C_HSSI_PARAM1_PI)) {
rtwn_bb_write(sc, R92C_HSSI_PARAM1(0),
hssi_param1 | R92C_HSSI_PARAM1_PI);
rtwn_bb_write(sc, R92C_HSSI_PARAM1(1),
hssi_param1 | R92C_HSSI_PARAM1_PI);
}
if (n == 0) {
vals->ofdm0_trxpathena =
rtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA);
vals->ofdm0_trmuxpar = rtwn_bb_read(sc, R92C_OFDM0_TRMUXPAR);
vals->fpga0_rfifacesw1 =
rtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(1));
}
rtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, 0x03a05600);
rtwn_bb_write(sc, R92C_OFDM0_TRMUXPAR, 0x000800e4);
rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1), 0x22204000);
if (sc->ntxchains > 1) {
rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00010000);
rtwn_bb_write(sc, R92C_LSSI_PARAM(1), 0x00010000);
}
rtwn_write_1(sc, R92C_TXPAUSE,
R92C_TX_QUEUE_AC | R92C_TX_QUEUE_MGT | R92C_TX_QUEUE_HIGH);
rtwn_write_1(sc, R92C_BCN_CTRL(0),
vals->bcn_ctrl[0] & ~R92C_BCN_CTRL_EN_BCN);
rtwn_write_1(sc, R92C_BCN_CTRL(1),
vals->bcn_ctrl[1] & ~R92C_BCN_CTRL_EN_BCN);
rtwn_write_1(sc, R92C_GPIO_MUXCFG,
vals->gpio_muxcfg & ~R92C_GPIO_MUXCFG_ENBT);
rtwn_bb_write(sc, 0x0b68, 0x00080000);
if (sc->ntxchains > 1)
rtwn_bb_write(sc, 0x0b6c, 0x00080000);
rtwn_bb_write(sc, 0x0e28, 0x80800000);
rtwn_bb_write(sc, 0x0e40, 0x01007c00);
rtwn_bb_write(sc, 0x0e44, 0x01004800);
rtwn_bb_write(sc, 0x0b68, 0x00080000);
for (chain = 0; chain < sc->ntxchains; chain++) {
if (chain > 0) {
/* Put chain 0 on standby. */
rtwn_bb_write(sc, 0x0e28, 0x00);
rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00010000);
rtwn_bb_write(sc, 0x0e28, 0x80800000);
/* Enable chain 1. */
for (i = 0; i < nitems(reg_adda); i++)
rtwn_bb_write(sc, reg_adda[i], 0x0b1b25a4);
}
/* Run IQ calibration twice. */
for (i = 0; i < 2; i++) {
int ret;
ret = r92ce_iq_calib_chain(sc, chain,
tx[chain], rx[chain]);
if (ret == 0) {
RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
"%s: chain %d: Tx failed.\n",
__func__, chain);
tx[chain][0] = 0xff;
tx[chain][1] = 0xff;
rx[chain][0] = 0xff;
rx[chain][1] = 0xff;
} else if (ret == 1) {
RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
"%s: chain %d: Rx failed.\n",
__func__, chain);
rx[chain][0] = 0xff;
rx[chain][1] = 0xff;
} else if (ret == 3) {
RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
"%s: chain %d: Both Tx and Rx "
"succeeded.\n", __func__, chain);
}
}
RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
"%s: results for run %d chain %d: tx[0] 0x%x, "
"tx[1] 0x%x, rx[0] 0x%x, rx[1] 0x%x\n", __func__, n, chain,
tx[chain][0], tx[chain][1], rx[chain][0], rx[chain][1]);
}
rtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA,
vals->ofdm0_trxpathena);
rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1),
vals->fpga0_rfifacesw1);
rtwn_bb_write(sc, R92C_OFDM0_TRMUXPAR, vals->ofdm0_trmuxpar);
rtwn_bb_write(sc, 0x0e28, 0x00);
rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00032ed3);
if (sc->ntxchains > 1)
rtwn_bb_write(sc, R92C_LSSI_PARAM(1), 0x00032ed3);
if (n != 0) {
if (!(hssi_param1 & R92C_HSSI_PARAM1_PI)) {
rtwn_bb_write(sc, R92C_HSSI_PARAM1(0), hssi_param1);
rtwn_bb_write(sc, R92C_HSSI_PARAM1(1), hssi_param1);
}
for (i = 0; i < nitems(reg_adda); i++)
rtwn_bb_write(sc, reg_adda[i], vals->adda[i]);
rtwn_write_1(sc, R92C_TXPAUSE, vals->txpause);
rtwn_write_1(sc, R92C_BCN_CTRL(0), vals->bcn_ctrl[0]);
rtwn_write_1(sc, R92C_BCN_CTRL(1), vals->bcn_ctrl[1]);
rtwn_write_4(sc, R92C_GPIO_MUXCFG, vals->gpio_muxcfg);
}
}
#define RTWN_IQ_CAL_MAX_TOLERANCE 5
static int
r92ce_iq_calib_compare_results(struct rtwn_softc *sc, uint16_t tx1[2][2],
uint16_t rx1[2][2], uint16_t tx2[2][2], uint16_t rx2[2][2])
{
int chain, i, tx_ok[2], rx_ok[2];
tx_ok[0] = tx_ok[1] = rx_ok[0] = rx_ok[1] = 0;
for (chain = 0; chain < sc->ntxchains; chain++) {
for (i = 0; i < 2; i++) {
if (tx1[chain][i] == 0xff || tx2[chain][i] == 0xff ||
rx1[chain][i] == 0xff || rx2[chain][i] == 0xff)
continue;
tx_ok[chain] = (abs(tx1[chain][i] - tx2[chain][i]) <=
RTWN_IQ_CAL_MAX_TOLERANCE);
rx_ok[chain] = (abs(rx1[chain][i] - rx2[chain][i]) <=
RTWN_IQ_CAL_MAX_TOLERANCE);
}
}
if (sc->ntxchains > 1)
return (tx_ok[0] && tx_ok[1] && rx_ok[0] && rx_ok[1]);
else
return (tx_ok[0] && rx_ok[0]);
}
#undef RTWN_IQ_CAL_MAX_TOLERANCE
static void
r92ce_iq_calib_write_results(struct rtwn_softc *sc, uint16_t tx[2],
uint16_t rx[2], int chain)
{
uint32_t reg, val, x;
long y, tx_c;
if (tx[0] == 0xff || tx[1] == 0xff)
return;
reg = rtwn_bb_read(sc, R92C_OFDM0_TXIQIMBALANCE(chain));
val = ((reg >> 22) & 0x3ff);
x = tx[0];
if (x & 0x00000200)
x |= 0xfffffc00;
reg = (((x * val) >> 8) & 0x3ff);
rtwn_bb_setbits(sc, R92C_OFDM0_TXIQIMBALANCE(chain), 0x3ff, reg);
rtwn_bb_setbits(sc, R92C_OFDM0_ECCATHRESHOLD, 0x80000000,
((x * val) & 0x80) << 24);
y = tx[1];
if (y & 0x00000200)
y |= 0xfffffc00;
tx_c = (y * val) >> 8;
rtwn_bb_setbits(sc, R92C_OFDM0_TXAFE(chain), 0xf0000000,
(tx_c & 0x3c0) << 22);
rtwn_bb_setbits(sc, R92C_OFDM0_TXIQIMBALANCE(chain), 0x003f0000,
(tx_c & 0x3f) << 16);
rtwn_bb_setbits(sc, R92C_OFDM0_ECCATHRESHOLD, 0x20000000,
((y * val) & 0x80) << 22);
if (rx[0] == 0xff || rx[1] == 0xff)
return;
rtwn_bb_setbits(sc, R92C_OFDM0_RXIQIMBALANCE(chain), 0x3ff,
rx[0] & 0x3ff);
rtwn_bb_setbits(sc, R92C_OFDM0_RXIQIMBALANCE(chain), 0xfc00,
(rx[1] & 0x3f) << 10);
if (chain == 0) {
rtwn_bb_setbits(sc, R92C_OFDM0_RXIQEXTANTA, 0xf0000000,
(rx[1] & 0x3c0) << 22);
} else {
rtwn_bb_setbits(sc, R92C_OFDM0_AGCRSSITABLE, 0xf000,
(rx[1] & 0x3c0) << 6);
}
}
#define RTWN_IQ_CAL_NRUN 3
void
r92ce_iq_calib(struct rtwn_softc *sc)
{
struct r92ce_iq_cal_reg_vals vals;
uint16_t tx[RTWN_IQ_CAL_NRUN][2][2], rx[RTWN_IQ_CAL_NRUN][2][2];
int n, valid;
valid = 0;
for (n = 0; n < RTWN_IQ_CAL_NRUN; n++) {
r92ce_iq_calib_run(sc, n, tx[n], rx[n], &vals);
if (n == 0)
continue;
/* Valid results remain stable after consecutive runs. */
valid = r92ce_iq_calib_compare_results(sc, tx[n - 1],
rx[n - 1], tx[n], rx[n]);
if (valid)
break;
}
if (valid) {
r92ce_iq_calib_write_results(sc, tx[n][0], rx[n][0], 0);
if (sc->ntxchains > 1)
r92ce_iq_calib_write_results(sc, tx[n][1], rx[n][1], 1);
}
}
#undef RTWN_IQ_CAL_NRUN

View File

@ -0,0 +1,77 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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/pci/rtwn_pci_var.h>
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#ifndef RTWN_WITHOUT_UCODE
void
r92ce_fw_reset(struct rtwn_softc *sc, int reason)
{
if (reason == RTWN_FW_RESET_CHECKSUM)
return;
r92c_fw_reset(sc, reason);
/*
* We must sleep for one second to let the firmware settle.
* Accessing registers too early will hang the whole system.
*/
if (reason == RTWN_FW_RESET_DOWNLOAD)
rtwn_delay(sc, 1000 * 1000);
}
#endif

View File

@ -0,0 +1,325 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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/pci/rtwn_pci_var.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
void
r92ce_init_intr(struct rtwn_softc *sc)
{
/* Disable interrupts. */
rtwn_write_4(sc, R92C_HISR, 0x00000000);
rtwn_write_4(sc, R92C_HIMR, 0x00000000);
}
void
r92ce_init_edca(struct rtwn_softc *sc)
{
/* SIFS */
rtwn_write_2(sc, R92C_SPEC_SIFS, 0x1010);
rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x1010);
rtwn_write_2(sc, R92C_SIFS_CCK, 0x1010);
rtwn_write_2(sc, R92C_SIFS_OFDM, 0x0e0e);
/* TXOP */
rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4322);
rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3222);
}
void
r92ce_init_bb(struct rtwn_softc *sc)
{
/* 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);
rtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
rtwn_write_1(sc, R92C_RF_CTRL,
R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
rtwn_write_1(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_DIO_PCIE | R92C_SYS_FUNC_EN_PCIEA |
R92C_SYS_FUNC_EN_PPLL | R92C_SYS_FUNC_EN_BB_GLB_RST |
R92C_SYS_FUNC_EN_BBRSTB);
rtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
rtwn_setbits_4(sc, R92C_LEDCFG0, 0, 0x00800000);
r92c_init_bb_common(sc);
}
int
r92ce_power_on(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
uint32_t reg;
int ntries;
/* Wait for autoload done bit. */
for (ntries = 0; ntries < 1000; ntries++) {
if (rtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
break;
DELAY(5);
}
if (ntries == 1000) {
device_printf(sc->sc_dev,
"timeout waiting for chip autoload\n");
return (ETIMEDOUT);
}
/* Unlock ISO/CLK/Power control register. */
rtwn_write_1(sc, R92C_RSV_CTRL, 0);
if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
/* bt coex */
rtwn_setbits_4(sc, R92C_APS_FSMCO, 0,
R92C_APS_FSMCO_SOP_ABG |
R92C_APS_FSMCO_SOP_AMB |
R92C_APS_FSMCO_XOP_BTCK);
}
/* Move SPS into PWM mode. */
rtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
/* Set low byte to 0x0f, leave others unchanged. */
rtwn_write_1(sc, R92C_AFE_XTAL_CTRL, 0x0f);
/* TODO: check if we need this for 8188CE */
if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
/* bt coex */
/* XXX magic from linux */
rtwn_setbits_4(sc, R92C_AFE_XTAL_CTRL, 0x024800, 0);
}
rtwn_setbits_2(sc, R92C_SYS_ISO_CTRL, 0xff00,
R92C_SYS_ISO_CTRL_PWC_EV12V | R92C_SYS_ISO_CTRL_DIOR);
DELAY(200);
/* TODO: linux does additional btcoex stuff here */
/* Auto enable WLAN. */
rtwn_setbits_2(sc, R92C_APS_FSMCO, 0, R92C_APS_FSMCO_APFM_ONMAC);
for (ntries = 0; ntries < 1000; ntries++) {
if (!(rtwn_read_2(sc, R92C_APS_FSMCO) &
R92C_APS_FSMCO_APFM_ONMAC))
break;
DELAY(5);
}
if (ntries == 1000) {
device_printf(sc->sc_dev, "timeout waiting for MAC auto ON\n");
return (ETIMEDOUT);
}
/* Enable radio, GPIO and LED functions. */
rtwn_write_2(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_AFSM_PCIE |
R92C_APS_FSMCO_PDN_EN |
R92C_APS_FSMCO_PFM_ALDN);
/* Release RF digital isolation. */
rtwn_setbits_2(sc, R92C_SYS_ISO_CTRL, R92C_SYS_ISO_CTRL_DIOR, 0);
if (rs->chip & R92C_CHIP_92C)
rtwn_write_1(sc, R92C_PCIE_CTRL_REG + 3, 0x77);
else
rtwn_write_1(sc, R92C_PCIE_CTRL_REG + 3, 0x22);
rtwn_write_4(sc, R92C_INT_MIG, 0);
if (rs->board_type != R92C_BOARD_TYPE_DONGLE) {
/* bt coex */
/* XXX magic from linux */
rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0x02, 0);
}
rtwn_setbits_1(sc, R92C_GPIO_MUXCFG, R92C_GPIO_MUXCFG_RFKILL, 0);
reg = rtwn_read_1(sc, R92C_GPIO_IO_SEL);
if (!(reg & R92C_GPIO_IO_SEL_RFKILL)) {
device_printf(sc->sc_dev,
"radio is disabled by hardware switch\n");
/* XXX how driver will know when radio will be enabled? */
return (EPERM);
}
/* Initialize MAC. */
rtwn_setbits_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF, 0);
for (ntries = 0; ntries < 200; ntries++) {
if (!(rtwn_read_1(sc, R92C_APSD_CTRL) &
R92C_APSD_CTRL_OFF_STATUS))
break;
DELAY(500);
}
if (ntries == 200) {
device_printf(sc->sc_dev,
"timeout waiting for MAC initialization\n");
return (ETIMEDOUT);
}
/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
rtwn_setbits_2(sc, R92C_CR, 0,
R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
((sc->sc_hwcrypto != RTWN_CRYPTO_SW) ? R92C_CR_ENSEC : 0));
rtwn_write_4(sc, R92C_MCUTST_1, 0x0);
return (0);
}
void
r92ce_power_off(struct rtwn_softc *sc)
{
#ifndef RTWN_WITHOUT_UCODE
struct r92c_softc *rs = sc->sc_priv;
/* Deinit C2H event handler. */
callout_stop(&rs->rs_c2h_report);
rs->rs_c2h_paused = 0;
rs->rs_c2h_pending = 0;
rs->rs_c2h_timeout = hz;
#endif
/* Stop hardware. */
/* Disable interrupts. */
rtwn_write_4(sc, R92C_HISR, 0);
rtwn_write_4(sc, R92C_HIMR, 0);
/* Stop hardware. */
rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
/* Turn off RF. */
rtwn_write_1(sc, R92C_RF_CTRL, 0);
/* Reset BB state machine */
rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, 0, R92C_SYS_FUNC_EN_BB_GLB_RST);
rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BB_GLB_RST, 0);
/* Disable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
rtwn_setbits_2(sc, R92C_CR,
R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
R92C_CR_ENSEC,
0);
/* If firmware in ram code, do reset. */
#ifndef RTWN_WITHOUT_UCODE
if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RAM_DL_SEL)
r92ce_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
#endif
/* TODO: linux does additional btcoex stuff here */
rtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0x80); /* linux magic number */
rtwn_write_1(sc, R92C_SPS0_CTRL, 0x23); /* ditto */
rtwn_write_1(sc, R92C_AFE_XTAL_CTRL, 0x0e); /* different with btcoex */
rtwn_write_1(sc, R92C_RSV_CTRL, 0x0e);
rtwn_write_1(sc, R92C_APS_FSMCO, R92C_APS_FSMCO_PDN_EN);
}
void
r92ce_init_ampdu(struct rtwn_softc *sc)
{
/* Setup AMPDU aggregation. */
rtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
rtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
}
void
r92ce_post_init(struct rtwn_softc *sc)
{
rtwn_write_2(sc, R92C_FWHW_TXQ_CTRL,
0x1f00 | R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW);
rtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
/* Perform LO and IQ calibrations. */
r92ce_iq_calib(sc);
/* Perform LC calibration. */
r92c_lc_calib(sc);
r92c_pa_bias_init(sc);
/* Fix for lower temperature. */
rtwn_write_1(sc, 0x15, 0xe9);
#ifndef RTWN_WITHOUT_UCODE
if (sc->sc_flags & RTWN_FW_LOADED) {
struct r92c_softc *rs = sc->sc_priv;
if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
/* XXX TODO: fix (see comment in r92cu_init.c) */
sc->sc_ratectl = RTWN_RATECTL_NET80211;
} else
sc->sc_ratectl = sc->sc_ratectl_sysctl;
/* Start C2H event handling. */
callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout,
r92c_handle_c2h_report, sc);
} else
#endif
sc->sc_ratectl = RTWN_RATECTL_NONE;
}

View File

@ -0,0 +1,69 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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/pci/rtwn_pci_var.h>
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
void
r92ce_set_led(struct rtwn_softc *sc, int led, int on)
{
if (led == RTWN_LED_LINK) {
rtwn_setbits_1(sc, R92C_LEDCFG2, 0x0f,
on ? R92C_LEDCFG2_EN : R92C_LEDCFG2_DIS);
sc->ledlink = on; /* Save LED state. */
}
}

View File

@ -0,0 +1,182 @@
/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef R92CE_PRIV_H
#define R92CE_PRIV_H
#include <dev/rtwn/rtl8192c/r92c_priv.h>
/*
* MAC initialization values.
*/
static const struct rtwn_mac_prog rtl8192ce_mac[] = {
{ 0x420, 0x80 }, { 0x423, 0x00 }, { 0x430, 0x00 }, { 0x431, 0x00 },
{ 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, { 0x435, 0x05 },
{ 0x436, 0x06 }, { 0x437, 0x07 }, { 0x438, 0x00 }, { 0x439, 0x00 },
{ 0x43a, 0x00 }, { 0x43b, 0x01 }, { 0x43c, 0x04 }, { 0x43d, 0x05 },
{ 0x43e, 0x06 }, { 0x43f, 0x07 }, { 0x440, 0x5d }, { 0x441, 0x01 },
{ 0x442, 0x00 }, { 0x444, 0x15 }, { 0x445, 0xf0 }, { 0x446, 0x0f },
{ 0x447, 0x00 }, { 0x458, 0x41 }, { 0x459, 0xa8 }, { 0x45a, 0x72 },
{ 0x45b, 0xb9 }, { 0x460, 0x88 }, { 0x461, 0x88 }, { 0x462, 0x06 },
{ 0x463, 0x03 }, { 0x4c8, 0x04 }, { 0x4c9, 0x08 }, { 0x4cc, 0x02 },
{ 0x4cd, 0x28 }, { 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 },
{ 0x515, 0x10 }, { 0x516, 0x0a }, { 0x517, 0x10 }, { 0x51a, 0x16 },
{ 0x524, 0x0f }, { 0x525, 0x4f }, { 0x546, 0x20 }, { 0x547, 0x00 },
{ 0x559, 0x02 }, { 0x55a, 0x02 }, { 0x55d, 0xff }, { 0x605, 0x30 },
{ 0x608, 0x0e }, { 0x609, 0x2a }, { 0x652, 0x20 }, { 0x63c, 0x0a },
{ 0x63d, 0x0e }, { 0x700, 0x21 }, { 0x701, 0x43 }, { 0x702, 0x65 },
{ 0x703, 0x87 }, { 0x708, 0x21 }, { 0x709, 0x43 }, { 0x70a, 0x65 },
{ 0x70b, 0x87 }
};
/*
* Baseband initialization values.
*/
static const uint16_t rtl8192ce_bb_regs0[] = {
0x024, 0x028, 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, 0x89c, 0x900, 0x904, 0x908,
0x90c, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18, 0xa1c,
0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 0xc00, 0xc04
}, rtl8192ce_bb_regs1[] = {
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
};
static const uint32_t rtl8192ce_bb_vals0_2t[] = {
0x0011800f, 0x00ffdb83, 0x80040002, 0x00000003, 0x0000fc00,
0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
0x01000100, 0x00390004, 0x01000100, 0x00390004, 0x27272727,
0x27272727, 0x27272727, 0x27272727, 0x00010000, 0x00010000,
0x27272727, 0x27272727, 0x00000000, 0x00000000, 0x569a569a,
0x0c1b25a4, 0x66e60230, 0x061f0130, 0x27272727, 0x2b2b2b27,
0x07000700, 0x22184000, 0x08080808, 0x00000000, 0xc0083070,
0x000004d5, 0x00000000, 0xcc0000c0, 0x00000800, 0xfffffffe,
0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
0x81121313, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
0x48071d40, 0x03a05633
}, rtl8192ce_bb_vals0_1t[] = {
0x0011800f, 0x00ffdb83, 0x80040000, 0x00000001, 0x0000fc00,
0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
0x01000100, 0x00390004, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x569a569a,
0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000, 0x32323200,
0x07000700, 0x22004000, 0x00000808, 0x00000000, 0xc0083070,
0x000004d5, 0x00000000, 0xccc000c0, 0x00000800, 0xfffffffe,
0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
0x48071d40, 0x03a05611
}, rtl8192ce_bb_vals1[] = {
0x000000e4, 0x6c6c6c6c, 0x08800000, 0x40000100, 0x08800000,
0x40000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x69e9ac44, 0x469652cf, 0x49795994, 0x0a97971c, 0x1f7c403f,
0x000100b7, 0xec020107, 0x007f037f, 0x69543420, 0x43bc0094,
0x69543420, 0x433c0094, 0x00000000, 0x5116848b, 0x47c00bff,
0x00000036, 0x2c7f000d, 0x018610db, 0x0000001f, 0x00b91612,
0x40000100, 0x20f60000, 0x40000100, 0x20200000, 0x00121820,
0x00000000, 0x00121820, 0x00007f7f, 0x00000000, 0x00000080,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x28000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x64b22427, 0x00766932, 0x00222222,
0x00000000, 0x37644302, 0x2f97d40c, 0x00080740
}, rtl8192ce_bb_vals4_1t[] = {
0x00000010, 0x001b25a4, 0x631b25a0, 0x631b25a0, 0x081b25a0,
0x081b25a0, 0x081b25a0, 0x081b25a0, 0x631b25a0, 0x081b25a0,
0x631b25a0, 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x001b25a0,
0x001b25a0, 0x6b1b25a0, 0x00000003, 0x00000000, 0x00000300
};
static const struct rtwn_bb_prog rtl8192ce_bb[] = {
{
nitems(rtl8192ce_bb_regs0),
rtl8192ce_bb_regs0,
rtl8192ce_bb_vals0_2t,
{ R92C_COND_RTL8192C },
&(const struct rtwn_bb_prog){
nitems(rtl8192ce_bb_regs0),
rtl8192ce_bb_regs0,
rtl8192ce_bb_vals0_1t,
{ 0 },
NULL
}
},
{
nitems(rtl8192ce_bb_regs1),
rtl8192ce_bb_regs1,
rtl8192ce_bb_vals1,
{ 0 },
NULL
},
{
nitems(rtl8192c_bb_regs3),
rtl8192c_bb_regs3,
rtl8192c_bb_vals3_92ce_92cu,
{ R92C_COND_RTL8192C },
&(const struct rtwn_bb_prog){
nitems(rtl8192c_bb_regs3),
rtl8192c_bb_regs3,
rtl8192c_bb_vals3_88cu_88ru,
{ 0 },
NULL
}
},
{
nitems(rtl8192c_bb_regs4),
rtl8192c_bb_regs4,
rtl8192c_bb_vals4,
{ 0 },
NULL
},
{
nitems(rtl8192c_bb_regs5),
rtl8192c_bb_regs5,
rtl8192c_bb_vals5_92ce_92cu,
{ R92C_COND_RTL8192C },
&(const struct rtwn_bb_prog){
nitems(rtl8192c_bb_regs5),
rtl8192c_bb_regs5,
rtl8192ce_bb_vals4_1t,
{ 0 },
NULL
}
}
};
#endif /* R92CE_PRIV_H */

View File

@ -0,0 +1,103 @@
/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef R92CE_REG_H
#define R92CE_REG_H
#include <dev/rtwn/rtl8192c/r92c_reg.h>
/*
* MAC registers.
*/
/* System Configuration. */
#define R92C_PCIE_MIO_INTF 0x0e4
#define R92C_PCIE_MIO_INTD 0x0e8
/* PCIe Configuration. */
#define R92C_PCIE_CTRL_REG 0x300
#define R92C_INT_MIG 0x304
#define R92C_BCNQ_DESA 0x308
#define R92C_HQ_DESA 0x310
#define R92C_MGQ_DESA 0x318
#define R92C_VOQ_DESA 0x320
#define R92C_VIQ_DESA 0x328
#define R92C_BEQ_DESA 0x330
#define R92C_BKQ_DESA 0x338
#define R92C_RX_DESA 0x340
#define R92C_DBI 0x348
#define R92C_MDIO 0x354
#define R92C_DBG_SEL 0x360
#define R92C_PCIE_HRPWM 0x361
#define R92C_PCIE_HCPWM 0x363
#define R92C_UART_CTRL 0x364
#define R92C_UART_TX_DES 0x370
#define R92C_UART_RX_DES 0x378
/* Bits for R92C_GPIO_MUXCFG. */
#define R92C_GPIO_MUXCFG_RFKILL 0x0008
/* Bits for R92C_GPIO_IO_SEL. */
#define R92C_GPIO_IO_SEL_RFKILL 0x0008
/* Bits for R92C_LEDCFG2. */
#define R92C_LEDCFG2_EN 0x60
#define R92C_LEDCFG2_DIS 0x68
/* Bits for R92C_HIMR. */
#define R92C_IMR_ROK 0x00000001 /* receive DMA OK */
#define R92C_IMR_VODOK 0x00000002 /* AC_VO DMA OK */
#define R92C_IMR_VIDOK 0x00000004 /* AC_VI DMA OK */
#define R92C_IMR_BEDOK 0x00000008 /* AC_BE DMA OK */
#define R92C_IMR_BKDOK 0x00000010 /* AC_BK DMA OK */
#define R92C_IMR_TXBDER 0x00000020 /* beacon transmit error */
#define R92C_IMR_MGNTDOK 0x00000040 /* management queue DMA OK */
#define R92C_IMR_TBDOK 0x00000080 /* beacon transmit OK */
#define R92C_IMR_HIGHDOK 0x00000100 /* high queue DMA OK */
#define R92C_IMR_BDOK 0x00000200 /* beacon queue DMA OK */
#define R92C_IMR_ATIMEND 0x00000400 /* ATIM window end interrupt */
#define R92C_IMR_RDU 0x00000800 /* Rx descriptor unavailable */
#define R92C_IMR_RXFOVW 0x00001000 /* receive FIFO overflow */
#define R92C_IMR_BCNINT 0x00002000 /* beacon DMA interrupt 0 */
#define R92C_IMR_PSTIMEOUT 0x00004000 /* powersave timeout */
#define R92C_IMR_TXFOVW 0x00008000 /* transmit FIFO overflow */
#define R92C_IMR_TIMEOUT1 0x00010000 /* timeout interrupt 1 */
#define R92C_IMR_TIMEOUT2 0x00020000 /* timeout interrupt 2 */
#define R92C_IMR_BCNDOK1 0x00040000 /* beacon queue DMA OK (1) */
#define R92C_IMR_BCNDOK2 0x00080000 /* beacon queue DMA OK (2) */
#define R92C_IMR_BCNDOK3 0x00100000 /* beacon queue DMA OK (3) */
#define R92C_IMR_BCNDOK4 0x00200000 /* beacon queue DMA OK (4) */
#define R92C_IMR_BCNDOK5 0x00400000 /* beacon queue DMA OK (5) */
#define R92C_IMR_BCNDOK6 0x00800000 /* beacon queue DMA OK (6) */
#define R92C_IMR_BCNDOK7 0x01000000 /* beacon queue DMA OK (7) */
#define R92C_IMR_BCNDOK8 0x02000000 /* beacon queue DMA OK (8) */
#define R92C_IMR_BCNDMAINT1 0x04000000 /* beacon DMA interrupt 1 */
#define R92C_IMR_BCNDMAINT2 0x08000000 /* beacon DMA interrupt 2 */
#define R92C_IMR_BCNDMAINT3 0x10000000 /* beacon DMA interrupt 3 */
#define R92C_IMR_BCNDMAINT4 0x20000000 /* beacon DMA interrupt 4 */
#define R92C_IMR_BCNDMAINT5 0x40000000 /* beacon DMA interrupt 5 */
#define R92C_IMR_BCNDMAINT6 0x80000000 /* beacon DMA interrupt 6 */
/* Shortcut. */
#define R92C_IBSS_INT_MASK \
(R92C_IMR_BCNINT | R92C_IMR_TBDOK | R92C_IMR_TBDER)
#endif /* R92CE_REG_H */

View File

@ -0,0 +1,134 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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/if_rtwn_debug.h>
#include <dev/rtwn/pci/rtwn_pci_var.h>
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_reg.h>
int
r92ce_classify_intr(struct rtwn_softc *sc, void *arg, int len __unused)
{
uint32_t status;
int *rings = arg;
int ret;
*rings = 0;
status = rtwn_read_4(sc, R92C_HISR);
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: HISR %08X, HISRE %04X\n",
__func__, status, rtwn_read_2(sc, R92C_HISRE));
if (status == 0 || status == 0xffffffff)
return (0);
/* Disable interrupts. */
rtwn_write_4(sc, R92C_HIMR, 0);
/* Ack interrupts. */
rtwn_write_4(sc, R92C_HISR, status);
if (status & R92C_IMR_BDOK)
*rings |= (1 << RTWN_PCI_BEACON_QUEUE);
if (status & R92C_IMR_HIGHDOK)
*rings |= (1 << RTWN_PCI_HIGH_QUEUE);
if (status & R92C_IMR_MGNTDOK)
*rings |= (1 << RTWN_PCI_MGNT_QUEUE);
if (status & R92C_IMR_BKDOK)
*rings |= (1 << RTWN_PCI_BK_QUEUE);
if (status & R92C_IMR_BEDOK)
*rings |= (1 << RTWN_PCI_BE_QUEUE);
if (status & R92C_IMR_VIDOK)
*rings |= (1 << RTWN_PCI_VI_QUEUE);
if (status & R92C_IMR_VODOK)
*rings |= (1 << RTWN_PCI_VO_QUEUE);
ret = 0;
if (status & R92C_IMR_RXFOVW)
ret |= RTWN_PCI_INTR_RX_OVERFLOW;
if (status & R92C_IMR_RDU)
ret |= RTWN_PCI_INTR_RX_DESC_UNAVAIL;
if (status & R92C_IMR_ROK)
ret |= RTWN_PCI_INTR_RX_DONE;
if (status & R92C_IMR_TXFOVW)
ret |= RTWN_PCI_INTR_TX_OVERFLOW;
if (status & R92C_IMR_PSTIMEOUT)
ret |= RTWN_PCI_INTR_PS_TIMEOUT;
return (ret);
}
#define R92C_INT_ENABLE (R92C_IMR_ROK | R92C_IMR_VODOK | R92C_IMR_VIDOK | \
R92C_IMR_BEDOK | R92C_IMR_BKDOK | R92C_IMR_MGNTDOK | \
R92C_IMR_HIGHDOK | R92C_IMR_BDOK | R92C_IMR_RDU | \
R92C_IMR_RXFOVW)
void
r92ce_enable_intr(struct rtwn_pci_softc *pc)
{
struct rtwn_softc *sc = &pc->pc_sc;
/* Enable interrupts. */
rtwn_write_4(sc, R92C_HIMR, R92C_INT_ENABLE);
}
void
r92ce_start_xfers(struct rtwn_softc *sc)
{
/* Clear pending interrupts. */
rtwn_write_4(sc, R92C_HISR, 0xffffffff);
/* Enable interrupts. */
rtwn_write_4(sc, R92C_HIMR, R92C_INT_ENABLE);
}
#undef R92C_INT_ENABLE

View File

@ -0,0 +1,41 @@
/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef R92CE_RX_DESC_H
#define R92CE_RX_DESC_H
#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
/* Rx MAC descriptor (PCIe). */
struct r92ce_rx_stat {
uint32_t rxdw0;
uint32_t rxdw1;
uint32_t rxdw2;
uint32_t rxdw3;
uint32_t rxdw4;
uint32_t tsf_low;
uint32_t rxbufaddr;
uint32_t rxbufaddr64;
} __packed __attribute__((aligned(4)));
#endif /* R92CE_RX_DESC_H */

View File

@ -0,0 +1,117 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $OpenBSD: if_rtwn.c,v 1.6 2015/08/28 00:03:53 deraadt Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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 <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.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/if_rtwn_debug.h>
#include <dev/rtwn/pci/rtwn_pci_var.h>
#include <dev/rtwn/rtl8192c/pci/r92ce.h>
#include <dev/rtwn/rtl8192c/pci/r92ce_tx_desc.h>
void
r92ce_setup_tx_desc(struct rtwn_pci_softc *pc, void *desc,
uint32_t next_desc_addr)
{
struct r92ce_tx_desc *txd = desc;
/* setup tx desc */
txd->nextdescaddr = htole32(next_desc_addr);
}
void
r92ce_tx_postsetup(struct rtwn_pci_softc *pc, void *desc,
bus_dma_segment_t segs[])
{
struct r92ce_tx_desc *txd = desc;
txd->txbufaddr = htole32(segs[0].ds_addr);
txd->txbufsize = txd->pktlen;
bus_space_barrier(pc->pc_st, pc->pc_sh, 0, pc->pc_mapsize,
BUS_SPACE_BARRIER_WRITE);
}
void
r92ce_copy_tx_desc(void *dest, const void *src)
{
struct r92ce_tx_desc *txd = dest;
size_t len = sizeof(struct r92c_tx_desc) +
sizeof(txd->txbufsize) + sizeof(txd->pad);
if (src != NULL)
memcpy(dest, src, len);
else
memset(dest, 0, len);
}
void
r92ce_dump_tx_desc(struct rtwn_softc *sc, const void *desc)
{
#ifdef RTWN_DEBUG
const struct r92ce_tx_desc *txd = desc;
RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT_DESC,
"%s: len %d, off %d, flags0 %02X, dw: 1 %08X, 2 %08X, 3 %04X "
"(seq %04X), 4 %08X, 5 %08X, 6 %08X, size %04X, pad %04X, "
"addr: %08X (64: %08X), next: %08X (64: %08X), "
"rsvd: %08X %08X %08X %08X\n",
__func__, le16toh(txd->pktlen), txd->offset, txd->flags0,
le32toh(txd->txdw1), le32toh(txd->txdw2), le16toh(txd->txdw3),
le16toh(txd->txdseq), le32toh(txd->txdw4), le32toh(txd->txdw5),
le32toh(txd->txdw6), le16toh(txd->txbufsize), le16toh(txd->pad),
le32toh(txd->txbufaddr), le32toh(txd->txbufaddr64),
le32toh(txd->nextdescaddr), le32toh(txd->nextdescaddr64),
le32toh(txd->reserved[0]), le32toh(txd->reserved[1]),
le32toh(txd->reserved[2]), le32toh(txd->reserved[3]));
#endif
}

View File

@ -0,0 +1,55 @@
/* $OpenBSD: if_rtwnreg.h,v 1.3 2015/06/14 08:02:47 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org>
* Copyright (c) 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.
*
* $FreeBSD$
*/
#ifndef R92CE_TX_DESC_H
#define R92CE_TX_DESC_H
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
/* Tx MAC descriptor (PCIe). */
struct r92ce_tx_desc {
uint16_t pktlen;
uint8_t offset;
uint8_t flags0;
uint32_t txdw1;
uint32_t txdw2;
uint16_t txdw3;
uint16_t txdseq;
uint32_t txdw4;
uint32_t txdw5;
uint32_t txdw6;
uint16_t txbufsize;
uint16_t pad;
uint32_t txbufaddr;
uint32_t txbufaddr64;
uint32_t nextdescaddr;
uint32_t nextdescaddr64;
uint32_t reserved[4];
} __packed __attribute__((aligned(4)));
#endif /* R92CE_TX_DESC_H */

View File

@ -0,0 +1,114 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef RTL8192C_H
#define RTL8192C_H
/*
* Global definitions.
*/
#define R92C_TXPKTBUF_COUNT 256
#define R92C_TX_PAGE_SIZE 128
#define R92C_RX_DMA_BUFFER_SIZE 0x2800
#define R92C_MAX_FW_SIZE 0x4000
#define R92C_MACID_MAX 31
#define R92C_CAM_ENTRY_COUNT 32
#define R92C_CALIB_THRESHOLD 2
/*
* Function declarations.
*/
/* r92c_attach.c */
void r92c_detach_private(struct rtwn_softc *);
void r92c_read_chipid_vendor(struct rtwn_softc *, uint32_t);
/* r92c_beacon.c */
void r92c_beacon_init(struct rtwn_softc *, void *, int);
void r92c_beacon_enable(struct rtwn_softc *, int, int);
/* r92c_calib.c */
void r92c_iq_calib(struct rtwn_softc *);
void r92c_lc_calib(struct rtwn_softc *);
void r92c_temp_measure(struct rtwn_softc *);
uint8_t r92c_temp_read(struct rtwn_softc *);
/* r92c_chan.c */
void r92c_get_txpower(struct rtwn_softc *, int,
struct ieee80211_channel *, uint16_t[]);
void r92c_set_bw20(struct rtwn_softc *, uint8_t);
void r92c_set_chan(struct rtwn_softc *, struct ieee80211_channel *);
void r92c_set_gain(struct rtwn_softc *, uint8_t);
void r92c_scan_start(struct ieee80211com *);
void r92c_scan_end(struct ieee80211com *);
/* r92c_fw.c */
#ifndef RTWN_WITHOUT_UCODE
void r92c_fw_reset(struct rtwn_softc *, int);
void r92c_fw_download_enable(struct rtwn_softc *, int);
#endif
void r92c_joinbss_rpt(struct rtwn_softc *, int);
#ifndef RTWN_WITHOUT_UCODE
int r92c_set_rsvd_page(struct rtwn_softc *, int, int, int);
int r92c_set_pwrmode(struct rtwn_softc *, struct ieee80211vap *, int);
void r92c_set_rssi(struct rtwn_softc *);
void r92c_handle_c2h_report(void *);
#endif
/* r92c_init.c */
int r92c_check_condition(struct rtwn_softc *, const uint8_t[]);
int r92c_set_page_size(struct rtwn_softc *);
void r92c_init_bb_common(struct rtwn_softc *);
int r92c_init_rf_chain(struct rtwn_softc *,
const struct rtwn_rf_prog *, int);
void r92c_init_rf(struct rtwn_softc *);
void r92c_init_edca(struct rtwn_softc *);
void r92c_init_ampdu(struct rtwn_softc *);
void r92c_init_antsel(struct rtwn_softc *);
void r92c_pa_bias_init(struct rtwn_softc *);
/* 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);
/* r92c_rom.c */
void r92c_efuse_postread(struct rtwn_softc *);
void r92c_parse_rom(struct rtwn_softc *, uint8_t *);
/* r92c_rx.c */
int8_t r92c_get_rssi_cck(struct rtwn_softc *, void *);
int8_t r92c_get_rssi_ofdm(struct rtwn_softc *, void *);
uint8_t r92c_rx_radiotap_flags(const void *);
/* r92c_tx.c */
void r92c_tx_enable_ampdu(void *, int);
void r92c_tx_setup_hwseq(void *);
void r92c_tx_setup_macid(void *, int);
void r92c_fill_tx_desc(struct rtwn_softc *, struct ieee80211_node *,
struct mbuf *, void *, uint8_t, int);
void r92c_fill_tx_desc_raw(struct rtwn_softc *, struct ieee80211_node *,
struct mbuf *, void *, const struct ieee80211_bpf_params *);
void r92c_fill_tx_desc_null(struct rtwn_softc *, void *, int, int, int);
uint8_t r92c_tx_radiotap_flags(const void *);
#endif /* RTL8192C_H */

View File

@ -0,0 +1,82 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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>
void
r92c_detach_private(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
free(rs, M_RTWN_PRIV);
}
void
r92c_read_chipid_vendor(struct rtwn_softc *sc, uint32_t reg_sys_cfg)
{
struct r92c_softc *rs = sc->sc_priv;
if (reg_sys_cfg & R92C_SYS_CFG_TYPE_92C) {
rs->chip |= R92C_CHIP_92C;
/* Check if it is a castrated 8192C. */
if (MS(rtwn_read_4(sc, R92C_HPON_FSM),
R92C_HPON_FSM_CHIP_BONDING_ID) ==
R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R)
rs->chip |= R92C_CHIP_92C_1T2R;
}
if (reg_sys_cfg & R92C_SYS_CFG_VENDOR_UMC) {
if (MS(reg_sys_cfg, R92C_SYS_CFG_CHIP_VER_RTL) == 0)
rs->chip |= R92C_CHIP_UMC_A_CUT;
}
}

View File

@ -0,0 +1,88 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/if_rtwnreg.h>
#include <dev/rtwn/if_rtwn_ridx.h>
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
void
r92c_beacon_init(struct rtwn_softc *sc, void *buf, int id)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
/*
* NB: there is no need to setup HWSEQ_EN bit;
* QSEL_BEACON already implies it.
*/
txd->flags0 |= R92C_FLAGS0_BMCAST | R92C_FLAGS0_FSG | R92C_FLAGS0_LSG;
txd->txdw1 |= htole32(
SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BEACON) |
SM(R92C_TXDW1_RAID, R92C_RAID_11B));
rtwn_r92c_tx_setup_macid(sc, buf, id);
txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, id));
txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, id));
txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, RTWN_RIDX_CCK1));
}
void
r92c_beacon_enable(struct rtwn_softc *sc, int id, int enable)
{
if (enable) {
rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
0, R92C_BCN_CTRL_EN_BCN);
} else {
rtwn_setbits_1(sc, R92C_BCN_CTRL(id),
R92C_BCN_CTRL_EN_BCN, 0);
}
}

View File

@ -0,0 +1,115 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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>
void
r92c_iq_calib(struct rtwn_softc *sc)
{
/* XXX TODO */
}
void
r92c_lc_calib(struct rtwn_softc *sc)
{
uint32_t rf_ac[2];
uint8_t txmode;
int i;
txmode = rtwn_read_1(sc, R92C_OFDM1_LSTF + 3);
if ((txmode & 0x70) != 0) {
/* Disable all continuous Tx. */
rtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode & ~0x70);
/* Set RF mode to standby mode. */
for (i = 0; i < sc->nrxchains; i++) {
rf_ac[i] = rtwn_rf_read(sc, i, R92C_RF_AC);
rtwn_rf_write(sc, i, R92C_RF_AC,
RW(rf_ac[i], R92C_RF_AC_MODE,
R92C_RF_AC_MODE_STANDBY));
}
} else {
/* Block all Tx queues. */
rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
}
/* Start calibration. */
rtwn_rf_setbits(sc, 0, R92C_RF_CHNLBW, 0, R92C_RF_CHNLBW_LCSTART);
/* Give calibration the time to complete. */
rtwn_delay(sc, 100000); /* 100ms */
/* Restore configuration. */
if ((txmode & 0x70) != 0) {
/* Restore Tx mode. */
rtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode);
/* Restore RF mode. */
for (i = 0; i < sc->nrxchains; i++)
rtwn_rf_write(sc, i, R92C_RF_AC, rf_ac[i]);
} else {
/* Unblock all Tx queues. */
rtwn_write_1(sc, R92C_TXPAUSE, 0x00);
}
}
void
r92c_temp_measure(struct rtwn_softc *sc)
{
rtwn_rf_write(sc, 0, R92C_RF_T_METER, R92C_RF_T_METER_START);
}
uint8_t
r92c_temp_read(struct rtwn_softc *sc)
{
return (MS(rtwn_rf_read(sc, 0, R92C_RF_T_METER),
R92C_RF_T_METER_VAL));
}

View File

@ -0,0 +1,353 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_priv.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
static int
r92c_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 <= 3) group = 0;
else if (chan <= 9) group = 1;
else if (chan <= 14) group = 2;
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);
}
/* XXX recheck */
void
r92c_get_txpower(struct rtwn_softc *sc, int chain,
struct ieee80211_channel *c, uint16_t power[RTWN_RIDX_COUNT])
{
struct r92c_softc *rs = sc->sc_priv;
struct rtwn_r92c_txpwr *rt = rs->rs_txpwr;
const struct rtwn_r92c_txagc *base = rs->rs_txagc;
uint8_t ofdmpow, htpow, diff, max;
int max_mcs, ridx, group;
/* Determine channel group. */
group = r92c_get_power_group(sc, c);
if (group == -1) { /* shouldn't happen */
device_printf(sc->sc_dev, "%s: incorrect channel\n", __func__);
return;
}
/* XXX net80211 regulatory */
max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
KASSERT(max_mcs <= RTWN_RIDX_COUNT, ("increase ridx limit\n"));
memset(power, 0, max_mcs * sizeof(power[0]));
if (rs->regulatory == 0) {
for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
power[ridx] = base[chain].pwr[0][ridx];
}
for (ridx = RTWN_RIDX_OFDM6; ridx < RTWN_RIDX_COUNT; ridx++) {
if (rs->regulatory == 3) {
power[ridx] = base[chain].pwr[0][ridx];
/* Apply vendor limits. */
if (IEEE80211_IS_CHAN_HT40(c))
max = rt->ht40_max_pwr[chain][group];
else
max = rt->ht20_max_pwr[chain][group];
if (power[ridx] > max)
power[ridx] = max;
} else if (rs->regulatory == 1) {
if (!IEEE80211_IS_CHAN_HT40(c))
power[ridx] = base[chain].pwr[group][ridx];
} else if (rs->regulatory != 2)
power[ridx] = base[chain].pwr[0][ridx];
}
/* Compute per-CCK rate Tx power. */
for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++)
power[ridx] += rt->cck_tx_pwr[chain][group];
htpow = rt->ht40_1s_tx_pwr[chain][group];
if (sc->ntxchains > 1) {
/* Apply reduction for 2 spatial streams. */
diff = rt->ht40_2s_tx_pwr_diff[chain][group];
htpow = (htpow > diff) ? htpow - diff : 0;
}
/* Compute per-OFDM rate Tx power. */
diff = rt->ofdm_tx_pwr_diff[chain][group];
ofdmpow = htpow + diff; /* HT->OFDM correction. */
for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
power[ridx] += ofdmpow;
/* Compute per-MCS Tx power. */
if (!IEEE80211_IS_CHAN_HT40(c)) {
diff = rt->ht20_tx_pwr_diff[chain][group];
htpow += diff; /* HT40->HT20 correction. */
}
for (ridx = RTWN_RIDX_MCS(0); ridx <= max_mcs; ridx++)
power[ridx] += htpow;
/* 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;
}
}
static void
r92c_write_txpower(struct rtwn_softc *sc, int chain,
uint16_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
r92c_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
uint16_t power[RTWN_RIDX_COUNT];
int i;
for (i = 0; i < sc->ntxchains; i++) {
/* Compute per-rate Tx power values. */
rtwn_r92c_get_txpower(sc, i, c, power);
#ifdef RTWN_DEBUG
if (sc->sc_debug & RTWN_DEBUG_TXPWR) {
int ridx;
/* Dump per-rate Tx power values. */
printf("Tx power for chain %d:\n", i);
for (ridx = RTWN_RIDX_CCK1;
ridx < RTWN_RIDX_COUNT;
ridx++)
printf("Rate %d = %u\n", ridx, power[ridx]);
}
#endif
/* Write per-rate Tx power values to hardware. */
r92c_write_txpower(sc, i, power);
}
}
static void
r92c_set_bw40(struct rtwn_softc *sc, uint8_t chan, int prichlo)
{
struct r92c_softc *rs = sc->sc_priv;
rtwn_setbits_1(sc, R92C_BWOPMODE, R92C_BWOPMODE_20MHZ, 0);
rtwn_setbits_1(sc, R92C_RRSR + 2, 0x6f, (prichlo ? 1 : 2) << 5);
rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, 0, R92C_RFMOD_40MHZ);
rtwn_bb_setbits(sc, R92C_FPGA1_RFMOD, 0, R92C_RFMOD_40MHZ);
/* Set CCK side band. */
rtwn_bb_setbits(sc, R92C_CCK0_SYSTEM, 0x10,
(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);
/* Select 40MHz bandwidth. */
rtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
(rs->rf_chnlbw[0] & ~0xfff) | chan);
}
void
r92c_set_bw20(struct rtwn_softc *sc, uint8_t chan)
{
struct r92c_softc *rs = sc->sc_priv;
rtwn_setbits_1(sc, R92C_BWOPMODE, 0, R92C_BWOPMODE_20MHZ);
rtwn_bb_setbits(sc, R92C_FPGA0_RFMOD, R92C_RFMOD_40MHZ, 0);
rtwn_bb_setbits(sc, R92C_FPGA1_RFMOD, R92C_RFMOD_40MHZ, 0);
rtwn_bb_setbits(sc, R92C_FPGA0_ANAPARAM2, 0,
R92C_FPGA0_ANAPARAM2_CBW20);
/* Select 20MHz bandwidth. */
rtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
(rs->rf_chnlbw[0] & ~0xfff) | chan | R92C_RF_CHNLBW_BW20);
}
void
r92c_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
struct r92c_softc *rs = sc->sc_priv;
u_int chan;
int i;
chan = rtwn_chan2centieee(c);
/* Set Tx power for this new channel. */
r92c_set_txpower(sc, c);
for (i = 0; i < sc->nrxchains; i++) {
rtwn_rf_write(sc, i, R92C_RF_CHNLBW,
RW(rs->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan));
}
if (IEEE80211_IS_CHAN_HT40(c))
r92c_set_bw40(sc, chan, IEEE80211_IS_CHAN_HT40U(c));
else
rtwn_r92c_set_bw20(sc, chan);
}
void
r92c_set_gain(struct rtwn_softc *sc, uint8_t gain)
{
rtwn_bb_setbits(sc, R92C_OFDM0_AGCCORE1(0),
R92C_OFDM0_AGCCORE1_GAIN_M, gain);
rtwn_bb_setbits(sc, R92C_OFDM0_AGCCORE1(1),
R92C_OFDM0_AGCCORE1_GAIN_M, gain);
}
void
r92c_scan_start(struct ieee80211com *ic)
{
struct rtwn_softc *sc = ic->ic_softc;
struct r92c_softc *rs = sc->sc_priv;
RTWN_LOCK(sc);
/* Set gain for scanning. */
rtwn_r92c_set_gain(sc, 0x20);
RTWN_UNLOCK(sc);
rs->rs_scan_start(ic);
}
void
r92c_scan_end(struct ieee80211com *ic)
{
struct rtwn_softc *sc = ic->ic_softc;
struct r92c_softc *rs = sc->sc_priv;
RTWN_LOCK(sc);
/* Set gain under link. */
rtwn_r92c_set_gain(sc, 0x32);
RTWN_UNLOCK(sc);
rs->rs_scan_end(ic);
}

View File

@ -0,0 +1,522 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/if_rtwn_rx.h>
#include <dev/rtwn/if_rtwn_task.h>
#include <dev/rtwn/if_rtwn_tx.h>
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/r92c_fw_cmd.h>
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
#ifndef RTWN_WITHOUT_UCODE
static int
r92c_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len)
{
struct r92c_fw_cmd cmd;
int ntries, error;
KASSERT(len <= sizeof(cmd.msg),
("%s: firmware command too long (%d > %zu)\n",
__func__, len, sizeof(cmd.msg)));
if (!(sc->sc_flags & RTWN_FW_LOADED)) {
RTWN_DPRINTF(sc, RTWN_DEBUG_FIRMWARE, "%s: firmware "
"was not loaded; command (id %u) will be discarded\n",
__func__, id);
return (0);
}
/* Wait for current FW box to be empty. */
for (ntries = 0; ntries < 50; ntries++) {
if (!(rtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur)))
break;
rtwn_delay(sc, 2000);
}
if (ntries == 100) {
device_printf(sc->sc_dev,
"could not send firmware command\n");
return (ETIMEDOUT);
}
memset(&cmd, 0, sizeof(cmd));
cmd.id = id;
if (len > 3) {
/* Ext command: [id : byte2 : byte3 : byte4 : byte0 : byte1] */
cmd.id |= R92C_CMD_FLAG_EXT;
memcpy(cmd.msg, (const uint8_t *)buf + 2, len - 2);
memcpy(cmd.msg + 3, buf, 2);
} else
memcpy(cmd.msg, buf, len);
/* Write the first word last since that will trigger the FW. */
if (len > 3) {
error = rtwn_write_2(sc, R92C_HMEBOX_EXT(sc->fwcur),
*(uint16_t *)((uint8_t *)&cmd + 4));
if (error != 0)
return (error);
}
error = rtwn_write_4(sc, R92C_HMEBOX(sc->fwcur),
*(uint32_t *)&cmd);
if (error != 0)
return (error);
sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
return (0);
}
void
r92c_fw_reset(struct rtwn_softc *sc, int reason)
{
int ntries;
if (reason == RTWN_FW_RESET_CHECKSUM)
return;
/* Tell 8051 to reset itself. */
rtwn_write_1(sc, R92C_HMETFR + 3, 0x20);
/* Wait until 8051 resets by itself. */
for (ntries = 0; ntries < 100; ntries++) {
if ((rtwn_read_2(sc, R92C_SYS_FUNC_EN) &
R92C_SYS_FUNC_EN_CPUEN) == 0)
return;
rtwn_delay(sc, 50);
}
/* Force 8051 reset. */
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_CPUEN, 0, 1);
}
void
r92c_fw_download_enable(struct rtwn_softc *sc, int enable)
{
if (enable) {
/* 8051 enable. */
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN, 0,
R92C_SYS_FUNC_EN_CPUEN, 1);
/* MCU firmware download enable. */
rtwn_setbits_1(sc, R92C_MCUFWDL, 0, R92C_MCUFWDL_EN);
/* 8051 reset. */
rtwn_setbits_1_shift(sc, R92C_MCUFWDL, R92C_MCUFWDL_ROM_DLEN,
0, 2);
} else {
/* MCU download disable. */
rtwn_setbits_1(sc, R92C_MCUFWDL, R92C_MCUFWDL_EN, 0);
/* Reserved for f/w extension. */
rtwn_write_1(sc, R92C_MCUFWDL + 1, 0);
}
}
#endif
/*
* Initialize firmware rate adaptation.
*/
#ifndef RTWN_WITHOUT_UCODE
static int
r92c_send_ra_cmd(struct rtwn_softc *sc, int macid, uint32_t rates,
int maxrate)
{
struct r92c_fw_cmd_macid_cfg cmd;
uint8_t mode;
int error = 0;
/* XXX should be called directly from iv_newstate() for MACID_BC */
/* XXX joinbss, not send_ra_cmd() */
#ifdef RTWN_TODO
/* NB: group addressed frames are done at 11bg rates for now */
if (ic->ic_curmode == IEEE80211_MODE_11B)
mode = R92C_RAID_11B;
else
mode = R92C_RAID_11BG;
/* XXX misleading 'mode' value here for unicast frames */
RTWN_DPRINTF(sc, RTWN_DEBUG_RA,
"%s: mode 0x%x, rates 0x%08x, basicrates 0x%08x\n", __func__,
mode, rates, basicrates);
/* Set rates mask for group addressed frames. */
cmd.macid = RTWN_MACID_BC | R92C_CMD_MACID_VALID;
cmd.mask = htole32(mode << 28 | basicrates);
error = rtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
if (error != 0) {
device_printf(sc->sc_dev,
"could not set RA mask for broadcast station\n");
return (error);
}
#endif
/* Set rates mask for unicast frames. */
if (maxrate >= RTWN_RIDX_MCS(0))
mode = R92C_RAID_11GN;
else if (maxrate >= RTWN_RIDX_OFDM6)
mode = R92C_RAID_11BG;
else
mode = R92C_RAID_11B;
cmd.macid = macid | R92C_CMD_MACID_VALID;
cmd.mask = htole32(mode << 28 | rates);
error = r92c_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
if (error != 0) {
device_printf(sc->sc_dev,
"%s: could not set RA mask for %d station\n",
__func__, macid);
return (error);
}
return (0);
}
#endif
static void
r92c_init_ra(struct rtwn_softc *sc, int macid)
{
struct ieee80211_htrateset *rs_ht;
struct ieee80211_node *ni;
uint32_t rates;
int maxrate;
RTWN_NT_LOCK(sc);
if (sc->node_list[macid] == NULL) {
RTWN_DPRINTF(sc, RTWN_DEBUG_RA, "%s: macid %d, ni is NULL\n",
__func__, macid);
RTWN_NT_UNLOCK(sc);
return;
}
ni = ieee80211_ref_node(sc->node_list[macid]);
if (ni->ni_flags & IEEE80211_NODE_HT)
rs_ht = &ni->ni_htrates;
else
rs_ht = NULL;
/* XXX MACID_BC */
rtwn_get_rates(sc, &ni->ni_rates, rs_ht, &rates, &maxrate, 0);
RTWN_NT_UNLOCK(sc);
#ifndef RTWN_WITHOUT_UCODE
if (sc->sc_ratectl == RTWN_RATECTL_FW) {
r92c_send_ra_cmd(sc, macid, rates, maxrate);
}
#endif
rtwn_write_1(sc, R92C_INIDATA_RATE_SEL(macid), maxrate);
ieee80211_free_node(ni);
}
void
r92c_joinbss_rpt(struct rtwn_softc *sc, int macid)
{
#ifndef RTWN_WITHOUT_UCODE
struct r92c_softc *rs = sc->sc_priv;
struct ieee80211vap *vap;
struct r92c_fw_cmd_joinbss_rpt cmd;
if (sc->vaps[0] == NULL) /* XXX fix */
goto end;
vap = &sc->vaps[0]->vap;
if ((vap->iv_state == IEEE80211_S_RUN) ^
!(rs->rs_flags & R92C_FLAG_ASSOCIATED))
goto end;
if (rs->rs_flags & R92C_FLAG_ASSOCIATED) {
cmd.mstatus = R92C_MSTATUS_DISASSOC;
rs->rs_flags &= ~R92C_FLAG_ASSOCIATED;
} else {
cmd.mstatus = R92C_MSTATUS_ASSOC;
rs->rs_flags |= R92C_FLAG_ASSOCIATED;
}
if (r92c_fw_cmd(sc, R92C_CMD_JOINBSS_RPT, &cmd, sizeof(cmd)) != 0) {
device_printf(sc->sc_dev, "%s: cannot change media status!\n",
__func__);
}
end:
#endif
/* TODO: init rates for RTWN_MACID_BC. */
if (macid & RTWN_MACID_VALID)
r92c_init_ra(sc, macid & ~RTWN_MACID_VALID);
}
#ifndef RTWN_WITHOUT_UCODE
int
r92c_set_rsvd_page(struct rtwn_softc *sc, int probe_resp, int null,
int qos_null)
{
struct r92c_fw_cmd_rsvdpage rsvd;
rsvd.probe_resp = probe_resp;
rsvd.ps_poll = 0;
rsvd.null_data = null;
return (r92c_fw_cmd(sc, R92C_CMD_RSVD_PAGE, &rsvd, sizeof(rsvd)));
}
int
r92c_set_pwrmode(struct rtwn_softc *sc, struct ieee80211vap *vap,
int off)
{
struct r92c_fw_cmd_pwrmode mode;
int error;
/* XXX dm_RF_saving */
if (off && vap->iv_state == IEEE80211_S_RUN &&
(vap->iv_flags & IEEE80211_F_PMGTON))
mode.mode = R92C_PWRMODE_MIN;
else
mode.mode = R92C_PWRMODE_CAM;
mode.smart_ps = R92C_PWRMODE_SMARTPS_NULLDATA;
mode.bcn_pass = 1; /* XXX */
error = r92c_fw_cmd(sc, R92C_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);
}
void
r92c_set_rssi(struct rtwn_softc *sc)
{
struct ieee80211_node *ni;
struct rtwn_node *rn;
struct r92c_fw_cmd_rssi cmd;
int i;
cmd.reserved = 0;
RTWN_NT_LOCK(sc);
for (i = 0; i < sc->macid_limit; i++) {
/* XXX optimize? */
ni = sc->node_list[i];
if (ni == NULL)
continue;
rn = RTWN_NODE(ni);
cmd.macid = i;
cmd.pwdb = rn->avg_pwdb;
RTWN_DPRINTF(sc, RTWN_DEBUG_RSSI,
"%s: sending RSSI command (macid %d, rssi %d)\n",
__func__, i, rn->avg_pwdb);
RTWN_NT_UNLOCK(sc);
r92c_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd, sizeof(cmd));
RTWN_NT_LOCK(sc);
}
RTWN_NT_UNLOCK(sc);
}
static void
r92c_ratectl_tx_complete(struct rtwn_softc *sc, uint8_t *buf, int len)
{
#if __FreeBSD_version >= 1200012
struct ieee80211_ratectl_tx_status txs;
#endif
struct r92c_c2h_tx_rpt *rpt;
struct ieee80211_node *ni;
uint8_t macid;
int ntries;
if (sc->sc_ratectl != RTWN_RATECTL_NET80211) {
/* shouldn't happen */
device_printf(sc->sc_dev, "%s called while ratectl = %d!\n",
__func__, sc->sc_ratectl);
return;
}
rpt = (struct r92c_c2h_tx_rpt *)buf;
if (len != sizeof(*rpt)) {
device_printf(sc->sc_dev,
"%s: wrong report size (%d, must be %zu)\n",
__func__, len, sizeof(*rpt));
return;
}
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
"%s: ccx report dump: 0: %02X, 1: %02X, queue time: "
"low %02X, high %02X, 4: %02X, 5: %02X, 6: %02X, 7: %02X\n",
__func__, rpt->rptb0, rpt->rptb1, rpt->queue_time_low,
rpt->queue_time_high, rpt->rptb4, rpt->rptb5, rpt->rptb6,
rpt->rptb7);
macid = MS(rpt->rptb5, R92C_RPTB5_MACID);
if (macid > sc->macid_limit) {
device_printf(sc->sc_dev,
"macid %u is too big; increase MACID_MAX limit\n",
macid);
return;
}
ntries = MS(rpt->rptb0, R92C_RPTB0_RETRY_CNT);
RTWN_NT_LOCK(sc);
ni = sc->node_list[macid];
if (ni != NULL) {
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: frame for macid %u was"
"%s sent (%d retries)\n", __func__, macid,
(rpt->rptb7 & R92C_RPTB7_PKT_OK) ? "" : " not",
ntries);
#if __FreeBSD_version >= 1200012
txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY;
txs.long_retries = ntries;
if (rpt->rptb7 & R92C_RPTB7_PKT_OK)
txs.status = IEEE80211_RATECTL_TX_SUCCESS;
else if (rpt->rptb6 & R92C_RPTB6_RETRY_OVER)
txs.status = IEEE80211_RATECTL_TX_FAIL_LONG; /* XXX */
else if (rpt->rptb6 & R92C_RPTB6_LIFE_EXPIRE)
txs.status = IEEE80211_RATECTL_TX_FAIL_EXPIRED;
else
txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
ieee80211_ratectl_tx_complete(ni, &txs);
#else
struct ieee80211vap *vap = ni->ni_vap;
if (rpt->rptb7 & R92C_RPTB7_PKT_OK) {
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS, &ntries, NULL);
} else {
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &ntries, NULL);
}
#endif
} else {
RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: macid %u, ni is NULL\n",
__func__, macid);
}
RTWN_NT_UNLOCK(sc);
#ifdef IEEE80211_SUPPORT_SUPERG
if (sc->sc_tx_n_active > 0 && --sc->sc_tx_n_active <= 1)
rtwn_cmd_sleepable(sc, NULL, 0, rtwn_ff_flush_all);
#endif
}
static void
r92c_handle_c2h_task(struct rtwn_softc *sc, union sec_param *data)
{
const uint16_t off = R92C_C2H_EVT_MSG + sizeof(struct r92c_c2h_evt);
struct r92c_softc *rs = sc->sc_priv;
uint16_t buf[R92C_C2H_MSG_MAX_LEN / 2 + 1];
uint8_t id, len, status;
int i;
/* Do not reschedule the task if device is not running. */
if (!(sc->sc_flags & RTWN_RUNNING))
return;
/* Read current status. */
status = rtwn_read_1(sc, R92C_C2H_EVT_CLEAR);
if (status == R92C_C2H_EVT_HOST_CLOSE)
goto end; /* nothing to do */
else if (status == R92C_C2H_EVT_FW_CLOSE) {
len = rtwn_read_1(sc, R92C_C2H_EVT_MSG);
id = MS(len, R92C_C2H_EVTB0_ID);
len = MS(len, R92C_C2H_EVTB0_LEN);
memset(buf, 0, sizeof(buf));
/* Try to optimize event reads. */
for (i = 0; i < len; i += 2)
buf[i / 2] = rtwn_read_2(sc, off + i);
KASSERT(i < sizeof(buf), ("%s: buffer overrun (%d >= %zu)!",
__func__, i, sizeof(buf)));
switch (id) {
case R92C_C2H_EVT_TX_REPORT:
r92c_ratectl_tx_complete(sc, (uint8_t *)buf, len);
break;
default:
device_printf(sc->sc_dev,
"%s: C2H report %u (len %u) was not handled\n",
__func__, id, len);
break;
}
}
/* Prepare for next event. */
rtwn_write_1(sc, R92C_C2H_EVT_CLEAR, R92C_C2H_EVT_HOST_CLOSE);
end:
/* Adjust timeout for next call. */
if (rs->rs_c2h_pending != 0) {
rs->rs_c2h_pending = 0;
rs->rs_c2h_paused = 0;
} else
rs->rs_c2h_paused++;
if (rs->rs_c2h_paused > R92C_TX_PAUSED_THRESHOLD)
rs->rs_c2h_timeout = hz;
else
rs->rs_c2h_timeout = MAX(hz / 100, 1);
/* Reschedule the task. */
callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout,
r92c_handle_c2h_report, sc);
}
void
r92c_handle_c2h_report(void *arg)
{
struct rtwn_softc *sc = arg;
rtwn_cmd_sleepable(sc, NULL, 0, r92c_handle_c2h_task);
}
#endif /* RTWN_WITHOUT_UCODE */

View File

@ -0,0 +1,148 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92C_FW_CMD_H
#define R92C_FW_CMD_H
/*
* Host to firmware commands.
*/
struct r92c_fw_cmd {
uint8_t id;
#define R92C_CMD_SET_PWRMODE 1
#define R92C_CMD_JOINBSS_RPT 2
#define R92C_CMD_RSVD_PAGE 3
#define R92C_CMD_RSSI_SETTING 5
#define R92C_CMD_MACID_CONFIG 6
#define R92C_CMD_FLAG_EXT 0x80
uint8_t msg[5];
} __packed __attribute__((aligned(4)));
/* Structure for R92C_CMD_JOINBSS_RPT. */
struct r92c_fw_cmd_joinbss_rpt {
uint8_t mstatus;
#define R92C_MSTATUS_DISASSOC 0x00
#define R92C_MSTATUS_ASSOC 0x01
} __packed;
/* Structure for R92C_CMD_SET_PWRMODE. */
struct r92c_fw_cmd_pwrmode {
uint8_t mode;
#define R92C_PWRMODE_CAM 0
#define R92C_PWRMODE_MIN 1
#define R92C_PWRMODE_MAX 2
#define R92C_PWRMODE_DTIM 3
#define R92C_PWRMODE_UAPSD_WMM 5
#define R92C_PWRMODE_UAPSD 6
#define R92C_PWRMODE_IBSS 7
uint8_t smart_ps;
/* XXX undocumented */
#define R92C_PWRMODE_SMARTPS_NULLDATA 2
uint8_t bcn_pass; /* unit: beacon interval */
} __packed;
/* Structure for R92C_CMD_RSVD_PAGE. */
struct r92c_fw_cmd_rsvdpage {
uint8_t probe_resp;
uint8_t ps_poll;
uint8_t null_data;
} __packed;
/* Structure for R92C_CMD_RSSI_SETTING. */
struct r92c_fw_cmd_rssi {
uint8_t macid;
uint8_t reserved;
uint8_t pwdb;
} __packed;
/* Structure for R92C_CMD_MACID_CONFIG. */
struct r92c_fw_cmd_macid_cfg {
uint32_t mask;
uint8_t macid;
#define R92C_CMD_MACID_VALID 0x80
} __packed;
/*
* C2H event structure.
*/
/* Bigger value is used to prevent buffer overrun. */
#define R92C_C2H_MSG_MAX_LEN 16
struct r92c_c2h_evt {
uint8_t evtb0;
#define R92C_C2H_EVTB0_ID_M 0x0f
#define R92C_C2H_EVTB0_ID_S 0
#define R92C_C2H_EVTB0_LEN_M 0xf0
#define R92C_C2H_EVTB0_LEN_S 4
uint8_t seq;
/* Followed by payload (see below). */
} __packed;
/*
* C2H event types.
*/
#define R92C_C2H_EVT_DEBUG 0
#define R92C_C2H_EVT_TX_REPORT 3
#define R92C_C2H_EVT_EXT_RA_RPT 6
/* Structure for R92C_C2H_EVT_TX_REPORT event. */
struct r92c_c2h_tx_rpt {
uint8_t rptb0;
#define R92C_RPTB0_RETRY_CNT_M 0x3f
#define R92C_RPTB0_RETRY_CNT_S 0
uint8_t rptb1; /* XXX junk */
#define R92C_RPTB1_RTS_RETRY_CNT_M 0x3f
#define R92C_RPTB1_RTS_RETRY_CNT_S 0
uint8_t queue_time_low;
uint8_t queue_time_high;
uint8_t rptb4;
#define R92C_RPTB4_MISSED_PKT_NUM_M 0x1f
#define R92C_RPTB4_MISSED_PKT_NUM_S 0
uint8_t rptb5;
#define R92C_RPTB5_MACID_M 0x1f
#define R92C_RPTB5_MACID_S 0
#define R92C_RPTB5_DES1_FRAGSSN_M 0xe0
#define R92C_RPTB5_DES1_FRAGSSN_S 5
uint8_t rptb6;
#define R92C_RPTB6_RPT_PKT_NUM_M 0x1f
#define R92C_RPTB6_RPT_PKT_NUM_S 0
#define R92C_RPTB6_PKT_DROP 0x20
#define R92C_RPTB6_LIFE_EXPIRE 0x40
#define R92C_RPTB6_RETRY_OVER 0x80
uint8_t rptb7;
#define R92C_RPTB7_EDCA_M 0x0f
#define R92C_RPTB7_EDCA_S 0
#define R92C_RPTB7_BMC 0x20
#define R92C_RPTB7_PKT_OK 0x40
#define R92C_RPTB7_INT_CCX 0x80
} __packed;
#endif /* R92C_FW_CMD_H */

View File

@ -0,0 +1,319 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8192c/r92c_priv.h>
#include <dev/rtwn/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
int
r92c_check_condition(struct rtwn_softc *sc, const uint8_t cond[])
{
struct r92c_softc *rs = sc->sc_priv;
uint8_t mask;
int i;
if (cond[0] == 0)
return (1);
RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
"%s: condition byte 0: %02X; chip %02X, board %02X\n",
__func__, cond[0], rs->chip, rs->board_type);
if (!(rs->chip & R92C_CHIP_92C)) {
if (rs->board_type == R92C_BOARD_TYPE_HIGHPA)
mask = R92C_COND_RTL8188RU;
else if (rs->board_type == R92C_BOARD_TYPE_MINICARD)
mask = R92C_COND_RTL8188CE;
else
mask = R92C_COND_RTL8188CU;
} else {
if (rs->board_type == R92C_BOARD_TYPE_MINICARD)
mask = R92C_COND_RTL8192CE;
else
mask = R92C_COND_RTL8192CU;
}
for (i = 0; i < RTWN_MAX_CONDITIONS && cond[i] != 0; i++)
if ((cond[i] & mask) == mask)
return (1);
return (0);
}
int
r92c_set_page_size(struct rtwn_softc *sc)
{
return (rtwn_write_1(sc, R92C_PBP, SM(R92C_PBP_PSRX, R92C_PBP_128) |
SM(R92C_PBP_PSTX, R92C_PBP_128)) == 0);
}
void
r92c_init_bb_common(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
int i, j;
/* 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);
}
}
if (rs->chip & R92C_CHIP_92C_1T2R) {
/* 8192C 1T only configuration. */
rtwn_bb_setbits(sc, R92C_FPGA0_TXINFO, 0x03, 0x02);
rtwn_bb_setbits(sc, R92C_FPGA1_TXINFO, 0x300033, 0x200022);
rtwn_bb_setbits(sc, R92C_CCK0_AFESETTING, 0xff000000,
0x45000000);
rtwn_bb_setbits(sc, R92C_OFDM0_TRXPATHENA, 0xff, 0x23);
rtwn_bb_setbits(sc, R92C_OFDM0_AGCPARAM1, 0x30, 0x10);
rtwn_bb_setbits(sc, 0xe74, 0x0c000000, 0x08000000);
rtwn_bb_setbits(sc, 0xe78, 0x0c000000, 0x08000000);
rtwn_bb_setbits(sc, 0xe7c, 0x0c000000, 0x08000000);
rtwn_bb_setbits(sc, 0xe80, 0x0c000000, 0x08000000);
rtwn_bb_setbits(sc, 0xe88, 0x0c000000, 0x08000000);
}
/* 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;
}
int
r92c_init_rf_chain(struct rtwn_softc *sc,
const struct rtwn_rf_prog *rf_prog, int chain)
{
int i, j;
RTWN_DPRINTF(sc, RTWN_DEBUG_RESET, "%s: chain %d\n",
__func__, chain);
for (i = 0; rf_prog[i].reg != NULL; i++) {
const struct rtwn_rf_prog *prog = &rf_prog[i];
while (!rtwn_check_condition(sc, prog->cond)) {
KASSERT(prog->next != NULL,
("%s: wrong condition value (i %d)\n",
__func__, i));
prog = prog->next;
}
for (j = 0; j < prog->count; j++) {
RTWN_DPRINTF(sc, RTWN_DEBUG_RESET,
"RF: reg 0x%02x, val 0x%05x\n",
prog->reg[j], prog->val[j]);
/*
* These are fake RF registers offsets that
* indicate a delay is required.
*/
/* NB: we are using 'value' to store required delay. */
if (prog->reg[j] > 0xf8) {
rtwn_delay(sc, prog->val[j]);
continue;
}
rtwn_rf_write(sc, chain, prog->reg[j], prog->val[j]);
rtwn_delay(sc, 1);
}
}
return (i);
}
void
r92c_init_rf(struct rtwn_softc *sc)
{
struct r92c_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);
/* Restore RF_ENV control type. */
rtwn_bb_setbits(sc, R92C_FPGA0_RFIFACESW(idx),
0x10 << off, type << off);
/* Cache RF register CHNLBW. */
rs->rf_chnlbw[chain] = rtwn_rf_read(sc, chain,
R92C_RF_CHNLBW);
}
if ((rs->chip & (R92C_CHIP_UMC_A_CUT | R92C_CHIP_92C)) ==
R92C_CHIP_UMC_A_CUT) {
rtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255);
rtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00);
}
/* 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);
}
void
r92c_init_edca(struct rtwn_softc *sc)
{
/* SIFS */
rtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
rtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
rtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
rtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
/* TXOP */
rtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
rtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
rtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324);
rtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226);
}
void
r92c_init_ampdu(struct rtwn_softc *sc)
{
/* Setup AMPDU aggregation. */
rtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
rtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
rtwn_write_2(sc, R92C_MAX_AGGR_NUM, 0x0708);
}
void
r92c_init_antsel(struct rtwn_softc *sc)
{
uint32_t reg;
if (sc->ntxchains != 1 || sc->nrxchains != 1)
return;
rtwn_setbits_1(sc, R92C_LEDCFG2, 0, 0x80);
rtwn_bb_setbits(sc, R92C_FPGA0_RFPARAM(0), 0, 0x2000);
reg = rtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(0));
sc->sc_ant = MS(reg, R92C_FPGA0_RFIFACEOE0_ANT); /* XXX */
}
void
r92c_pa_bias_init(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
int i;
for (i = 0; i < sc->nrxchains; i++) {
if (rs->pa_setting & (1 << i))
continue;
r92c_rf_write(sc, i, R92C_RF_IPA, 0x0f406);
r92c_rf_write(sc, i, R92C_RF_IPA, 0x4f406);
r92c_rf_write(sc, i, R92C_RF_IPA, 0x8f406);
r92c_rf_write(sc, i, R92C_RF_IPA, 0xcf406);
}
if (!(rs->pa_setting & 0x10))
rtwn_setbits_1(sc, 0x16, 0xf0, 0x90);
}

View File

@ -0,0 +1,408 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92C_PRIV_H
#define R92C_PRIV_H
#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
/*
* Parsed Tx power (diff) values.
*/
struct rtwn_r92c_txpwr {
uint8_t cck_tx_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
uint8_t ht40_1s_tx_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
int8_t ht40_2s_tx_pwr_diff[R92C_MAX_CHAINS][R92C_GROUP_2G];
int8_t ht20_tx_pwr_diff[R92C_MAX_CHAINS][R92C_GROUP_2G];
int8_t ofdm_tx_pwr_diff[R92C_MAX_CHAINS][R92C_GROUP_2G];
int8_t ht40_max_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
int8_t ht20_max_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
};
/*
* Baseband initialization values (shared parts).
*/
#define R92C_COND_RTL8188CE 0x01
#define R92C_COND_RTL8188CU 0x02
#define R92C_COND_RTL8188RU 0x04
#define R92C_COND_RTL8192CE 0x08
#define R92C_COND_RTL8192CU 0x10
/* Shortcut. */
#define R92C_COND_RTL8192C (R92C_COND_RTL8192CE | R92C_COND_RTL8192CU)
static const uint16_t rtl8192c_bb_regs3[] = {
0xd04
}, rtl8192c_bb_regs4[] = {
0xd08, 0xd0c, 0xd10, 0xd14, 0xd18, 0xd2c, 0xd30, 0xd34, 0xd38,
0xd3c, 0xd40, 0xd44, 0xd48, 0xd4c, 0xd50, 0xd54, 0xd58, 0xd5c,
0xd60, 0xd64, 0xd68, 0xd6c, 0xd70, 0xd74, 0xd78, 0xe00, 0xe04,
0xe08, 0xe10, 0xe14, 0xe18, 0xe1c, 0xe28, 0xe30, 0xe34, 0xe38,
0xe3c, 0xe40, 0xe44, 0xe48, 0xe4c, 0xe50, 0xe54, 0xe58, 0xe5c
}, rtl8192c_bb_regs5[] = {
0xe60, 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec, 0xf14,
0xf4c, 0xf00
};
static const uint32_t rtl8192c_bb_vals3_88cu_88ru[] = {
0x00020401
}, rtl8192c_bb_vals3_92ce_92cu[] = {
0x00020403
}, rtl8192c_bb_vals4[] = {
0x0000907f, 0x20010201, 0xa0633333, 0x3333bc43, 0x7a8f5b6b,
0xcc979975, 0x00000000, 0x80608000, 0x00000000, 0x00027293,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6437140a,
0x00000000, 0x00000000, 0x30032064, 0x4653de68, 0x04518a3c,
0x00002101, 0x2a201c16, 0x1812362e, 0x322c2220, 0x000e3c24,
0x2a2a2a2a, 0x2a2a2a2a, 0x03902a2a, 0x2a2a2a2a, 0x2a2a2a2a,
0x2a2a2a2a, 0x2a2a2a2a, 0x00000000, 0x1000dc1f, 0x10008c1f,
0x02140102, 0x681604c2, 0x01007c00, 0x01004800, 0xfb000000,
0x000028d1, 0x1000dc1f, 0x10008c1f, 0x02140102, 0x28160d05
},rtl8192c_bb_vals5_92ce_92cu[] = {
0x00000010, 0x001b25a4, 0x63db25a4, 0x63db25a4, 0x0c1b25a4,
0x0c1b25a4, 0x0c1b25a4, 0x0c1b25a4, 0x63db25a4, 0x0c1b25a4,
0x63db25a4, 0x63db25a4, 0x63db25a4, 0x63db25a4, 0x001b25a4,
0x001b25a4, 0x6fdb25a4, 0x00000003, 0x00000000, 0x00000300
};
/*
* RTL8192CU and RTL8192CE-VAU.
*/
static const uint32_t rtl8192ce_agc_vals[] = {
0x7b000001, 0x7b010001, 0x7b020001, 0x7b030001, 0x7b040001,
0x7b050001, 0x7a060001, 0x79070001, 0x78080001, 0x77090001,
0x760a0001, 0x750b0001, 0x740c0001, 0x730d0001, 0x720e0001,
0x710f0001, 0x70100001, 0x6f110001, 0x6e120001, 0x6d130001,
0x6c140001, 0x6b150001, 0x6a160001, 0x69170001, 0x68180001,
0x67190001, 0x661a0001, 0x651b0001, 0x641c0001, 0x631d0001,
0x621e0001, 0x611f0001, 0x60200001, 0x49210001, 0x48220001,
0x47230001, 0x46240001, 0x45250001, 0x44260001, 0x43270001,
0x42280001, 0x41290001, 0x402a0001, 0x262b0001, 0x252c0001,
0x242d0001, 0x232e0001, 0x222f0001, 0x21300001, 0x20310001,
0x06320001, 0x05330001, 0x04340001, 0x03350001, 0x02360001,
0x01370001, 0x00380001, 0x00390001, 0x003a0001, 0x003b0001,
0x003c0001, 0x003d0001, 0x003e0001, 0x003f0001, 0x7b400001,
0x7b410001, 0x7b420001, 0x7b430001, 0x7b440001, 0x7b450001,
0x7a460001, 0x79470001, 0x78480001, 0x77490001, 0x764a0001,
0x754b0001, 0x744c0001, 0x734d0001, 0x724e0001, 0x714f0001,
0x70500001, 0x6f510001, 0x6e520001, 0x6d530001, 0x6c540001,
0x6b550001, 0x6a560001, 0x69570001, 0x68580001, 0x67590001,
0x665a0001, 0x655b0001, 0x645c0001, 0x635d0001, 0x625e0001,
0x615f0001, 0x60600001, 0x49610001, 0x48620001, 0x47630001,
0x46640001, 0x45650001, 0x44660001, 0x43670001, 0x42680001,
0x41690001, 0x406a0001, 0x266b0001, 0x256c0001, 0x246d0001,
0x236e0001, 0x226f0001, 0x21700001, 0x20710001, 0x06720001,
0x05730001, 0x04740001, 0x03750001, 0x02760001, 0x01770001,
0x00780001, 0x00790001, 0x007a0001, 0x007b0001, 0x007c0001,
0x007d0001, 0x007e0001, 0x007f0001, 0x3800001e, 0x3801001e,
0x3802001e, 0x3803001e, 0x3804001e, 0x3805001e, 0x3806001e,
0x3807001e, 0x3808001e, 0x3c09001e, 0x3e0a001e, 0x400b001e,
0x440c001e, 0x480d001e, 0x4c0e001e, 0x500f001e, 0x5210001e,
0x5611001e, 0x5a12001e, 0x5e13001e, 0x6014001e, 0x6015001e,
0x6016001e, 0x6217001e, 0x6218001e, 0x6219001e, 0x621a001e,
0x621b001e, 0x621c001e, 0x621d001e, 0x621e001e, 0x621f001e
};
static const struct rtwn_agc_prog rtl8192ce_agc[] = {
{
nitems(rtl8192ce_agc_vals),
rtl8192ce_agc_vals,
{ 0 },
NULL
}
};
/*
* RF initialization values.
*/
static const uint8_t rtl8192c_rf0_regs0[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21
}, rtl8192c_rf0_regs1[] = {
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28
}, rtl8192c_rf0_regs2[] = {
0x29, 0x2a, 0x2b, 0x2a, 0x2b, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b,
0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a,
0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c,
0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b,
0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x2b,
0x2b, 0x2c, 0x2a, 0x2b, 0x2b, 0x2c, 0x2a, 0x10, 0x11, 0x10, 0x11,
0x10, 0x11, 0x10, 0x11, 0x10, 0x11, 0x10, 0x11, 0x10, 0x11
}, rtl8192c_rf0_regs3[] = {
0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
0x13, 0x13, 0x13, 0x13
}, rtl8192c_rf0_regs4[] = {
0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15
}, rtl8192c_rf0_regs5[] = {
0x16, 0x16, 0x16, 0x16, 0x00, 0x18, 0xfe, 0xfe, 0x1f, 0xfe, 0xfe,
0x1e, 0x1f, 0x00
};
static const uint32_t rtl8192c_rf0_vals0_88ce_88cu_92ce[] = {
0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb1,
0x54867, 0x8992e, 0x0e52c, 0x39ce7, 0x00451, 0x00000, 0x10255,
0x60a00, 0xfc378, 0xa1250, 0x4445f, 0x80001, 0x0b614, 0x6c000
}, rtl8192c_rf0_vals0_88ru[] = {
0x30159, 0x31284, 0x98000, 0x18c63, 0x210e7, 0x2044f, 0x1adb0,
0x54867, 0x8992e, 0x0e529, 0x39ce7, 0x00451, 0x00000, 0x00255,
0x60a00, 0xfc378, 0xa1250, 0x4445f, 0x80001, 0x0b614, 0x6c000
}, rtl8192c_rf0_vals1_88ru[] = {
0x0083c, 0x01558, 0x00060, 0x00483, 0x4f000, 0xec7d9, 0x977c0
}, rtl8192c_rf0_vals1_88ce[] = {
0x00000, 0x01558, 0x00060, 0x00483, 0x4f200, 0xec7d9, 0x577c0
}, rtl8192c_rf0_vals1_88cu_92ce[] = {
0x00000, 0x01558, 0x00060, 0x00483, 0x4f000, 0xec7d9, 0x577c0
}, rtl8192c_rf0_vals2[] = {
0x04783, 0x00001, 0x21334, 0x00000, 0x00054, 0x00001, 0x00808,
0x53333, 0x0000c, 0x00002, 0x00808, 0x5b333, 0x0000d, 0x00003,
0x00808, 0x63333, 0x0000d, 0x00004, 0x00808, 0x6b333, 0x0000d,
0x00005, 0x00808, 0x73333, 0x0000d, 0x00006, 0x00709, 0x5b333,
0x0000d, 0x00007, 0x00709, 0x63333, 0x0000d, 0x00008, 0x0060a,
0x4b333, 0x0000d, 0x00009, 0x0060a, 0x53333, 0x0000d, 0x0000a,
0x0060a, 0x5b333, 0x0000d, 0x0000b, 0x0060a, 0x63333, 0x0000d,
0x0000c, 0x0060a, 0x6b333, 0x0000d, 0x0000d, 0x0060a, 0x73333,
0x0000d, 0x0000e, 0x0050b, 0x66666, 0x0001a, 0xe0000, 0x4000f,
0xe31fc, 0x6000f, 0xff9f8, 0x2000f, 0x203f9, 0x3000f, 0xff500,
0x00000, 0x00000, 0x8000f, 0x3f100, 0x9000f, 0x23100
}, rtl8192c_rf0_vals3_88ru[] = {
0xd8000, 0x90000, 0x51000, 0x12000, 0x28fb4, 0x24fa8, 0x207a4,
0x1c798, 0x183a4, 0x14398, 0x101a4, 0x0c198, 0x080a4, 0x04098,
0x00014
}, rtl8192c_rf0_vals3_92ce[] = {
0x32000, 0x71000, 0xb0000, 0xfc000, 0x287af, 0x244b7, 0x204ab,
0x1c49f, 0x18493, 0x14297, 0x10295, 0x0c298, 0x0819c, 0x040a8,
0x0001c
}, rtl8192c_rf0_vals3_88cu_88ce[] = {
0x32000, 0x71000, 0xb0000, 0xfc000, 0x287b3, 0x244b7, 0x204ab,
0x1c49f, 0x18493, 0x1429b, 0x10299, 0x0c29c, 0x081a0, 0x040ac,
0x00020
}, rtl8192c_rf0_vals4_92ce_88ce[] = {
0x1944c, 0x59444, 0x9944c, 0xd9444, 0x0f424, 0x4f424, 0x8f424,
0xcf424
}, rtl8192c_rf0_vals4_88cu_88ru[] = {
0x1944c, 0x59444, 0x9944c, 0xd9444, 0x0f405, 0x4f405, 0x8f405,
0xcf405
}, rtl8192c_rf0_vals5[] = {
0xe0330, 0xa0330, 0x60330, 0x20330, 0x10159, 0x0f401, 0x0c350,
0x0c350, 0x80003, 0x0c350, 0x0c350, 0x44457, 0x80000, 0x30159
};
static const struct rtwn_rf_prog rtl8192c_rf[] = {
/* RF chain 0 */
/* RTL8188RU. */
{
nitems(rtl8192c_rf0_regs0),
rtl8192c_rf0_regs0,
rtl8192c_rf0_vals0_88ru,
{ R92C_COND_RTL8188RU },
/* Others. */
&(const struct rtwn_rf_prog){
nitems(rtl8192c_rf0_regs0),
rtl8192c_rf0_regs0,
rtl8192c_rf0_vals0_88ce_88cu_92ce,
{ 0 },
NULL
}
},
/* RTL8188RU. */
{
nitems(rtl8192c_rf0_regs1),
rtl8192c_rf0_regs1,
rtl8192c_rf0_vals1_88ru,
{ R92C_COND_RTL8188RU },
/* RTL8188CE. */
&(const struct rtwn_rf_prog){
nitems(rtl8192c_rf0_regs1),
rtl8192c_rf0_regs1,
rtl8192c_rf0_vals1_88ce,
{ R92C_COND_RTL8188CE },
/* Others. */
&(const struct rtwn_rf_prog){
nitems(rtl8192c_rf0_regs1),
rtl8192c_rf0_regs1,
rtl8192c_rf0_vals1_88cu_92ce,
{ 0 },
NULL
}
}
},
{
nitems(rtl8192c_rf0_regs2),
rtl8192c_rf0_regs2,
rtl8192c_rf0_vals2,
{ 0 },
NULL
},
/* RTL8188RU. */
{
nitems(rtl8192c_rf0_regs3),
rtl8192c_rf0_regs3,
rtl8192c_rf0_vals3_88ru,
{ R92C_COND_RTL8188RU },
/* RTL8192C. */
&(const struct rtwn_rf_prog){
nitems(rtl8192c_rf0_regs3),
rtl8192c_rf0_regs3,
rtl8192c_rf0_vals3_92ce,
{ R92C_COND_RTL8192C },
/* Others. */
&(struct rtwn_rf_prog){
nitems(rtl8192c_rf0_regs3),
rtl8192c_rf0_regs3,
rtl8192c_rf0_vals3_88cu_88ce,
{ 0 },
NULL
}
}
},
/* RTL8188CE / RTL8192C. */
{
nitems(rtl8192c_rf0_regs4),
rtl8192c_rf0_regs4,
rtl8192c_rf0_vals4_92ce_88ce,
{ R92C_COND_RTL8188CE | R92C_COND_RTL8192C },
/* Others. */
&(const struct rtwn_rf_prog){
nitems(rtl8192c_rf0_regs4),
rtl8192c_rf0_regs4,
rtl8192c_rf0_vals4_88cu_88ru,
{ 0 },
NULL
}
},
{
nitems(rtl8192c_rf0_regs5),
rtl8192c_rf0_regs5,
rtl8192c_rf0_vals5,
{ 0 },
NULL
},
{ 0, NULL, NULL, { 0 }, NULL },
/* RF chain 1 (RTL8192C). */
{
12, /* 0x00 - 0x0f */
rtl8192c_rf0_regs0,
rtl8192c_rf0_vals0_88ce_88cu_92ce,
{ 0 },
NULL
},
{
nitems(rtl8192c_rf0_regs3), /* 0x12 - 0x13 */
rtl8192c_rf0_regs3,
rtl8192c_rf0_vals3_92ce,
{ 0 },
NULL
},
{
nitems(rtl8192c_rf0_regs4), /* 0x14 - 0x15 */
rtl8192c_rf0_regs4,
rtl8192c_rf0_vals4_92ce_88ce,
{ 0 },
NULL
},
{
4, /* 0x16 */
rtl8192c_rf0_regs5,
rtl8192c_rf0_vals5,
{ 0 },
NULL
},
{ 0, NULL, NULL, { 0 }, NULL }
};
struct rtwn_r92c_txagc {
uint8_t pwr[R92C_GROUP_2G][28]; /* RTWN_RIDX_MCS(15) + 1 */
};
/*
* Per RF chain/group/rate Tx gain values.
*/
static const struct rtwn_r92c_txagc rtl8192cu_txagc[] = {
{ { /* Chain 0. */
{ /* Group 0. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x0c, 0x0c, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, /* OFDM6~54. */
0x0e, 0x0d, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, /* MCS0~7. */
0x0e, 0x0d, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02 /* MCS8~15. */
},
{ /* Group 1. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
},
{ /* Group 2. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
}
} },
{ { /* Chain 1. */
{ /* Group 0. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
},
{ /* Group 1. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
},
{ /* Group 2. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x04, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
}
} }
};
static const struct rtwn_r92c_txagc rtl8188ru_txagc[] = {
{ { /* Chain 0. */
{ /* Group 0. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x08, 0x08, 0x08, 0x06, 0x06, 0x04, 0x04, 0x00, /* OFDM6~54. */
0x08, 0x06, 0x06, 0x04, 0x04, 0x02, 0x02, 0x00, /* MCS0~7. */
0x08, 0x06, 0x06, 0x04, 0x04, 0x02, 0x02, 0x00 /* MCS8~15. */
},
{ /* Group 1. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
},
{ /* Group 2. */
0x00, 0x00, 0x00, 0x00, /* CCK1~11. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */
}
} }
};
#endif /* R92C_PRIV_H */

View File

@ -0,0 +1,855 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2015 Stefan Sperling <stsp@openbsd.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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92C_REG_H
#define R92C_REG_H
/*
* MAC registers.
*/
/* System Configuration. */
#define R92C_SYS_ISO_CTRL 0x000
#define R92C_SYS_FUNC_EN 0x002
#define R92C_APS_FSMCO 0x004
#define R92C_SYS_CLKR 0x008
#define R92C_AFE_MISC 0x010
#define R92C_SPS0_CTRL 0x011
#define R92C_SPS_OCP_CFG 0x018
#define R92C_RSV_CTRL 0x01c
#define R92C_RF_CTRL 0x01f
#define R92C_LDOA15_CTRL 0x020
#define R92C_LDOV12D_CTRL 0x021
#define R92C_LDOHCI12_CTRL 0x022
#define R92C_LPLDO_CTRL 0x023
#define R92C_AFE_XTAL_CTRL 0x024
#define R92C_AFE_PLL_CTRL 0x028
#define R92C_APE_PLL_CTRL_EXT 0x02c
#define R92C_MAC_PHY_CTRL R92C_APE_PLL_CTRL_EXT
#define R92C_EFUSE_CTRL 0x030
#define R92C_EFUSE_TEST 0x034
#define R92C_PWR_DATA 0x038
#define R92C_CAL_TIMER 0x03c
#define R92C_ACLK_MON 0x03e
#define R92C_GPIO_MUXCFG 0x040
#define R92C_GPIO_IO_SEL 0x042
#define R92C_MAC_PINMUX_CFG 0x043
#define R92C_GPIO_PIN_CTRL 0x044
#define R92C_GPIO_IN 0x044
#define R92C_GPIO_OUT 0x045
#define R92C_GPIO_IOSEL 0x046
#define R92C_GPIO_MOD 0x047
#define R92C_GPIO_INTM 0x048
#define R92C_LEDCFG0 0x04c
#define R92C_LEDCFG1 0x04d
#define R92C_LEDCFG2 0x04e
#define R92C_LEDCFG3 0x04f
#define R92C_FSIMR 0x050
#define R92C_FSISR 0x054
#define R92C_HSIMR 0x058
#define R92C_HSISR 0x05c
#define R92C_MULTI_FUNC_CTRL 0x068
#define R92C_MCUFWDL 0x080
#define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2)
#define R92C_EFUSE_ACCESS 0x0cf
#define R92C_BIST_SCAN 0x0d0
#define R92C_BIST_RPT 0x0d4
#define R92C_BIST_ROM_RPT 0x0d8
#define R92C_HPON_FSM 0x0ec
#define R92C_SYS_CFG 0x0f0
#define R92C_TYPE_ID 0x0fc
/* MAC General Configuration. */
#define R92C_CR 0x100
#define R92C_MSR 0x102
#define R92C_PBP 0x104
#define R92C_TRXDMA_CTRL 0x10c
#define R92C_TRXFF_BNDY 0x114
#define R92C_TRXFF_STATUS 0x118
#define R92C_RXFF_PTR 0x11c
#define R92C_HIMR 0x120
#define R92C_HISR 0x124
#define R92C_HIMRE 0x128
#define R92C_HISRE 0x12c
#define R92C_CPWM 0x12f
#define R92C_FWIMR 0x130
#define R92C_FWISR 0x134
#define R92C_PKTBUF_DBG_CTRL 0x140
#define R92C_PKTBUF_DBG_DATA_L 0x144
#define R92C_PKTBUF_DBG_DATA_H 0x148
#define R92C_TC0_CTRL(i) (0x150 + (i) * 4)
#define R92C_TCUNIT_BASE 0x164
#define R92C_MBIST_START 0x174
#define R92C_MBIST_DONE 0x178
#define R92C_MBIST_FAIL 0x17c
#define R92C_C2H_EVT_MSG 0x1a0
#define R92C_C2H_EVT_CLEAR 0x1af
#define R92C_C2H_EVT_MSG_TEST 0x1b8
#define R92C_MCUTST_1 0x1c0
#define R92C_FMETHR 0x1c8
#define R92C_HMETFR 0x1cc
#define R92C_HMEBOX(idx) (0x1d0 + (idx) * 4)
#define R92C_LLT_INIT 0x1e0
#define R92C_BB_ACCESS_CTRL 0x1e8
#define R92C_BB_ACCESS_DATA 0x1ec
/* Tx DMA Configuration. */
#define R92C_RQPN 0x200
#define R92C_FIFOPAGE 0x204
#define R92C_TDECTRL 0x208
#define R92C_TXDMA_OFFSET_CHK 0x20c
#define R92C_TXDMA_STATUS 0x210
#define R92C_RQPN_NPQ 0x214
/* Rx DMA Configuration. */
#define R92C_RXDMA_AGG_PG_TH 0x280
#define R92C_RXPKT_NUM 0x284
#define R92C_RXDMA_STATUS 0x288
/* Protocol Configuration. */
#define R92C_VOQ_INFORMATION 0x400
#define R92C_VIQ_INFORMATION 0x404
#define R92C_BEQ_INFORMATION 0x408
#define R92C_BKQ_INFORMATION 0x40c
#define R92C_MGQ_INFORMATION 0x410
#define R92C_HGQ_INFORMATION 0x414
#define R92C_BCNQ_INFORMATION 0x418
#define R92C_CPU_MGQ_INFORMATION 0x41c
#define R92C_FWHW_TXQ_CTRL 0x420
#define R92C_HWSEQ_CTRL 0x423
#define R92C_TXPKTBUF_BCNQ_BDNY 0x424
#define R92C_TXPKTBUF_MGQ_BDNY 0x425
#define R92C_SPEC_SIFS 0x428
#define R92C_RL 0x42a
#define R92C_DARFRC 0x430
#define R92C_RARFRC 0x438
#define R92C_RRSR 0x440
#define R92C_ARFR(i) (0x444 + (i) * 4)
#define R92C_AGGLEN_LMT 0x458
#define R92C_AMPDU_MIN_SPACE 0x45c
#define R92C_TXPKTBUF_WMAC_LBK_BF_HD 0x45d
#define R92C_FAST_EDCA_CTRL 0x460
#define R92C_RD_RESP_PKT_TH 0x463
#define R92C_INIRTS_RATE_SEL 0x480
#define R92C_INIDATA_RATE_SEL(macid) (0x484 + (macid))
#define R92C_QUEUE_CTRL 0x4c6
#define R92C_MAX_AGGR_NUM 0x4ca
#define R92C_BAR_MODE_CTRL 0x4cc
/* EDCA Configuration. */
#define R92C_EDCA_VO_PARAM 0x500
#define R92C_EDCA_VI_PARAM 0x504
#define R92C_EDCA_BE_PARAM 0x508
#define R92C_EDCA_BK_PARAM 0x50c
#define R92C_BCNTCFG 0x510
#define R92C_PIFS 0x512
#define R92C_RDG_PIFS 0x513
#define R92C_SIFS_CCK 0x514
#define R92C_SIFS_OFDM 0x516
#define R92C_AGGR_BREAK_TIME 0x51a
#define R92C_SLOT 0x51b
#define R92C_TX_PTCL_CTRL 0x520
#define R92C_TXPAUSE 0x522
#define R92C_DIS_TXREQ_CLR 0x523
#define R92C_RD_CTRL 0x524
#define R92C_TBTT_PROHIBIT 0x540
#define R92C_RD_NAV_NXT 0x544
#define R92C_NAV_PROT_LEN 0x546
#define R92C_BCN_CTRL(id) ((id) + 0x550)
/* WARNING: R92C_USTIME_TSF == 0x55c, not 0x551 */
#define R92C_MBID_NUM 0x552
#define R92C_DUAL_TSF_RST 0x553
#define R92C_BCN_INTERVAL(id) (0x554 + (id) * 2)
#define R92C_DRVERLYINT 0x558
#define R92C_BCNDMATIM 0x559
#define R92C_ATIMWND 0x55a
#define R92C_USTIME_TSF 0x55c
#define R92C_BCN_MAX_ERR 0x55d
#define R92C_RXTSF_OFFSET_CCK 0x55e
#define R92C_RXTSF_OFFSET_OFDM 0x55f
#define R92C_TSFTR(i) (0x560 + (i) * 8)
#define R92C_PSTIMER 0x580
#define R92C_TIMER0 0x584
#define R92C_TIMER1 0x588
#define R92C_ACMHWCTRL 0x5c0
#define R92C_ACMRSTCTRL 0x5c1
#define R92C_ACMAVG 0x5c2
#define R92C_VO_ADMTIME 0x5c4
#define R92C_VI_ADMTIME 0x5c6
#define R92C_BE_ADMTIME 0x5c8
#define R92C_EDCA_RANDOM_GEN 0x5cc
#define R92C_SCH_TXCMD 0x5d0
/* WMAC Configuration. */
#define R92C_APSD_CTRL 0x600
#define R92C_BWOPMODE 0x603
#define R92C_TCR 0x604
#define R92C_RCR 0x608
#define R92C_RX_PKT_LIMIT 0x60c
#define R92C_RX_DRVINFO_SZ 0x60f
#define R92C_MACID0 0x610
#define R92C_BSSID0 0x618
#define R92C_MAR 0x620
#define R92C_USTIME_EDCA 0x638
#define R92C_MAC_SPEC_SIFS 0x63a
#define R92C_R2T_SIFS 0x63c
#define R92C_T2T_SIFS 0x63e
#define R92C_ACKTO 0x640
#define R92C_NAV_UPPER 0x652
#define R92C_WMAC_TRXPTCL_CTL 0x668
#define R92C_CAMCMD 0x670
#define R92C_CAMWRITE 0x674
#define R92C_CAMREAD 0x678
#define R92C_CAMDBG 0x67c
#define R92C_SECCFG 0x680
#define R92C_RXFLTMAP0 0x6a0
#define R92C_RXFLTMAP1 0x6a2
#define R92C_RXFLTMAP2 0x6a4
#define R92C_BCN_PSR_RPT 0x6a8
#define R92C_MACID1 0x700
#define R92C_BSSID1 0x708
#define R92C_MACID(id) ((id) == 0 ? R92C_MACID0 : R92C_MACID1)
#define R92C_BSSID(id) ((id) == 0 ? R92C_BSSID0 : R92C_BSSID1)
/* Bits for R92C_SYS_ISO_CTRL. */
#define R92C_SYS_ISO_CTRL_MD2PP 0x0001
#define R92C_SYS_ISO_CTRL_UA2USB 0x0002
#define R92C_SYS_ISO_CTRL_UD2CORE 0x0004
#define R92C_SYS_ISO_CTRL_PA2PCIE 0x0008
#define R92C_SYS_ISO_CTRL_PD2CORE 0x0010
#define R92C_SYS_ISO_CTRL_IP2MAC 0x0020
#define R92C_SYS_ISO_CTRL_DIOP 0x0040
#define R92C_SYS_ISO_CTRL_DIOE 0x0080
#define R92C_SYS_ISO_CTRL_EB2CORE 0x0100
#define R92C_SYS_ISO_CTRL_DIOR 0x0200
#define R92C_SYS_ISO_CTRL_PWC_EV25V 0x4000
#define R92C_SYS_ISO_CTRL_PWC_EV12V 0x8000
/* Bits for R92C_SYS_FUNC_EN. */
#define R92C_SYS_FUNC_EN_BBRSTB 0x0001
#define R92C_SYS_FUNC_EN_BB_GLB_RST 0x0002
#define R92C_SYS_FUNC_EN_USBA 0x0004
#define R92C_SYS_FUNC_EN_UPLL 0x0008
#define R92C_SYS_FUNC_EN_USBD 0x0010
#define R92C_SYS_FUNC_EN_DIO_PCIE 0x0020
#define R92C_SYS_FUNC_EN_PCIEA 0x0040
#define R92C_SYS_FUNC_EN_PPLL 0x0080
#define R92C_SYS_FUNC_EN_PCIED 0x0100
#define R92C_SYS_FUNC_EN_DIOE 0x0200
#define R92C_SYS_FUNC_EN_CPUEN 0x0400
#define R92C_SYS_FUNC_EN_DCORE 0x0800
#define R92C_SYS_FUNC_EN_ELDR 0x1000
#define R92C_SYS_FUNC_EN_DIO_RF 0x2000
#define R92C_SYS_FUNC_EN_HWPDN 0x4000
#define R92C_SYS_FUNC_EN_MREGEN 0x8000
/* Bits for R92C_APS_FSMCO. */
#define R92C_APS_FSMCO_PFM_LDALL 0x00000001
#define R92C_APS_FSMCO_PFM_ALDN 0x00000002
#define R92C_APS_FSMCO_PFM_LDKP 0x00000004
#define R92C_APS_FSMCO_PFM_WOWL 0x00000008
#define R92C_APS_FSMCO_PDN_EN 0x00000010
#define R92C_APS_FSMCO_PDN_PL 0x00000020
#define R92C_APS_FSMCO_APFM_ONMAC 0x00000100
#define R92C_APS_FSMCO_APFM_OFF 0x00000200
#define R92C_APS_FSMCO_APFM_RSM 0x00000400
#define R92C_APS_FSMCO_AFSM_HSUS 0x00000800
#define R92C_APS_FSMCO_AFSM_PCIE 0x00001000
#define R92C_APS_FSMCO_APDM_MAC 0x00002000
#define R92C_APS_FSMCO_APDM_HOST 0x00004000
#define R92C_APS_FSMCO_APDM_HPDN 0x00008000
#define R92C_APS_FSMCO_RDY_MACON 0x00010000
#define R92C_APS_FSMCO_SUS_HOST 0x00020000
#define R92C_APS_FSMCO_ROP_ALD 0x00100000
#define R92C_APS_FSMCO_ROP_PWR 0x00200000
#define R92C_APS_FSMCO_ROP_SPS 0x00400000
#define R92C_APS_FSMCO_SOP_MRST 0x02000000
#define R92C_APS_FSMCO_SOP_FUSE 0x04000000
#define R92C_APS_FSMCO_SOP_ABG 0x08000000
#define R92C_APS_FSMCO_SOP_AMB 0x10000000
#define R92C_APS_FSMCO_SOP_RCK 0x20000000
#define R92C_APS_FSMCO_SOP_A8M 0x40000000
#define R92C_APS_FSMCO_XOP_BTCK 0x80000000
/* Bits for R92C_SYS_CLKR. */
#define R92C_SYS_CLKR_ANAD16V_EN 0x00000001
#define R92C_SYS_CLKR_ANA8M 0x00000002
#define R92C_SYS_CLKR_MACSLP 0x00000010
#define R92C_SYS_CLKR_LOADER_EN 0x00000020
#define R92C_SYS_CLKR_80M_SSC_DIS 0x00000080
#define R92C_SYS_CLKR_80M_SSC_EN_HO 0x00000100
#define R92C_SYS_CLKR_PHY_SSC_RSTB 0x00000200
#define R92C_SYS_CLKR_SEC_EN 0x00000400
#define R92C_SYS_CLKR_MAC_EN 0x00000800
#define R92C_SYS_CLKR_SYS_EN 0x00001000
#define R92C_SYS_CLKR_RING_EN 0x00002000
/* Bits for R92C_RF_CTRL. */
#define R92C_RF_CTRL_EN 0x01
#define R92C_RF_CTRL_RSTB 0x02
#define R92C_RF_CTRL_SDMRSTB 0x04
/* Bits for R92C_LDOA15_CTRL. */
#define R92C_LDOA15_CTRL_EN 0x01
#define R92C_LDOA15_CTRL_STBY 0x02
#define R92C_LDOA15_CTRL_OBUF 0x04
#define R92C_LDOA15_CTRL_REG_VOS 0x08
/* Bits for R92C_LDOV12D_CTRL. */
#define R92C_LDOV12D_CTRL_LDV12_EN 0x01
/* Bits for R92C_LPLDO_CTRL. */
#define R92C_LPLDO_CTRL_SLEEP 0x10
/* Bits for R92C_AFE_XTAL_CTRL. */
#define R92C_AFE_XTAL_CTRL_ADDR_M 0x007ff800
#define R92C_AFE_XTAL_CTRL_ADDR_S 11
/* Bits for R92C_AFE_PLL_CTRL. */
#define R92C_AFE_PLL_CTRL_EN 0x0001
#define R92C_AFE_PLL_CTRL_320_EN 0x0002
#define R92C_AFE_PLL_CTRL_FREF_SEL 0x0004
#define R92C_AFE_PLL_CTRL_EDGE_SEL 0x0008
#define R92C_AFE_PLL_CTRL_WDOGB 0x0010
#define R92C_AFE_PLL_CTRL_LPFEN 0x0020
/* Bits for R92C_EFUSE_CTRL. */
#define R92C_EFUSE_CTRL_DATA_M 0x000000ff
#define R92C_EFUSE_CTRL_DATA_S 0
#define R92C_EFUSE_CTRL_ADDR_M 0x0003ff00
#define R92C_EFUSE_CTRL_ADDR_S 8
#define R92C_EFUSE_CTRL_VALID 0x80000000
/* Bits for R92C_GPIO_MUXCFG. */
#define R92C_GPIO_MUXCFG_ENBT 0x0020
/* Bits for R92C_LEDCFG0. */
#define R92C_LEDCFG0_DIS 0x08
/* Bits for R92C_MULTI_FUNC_CTRL. */
#define R92C_MULTI_BT_FUNC_EN 0x00040000
/* Bits for R92C_MCUFWDL. */
#define R92C_MCUFWDL_EN 0x00000001
#define R92C_MCUFWDL_RDY 0x00000002
#define R92C_MCUFWDL_CHKSUM_RPT 0x00000004
#define R92C_MCUFWDL_MACINI_RDY 0x00000008
#define R92C_MCUFWDL_BBINI_RDY 0x00000010
#define R92C_MCUFWDL_RFINI_RDY 0x00000020
#define R92C_MCUFWDL_WINTINI_RDY 0x00000040
#define R92C_MCUFWDL_RAM_DL_SEL 0x00000080 /* 1: RAM, 0: ROM */
#define R92C_MCUFWDL_PAGE_M 0x00070000
#define R92C_MCUFWDL_PAGE_S 16
#define R92C_MCUFWDL_ROM_DLEN 0x00080000
#define R92C_MCUFWDL_CPRST 0x00800000
/* Bits for R92C_EFUSE_ACCESS. */
#define R92C_EFUSE_ACCESS_OFF 0x00
#define R92C_EFUSE_ACCESS_ON 0x69
/* Bits for R92C_HPON_FSM. */
#define R92C_HPON_FSM_CHIP_BONDING_ID_S 22
#define R92C_HPON_FSM_CHIP_BONDING_ID_M 0x00c00000
#define R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R 1
/* Bits for R92C_SYS_CFG. */
#define R92C_SYS_CFG_XCLK_VLD 0x00000001
#define R92C_SYS_CFG_ACLK_VLD 0x00000002
#define R92C_SYS_CFG_UCLK_VLD 0x00000004
#define R92C_SYS_CFG_PCLK_VLD 0x00000008
#define R92C_SYS_CFG_PCIRSTB 0x00000010
#define R92C_SYS_CFG_V15_VLD 0x00000020
#define R92C_SYS_CFG_TRP_B15V_EN 0x00000080
#define R92C_SYS_CFG_SIC_IDLE 0x00000100
#define R92C_SYS_CFG_BD_MAC2 0x00000200
#define R92C_SYS_CFG_BD_MAC1 0x00000400
#define R92C_SYS_CFG_IC_MACPHY_MODE 0x00000800
#define R92C_SYS_CFG_CHIP_VER_RTL_M 0x0000f000
#define R92C_SYS_CFG_CHIP_VER_RTL_S 12
#define R92C_SYS_CFG_BT_FUNC 0x00010000
#define R92C_SYS_CFG_VENDOR_UMC 0x00080000
#define R92C_SYS_CFG_PAD_HWPD_IDN 0x00400000
#define R92C_SYS_CFG_TRP_VAUX_EN 0x00800000
#define R92C_SYS_CFG_TRP_BT_EN 0x01000000
#define R92C_SYS_CFG_BD_PKG_SEL 0x02000000
#define R92C_SYS_CFG_BD_HCI_SEL 0x04000000
#define R92C_SYS_CFG_TYPE_92C 0x08000000
/* Bits for R92C_CR. */
#define R92C_CR_HCI_TXDMA_EN 0x0001
#define R92C_CR_HCI_RXDMA_EN 0x0002
#define R92C_CR_TXDMA_EN 0x0004
#define R92C_CR_RXDMA_EN 0x0008
#define R92C_CR_PROTOCOL_EN 0x0010
#define R92C_CR_SCHEDULE_EN 0x0020
#define R92C_CR_MACTXEN 0x0040
#define R92C_CR_MACRXEN 0x0080
#define R92C_CR_ENSWBCN 0x0100
#define R92C_CR_ENSEC 0x0200
#define R92C_CR_CALTMR_EN 0x0400
/* Bits for R92C_MSR. */
#define R92C_MSR_NOLINK 0x00
#define R92C_MSR_ADHOC 0x01
#define R92C_MSR_INFRA 0x02
#define R92C_MSR_AP 0x03
#define R92C_MSR_MASK (R92C_MSR_AP)
/* Bits for R92C_PBP. */
#define R92C_PBP_PSRX_M 0x0f
#define R92C_PBP_PSRX_S 0
#define R92C_PBP_PSTX_M 0xf0
#define R92C_PBP_PSTX_S 4
#define R92C_PBP_64 0
#define R92C_PBP_128 1
#define R92C_PBP_256 2
#define R92C_PBP_512 3
#define R92C_PBP_1024 4
/* Bits for R92C_TRXDMA_CTRL. */
#define R92C_TRXDMA_CTRL_RXDMA_AGG_EN 0x0004
#define R92C_TRXDMA_CTRL_TXDMA_VOQ_MAP_M 0x0030
#define R92C_TRXDMA_CTRL_TXDMA_VOQ_MAP_S 4
#define R92C_TRXDMA_CTRL_TXDMA_VIQ_MAP_M 0x00c0
#define R92C_TRXDMA_CTRL_TXDMA_VIQ_MAP_S 6
#define R92C_TRXDMA_CTRL_TXDMA_BEQ_MAP_M 0x0300
#define R92C_TRXDMA_CTRL_TXDMA_BEQ_MAP_S 8
#define R92C_TRXDMA_CTRL_TXDMA_BKQ_MAP_M 0x0c00
#define R92C_TRXDMA_CTRL_TXDMA_BKQ_MAP_S 10
#define R92C_TRXDMA_CTRL_TXDMA_MGQ_MAP_M 0x3000
#define R92C_TRXDMA_CTRL_TXDMA_MGQ_MAP_S 12
#define R92C_TRXDMA_CTRL_TXDMA_HIQ_MAP_M 0xc000
#define R92C_TRXDMA_CTRL_TXDMA_HIQ_MAP_S 14
#define R92C_TRXDMA_CTRL_QUEUE_LOW 1
#define R92C_TRXDMA_CTRL_QUEUE_NORMAL 2
#define R92C_TRXDMA_CTRL_QUEUE_HIGH 3
#define R92C_TRXDMA_CTRL_QMAP_M 0xfff0
/* Shortcuts. */
#define R92C_TRXDMA_CTRL_QMAP_3EP 0xf5b0
#define R92C_TRXDMA_CTRL_QMAP_HQ_LQ 0xf5f0
#define R92C_TRXDMA_CTRL_QMAP_HQ_NQ 0xfaf0
#define R92C_TRXDMA_CTRL_QMAP_LQ 0x5550
#define R92C_TRXDMA_CTRL_QMAP_NQ 0xaaa0
#define R92C_TRXDMA_CTRL_QMAP_HQ 0xfff0
/* Bits for R92C_C2H_EVT_CLEAR. */
#define R92C_C2H_EVT_HOST_CLOSE 0x00
#define R92C_C2H_EVT_FW_CLOSE 0xff
/* Bits for R92C_LLT_INIT. */
#define R92C_LLT_INIT_DATA_M 0x000000ff
#define R92C_LLT_INIT_DATA_S 0
#define R92C_LLT_INIT_ADDR_M 0x0000ff00
#define R92C_LLT_INIT_ADDR_S 8
#define R92C_LLT_INIT_OP_M 0xc0000000
#define R92C_LLT_INIT_OP_S 30
#define R92C_LLT_INIT_OP_NO_ACTIVE 0
#define R92C_LLT_INIT_OP_WRITE 1
/* Bits for R92C_RQPN. */
#define R92C_RQPN_HPQ_M 0x000000ff
#define R92C_RQPN_HPQ_S 0
#define R92C_RQPN_LPQ_M 0x0000ff00
#define R92C_RQPN_LPQ_S 8
#define R92C_RQPN_PUBQ_M 0x00ff0000
#define R92C_RQPN_PUBQ_S 16
#define R92C_RQPN_LD 0x80000000
/* Bits for R92C_TDECTRL. */
#define R92C_TDECTRL_BLK_DESC_NUM_M 0x000000f0
#define R92C_TDECTRL_BLK_DESC_NUM_S 4
#define R92C_TDECTRL_BCN_VALID 0x00010000
/* Bits for R92C_TXDMA_OFFSET_CHK. */
#define R92C_TXDMA_OFFSET_DROP_DATA_EN 0x00000200
/* Bits for R92C_FWHW_TXQ_CTRL. */
#define R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW 0x80
#define R92C_FWHW_TXQ_CTRL_REAL_BEACON 0x400000
/* Bits for R92C_SPEC_SIFS. */
#define R92C_SPEC_SIFS_CCK_M 0x00ff
#define R92C_SPEC_SIFS_CCK_S 0
#define R92C_SPEC_SIFS_OFDM_M 0xff00
#define R92C_SPEC_SIFS_OFDM_S 8
/* Bits for R92C_RL. */
#define R92C_RL_LRL_M 0x003f
#define R92C_RL_LRL_S 0
#define R92C_RL_SRL_M 0x3f00
#define R92C_RL_SRL_S 8
/* Size of R92C_DARFRC. */
#define R92C_DARFRC_SIZE 8
/* Bits for R92C_RRSR. */
#define R92C_RRSR_RATE_BITMAP_M 0x000fffff
#define R92C_RRSR_RATE_BITMAP_S 0
#define R92C_RRSR_RATE_CCK_ONLY_1M 0xffff1
#define R92C_RRSR_RATE_ALL 0xfffff
#define R92C_RRSR_RSC_LOWSUBCHNL 0x00200000
#define R92C_RRSR_RSC_UPSUBCHNL 0x00400000
#define R92C_RRSR_SHORT 0x00800000
/* Bits for R92C_EDCA_XX_PARAM. */
#define R92C_EDCA_PARAM_AIFS_M 0x000000ff
#define R92C_EDCA_PARAM_AIFS_S 0
#define R92C_EDCA_PARAM_ECWMIN_M 0x00000f00
#define R92C_EDCA_PARAM_ECWMIN_S 8
#define R92C_EDCA_PARAM_ECWMAX_M 0x0000f000
#define R92C_EDCA_PARAM_ECWMAX_S 12
#define R92C_EDCA_PARAM_TXOP_M 0xffff0000
#define R92C_EDCA_PARAM_TXOP_S 16
/* Bits for R92C_HWSEQ_CTRL / R92C_TXPAUSE. */
#define R92C_TX_QUEUE_VO 0x01
#define R92C_TX_QUEUE_VI 0x02
#define R92C_TX_QUEUE_BE 0x04
#define R92C_TX_QUEUE_BK 0x08
#define R92C_TX_QUEUE_MGT 0x10
#define R92C_TX_QUEUE_HIGH 0x20
#define R92C_TX_QUEUE_BCN 0x40
/* Shortcuts. */
#define R92C_TX_QUEUE_AC \
(R92C_TX_QUEUE_VO | R92C_TX_QUEUE_VI | \
R92C_TX_QUEUE_BE | R92C_TX_QUEUE_BK)
#define R92C_TX_QUEUE_ALL \
(R92C_TX_QUEUE_AC | R92C_TX_QUEUE_MGT | \
R92C_TX_QUEUE_HIGH | R92C_TX_QUEUE_BCN | 0x80) /* XXX */
/* Bits for R92C_BCN_CTRL. */
#define R92C_BCN_CTRL_EN_MBSSID 0x02
#define R92C_BCN_CTRL_TXBCN_RPT 0x04
#define R92C_BCN_CTRL_EN_BCN 0x08
#define R92C_BCN_CTRL_DIS_TSF_UDT0 0x10
/* Bits for R92C_DUAL_TSF_RST. */
#define R92C_DUAL_TSF_RESET(id) (0x01 << (id))
#define R92C_DUAL_TSF_RST_TXOK 0x20
/* Bits for R92C_ACMHWCTRL. */
#define R92C_ACMHWCTRL_EN 0x01
#define R92C_ACMHWCTRL_BE 0x02
#define R92C_ACMHWCTRL_VI 0x04
#define R92C_ACMHWCTRL_VO 0x08
#define R92C_ACMHWCTRL_ACM_MASK 0x0f
/* Bits for R92C_APSD_CTRL. */
#define R92C_APSD_CTRL_OFF 0x40
#define R92C_APSD_CTRL_OFF_STATUS 0x80
/* Bits for R92C_BWOPMODE. */
#define R92C_BWOPMODE_11J 0x01
#define R92C_BWOPMODE_5G 0x02
#define R92C_BWOPMODE_20MHZ 0x04
/* Bits for R92C_TCR. */
#define R92C_TCR_TSFRST 0x00000001
#define R92C_TCR_DIS_GCLK 0x00000002
#define R92C_TCR_PAD_SEL 0x00000004
#define R92C_TCR_PWR_ST 0x00000040
#define R92C_TCR_PWRBIT_OW_EN 0x00000080
#define R92C_TCR_ACRC 0x00000100
#define R92C_TCR_CFENDFORM 0x00000200
#define R92C_TCR_ICV 0x00000400
/* Bits for R92C_RCR. */
#define R92C_RCR_AAP 0x00000001
#define R92C_RCR_APM 0x00000002
#define R92C_RCR_AM 0x00000004
#define R92C_RCR_AB 0x00000008
#define R92C_RCR_ADD3 0x00000010
#define R92C_RCR_APWRMGT 0x00000020
#define R92C_RCR_CBSSID_DATA 0x00000040
#define R92C_RCR_CBSSID_BCN 0x00000080
#define R92C_RCR_ACRC32 0x00000100
#define R92C_RCR_AICV 0x00000200
#define R92C_RCR_ADF 0x00000800
#define R92C_RCR_ACF 0x00001000
#define R92C_RCR_AMF 0x00002000
#define R92C_RCR_HTC_LOC_CTRL 0x00004000
#define R92C_RCR_MFBEN 0x00400000
#define R92C_RCR_LSIGEN 0x00800000
#define R92C_RCR_ENMBID 0x01000000
#define R92C_RCR_APP_BA_SSN 0x08000000
#define R92C_RCR_APP_PHYSTS 0x10000000
#define R92C_RCR_APP_ICV 0x20000000
#define R92C_RCR_APP_MIC 0x40000000
#define R92C_RCR_APPFCS 0x80000000
/* Bits for R92C_RX_DRVINFO_SZ. */
#define R92C_RX_DRVINFO_SZ_DEF 4 /* XXX other values will not work */
/* Bits for R92C_WMAC_TRXPTCL_CTL. */
#define R92C_WMAC_TRXPTCL_SHPRE 0x00020000
/* Bits for R92C_CAMCMD. */
#define R92C_CAMCMD_ADDR_M 0x0000ffff
#define R92C_CAMCMD_ADDR_S 0
#define R92C_CAMCMD_WRITE 0x00010000
#define R92C_CAMCMD_CLR 0x40000000
#define R92C_CAMCMD_POLLING 0x80000000
/*
* CAM entries.
*/
#define R92C_CAM_CTL0(entry) ((entry) * 8 + 0)
#define R92C_CAM_CTL1(entry) ((entry) * 8 + 1)
#define R92C_CAM_KEY(entry, i) ((entry) * 8 + 2 + (i))
#define R92C_CAM_CTL6(entry) ((entry) * 8 + 6)
#define R92C_CAM_CTL7(entry) ((entry) * 8 + 7)
/* Bits for R92C_CAM_CTL0(i). */
#define R92C_CAM_KEYID_M 0x00000003
#define R92C_CAM_KEYID_S 0
#define R92C_CAM_ALGO_M 0x0000001c
#define R92C_CAM_ALGO_S 2
#define R92C_CAM_ALGO_NONE 0
#define R92C_CAM_ALGO_WEP40 1
#define R92C_CAM_ALGO_TKIP 2
#define R92C_CAM_ALGO_AES 4
#define R92C_CAM_ALGO_WEP104 5
#define R92C_CAM_VALID 0x00008000
#define R92C_CAM_MACLO_M 0xffff0000
#define R92C_CAM_MACLO_S 16
/* Bits for R92C_SECCFG. */
#define R92C_SECCFG_TXUCKEY_DEF 0x0001
#define R92C_SECCFG_RXUCKEY_DEF 0x0002
#define R92C_SECCFG_TXENC_ENA 0x0004
#define R92C_SECCFG_RXDEC_ENA 0x0008
#define R92C_SECCFG_CMP_A2 0x0010
#define R92C_SECCFG_MC_SRCH_DIS 0x0020
#define R92C_SECCFG_TXBCKEY_DEF 0x0040
#define R92C_SECCFG_RXBCKEY_DEF 0x0080
/* Bits for R92C_RXFLTMAP*. */
#define R92C_RXFLTMAP_SUBTYPE(subtype) \
(1 << ((subtype) >> IEEE80211_FC0_SUBTYPE_SHIFT))
/*
* Baseband registers.
*/
#define R92C_FPGA0_RFMOD 0x800
#define R92C_FPGA0_TXINFO 0x804
#define R92C_HSSI_PARAM1(chain) (0x820 + (chain) * 8)
#define R92C_HSSI_PARAM2(chain) (0x824 + (chain) * 8)
#define R92C_TXAGC_RATE18_06(i) (((i) == 0) ? 0xe00 : 0x830)
#define R92C_TXAGC_RATE54_24(i) (((i) == 0) ? 0xe04 : 0x834)
#define R92C_TXAGC_A_CCK1_MCS32 0xe08
#define R92C_TXAGC_B_CCK1_55_MCS32 0x838
#define R92C_TXAGC_B_CCK11_A_CCK2_11 0x86c
#define R92C_TXAGC_MCS03_MCS00(i) (((i) == 0) ? 0xe10 : 0x83c)
#define R92C_TXAGC_MCS07_MCS04(i) (((i) == 0) ? 0xe14 : 0x848)
#define R92C_TXAGC_MCS11_MCS08(i) (((i) == 0) ? 0xe18 : 0x84c)
#define R92C_TXAGC_MCS15_MCS12(i) (((i) == 0) ? 0xe1c : 0x868)
#define R92C_LSSI_PARAM(chain) (0x840 + (chain) * 4)
#define R92C_FPGA0_RFIFACEOE(chain) (0x860 + (chain) * 4)
#define R92C_FPGA0_RFIFACESW(idx) (0x870 + (idx) * 4)
#define R92C_FPGA0_RFPARAM(idx) (0x878 + (idx) * 4)
#define R92C_FPGA0_ANAPARAM2 0x884
#define R92C_LSSI_READBACK(chain) (0x8a0 + (chain) * 4)
#define R92C_HSPI_READBACK(chain) (0x8b8 + (chain) * 4)
#define R92C_FPGA1_RFMOD 0x900
#define R92C_FPGA1_TXINFO 0x90c
#define R92C_CCK0_SYSTEM 0xa00
#define R92C_CCK0_AFESETTING 0xa04
#define R92C_OFDM0_TRXPATHENA 0xc04
#define R92C_OFDM0_TRMUXPAR 0xc08
#define R92C_OFDM0_RXIQIMBALANCE(chain) (0xc14 + (chain) * 8)
#define R92C_OFDM0_ECCATHRESHOLD 0xc4c
#define R92C_OFDM0_AGCCORE1(chain) (0xc50 + (chain) * 8)
#define R92C_OFDM0_AGCPARAM1 0xc70
#define R92C_OFDM0_AGCRSSITABLE 0xc78
#define R92C_OFDM0_TXIQIMBALANCE(chain) (0xc80 + (chain) * 8)
#define R92C_OFDM0_TXAFE(chain) (0xc94 + (chain) * 8)
#define R92C_OFDM0_RXIQEXTANTA 0xca0
#define R92C_OFDM1_LSTF 0xd00
/* Bits for R92C_FPGA[01]_RFMOD. */
#define R92C_RFMOD_40MHZ 0x00000001
#define R92C_RFMOD_JAPAN 0x00000002
#define R92C_RFMOD_CCK_TXSC 0x00000030
#define R92C_RFMOD_CCK_EN 0x01000000
#define R92C_RFMOD_OFDM_EN 0x02000000
/* Bits for R92C_HSSI_PARAM1(i). */
#define R92C_HSSI_PARAM1_PI 0x00000100
/* Bits for R92C_HSSI_PARAM2(i). */
#define R92C_HSSI_PARAM2_CCK_HIPWR 0x00000200
#define R92C_HSSI_PARAM2_ADDR_LENGTH 0x00000400
#define R92C_HSSI_PARAM2_DATA_LENGTH 0x00000800
#define R92C_HSSI_PARAM2_READ_ADDR_M 0x7f800000
#define R92C_HSSI_PARAM2_READ_ADDR_S 23
#define R92C_HSSI_PARAM2_READ_EDGE 0x80000000
/* Bits for R92C_TXAGC_A_CCK1_MCS32. */
#define R92C_TXAGC_A_CCK1_M 0x0000ff00
#define R92C_TXAGC_A_CCK1_S 8
/* Bits for R92C_TXAGC_B_CCK11_A_CCK2_11. */
#define R92C_TXAGC_B_CCK11_M 0x000000ff
#define R92C_TXAGC_B_CCK11_S 0
#define R92C_TXAGC_A_CCK2_M 0x0000ff00
#define R92C_TXAGC_A_CCK2_S 8
#define R92C_TXAGC_A_CCK55_M 0x00ff0000
#define R92C_TXAGC_A_CCK55_S 16
#define R92C_TXAGC_A_CCK11_M 0xff000000
#define R92C_TXAGC_A_CCK11_S 24
/* Bits for R92C_TXAGC_B_CCK1_55_MCS32. */
#define R92C_TXAGC_B_CCK1_M 0x0000ff00
#define R92C_TXAGC_B_CCK1_S 8
#define R92C_TXAGC_B_CCK2_M 0x00ff0000
#define R92C_TXAGC_B_CCK2_S 16
#define R92C_TXAGC_B_CCK55_M 0xff000000
#define R92C_TXAGC_B_CCK55_S 24
/* Bits for R92C_TXAGC_RATE18_06(x). */
#define R92C_TXAGC_RATE06_M 0x000000ff
#define R92C_TXAGC_RATE06_S 0
#define R92C_TXAGC_RATE09_M 0x0000ff00
#define R92C_TXAGC_RATE09_S 8
#define R92C_TXAGC_RATE12_M 0x00ff0000
#define R92C_TXAGC_RATE12_S 16
#define R92C_TXAGC_RATE18_M 0xff000000
#define R92C_TXAGC_RATE18_S 24
/* Bits for R92C_TXAGC_RATE54_24(x). */
#define R92C_TXAGC_RATE24_M 0x000000ff
#define R92C_TXAGC_RATE24_S 0
#define R92C_TXAGC_RATE36_M 0x0000ff00
#define R92C_TXAGC_RATE36_S 8
#define R92C_TXAGC_RATE48_M 0x00ff0000
#define R92C_TXAGC_RATE48_S 16
#define R92C_TXAGC_RATE54_M 0xff000000
#define R92C_TXAGC_RATE54_S 24
/* Bits for R92C_TXAGC_MCS03_MCS00(x). */
#define R92C_TXAGC_MCS00_M 0x000000ff
#define R92C_TXAGC_MCS00_S 0
#define R92C_TXAGC_MCS01_M 0x0000ff00
#define R92C_TXAGC_MCS01_S 8
#define R92C_TXAGC_MCS02_M 0x00ff0000
#define R92C_TXAGC_MCS02_S 16
#define R92C_TXAGC_MCS03_M 0xff000000
#define R92C_TXAGC_MCS03_S 24
/* Bits for R92C_TXAGC_MCS07_MCS04(x). */
#define R92C_TXAGC_MCS04_M 0x000000ff
#define R92C_TXAGC_MCS04_S 0
#define R92C_TXAGC_MCS05_M 0x0000ff00
#define R92C_TXAGC_MCS05_S 8
#define R92C_TXAGC_MCS06_M 0x00ff0000
#define R92C_TXAGC_MCS06_S 16
#define R92C_TXAGC_MCS07_M 0xff000000
#define R92C_TXAGC_MCS07_S 24
/* Bits for R92C_TXAGC_MCS11_MCS08(x). */
#define R92C_TXAGC_MCS08_M 0x000000ff
#define R92C_TXAGC_MCS08_S 0
#define R92C_TXAGC_MCS09_M 0x0000ff00
#define R92C_TXAGC_MCS09_S 8
#define R92C_TXAGC_MCS10_M 0x00ff0000
#define R92C_TXAGC_MCS10_S 16
#define R92C_TXAGC_MCS11_M 0xff000000
#define R92C_TXAGC_MCS11_S 24
/* Bits for R92C_TXAGC_MCS15_MCS12(x). */
#define R92C_TXAGC_MCS12_M 0x000000ff
#define R92C_TXAGC_MCS12_S 0
#define R92C_TXAGC_MCS13_M 0x0000ff00
#define R92C_TXAGC_MCS13_S 8
#define R92C_TXAGC_MCS14_M 0x00ff0000
#define R92C_TXAGC_MCS14_S 16
#define R92C_TXAGC_MCS15_M 0xff000000
#define R92C_TXAGC_MCS15_S 24
/* Bits for R92C_LSSI_PARAM(i). */
#define R92C_LSSI_PARAM_DATA_M 0x000fffff
#define R92C_LSSI_PARAM_DATA_S 0
#define R92C_LSSI_PARAM_ADDR_M 0x03f00000
#define R92C_LSSI_PARAM_ADDR_S 20
/* Bits for R92C_FPGA0_RFIFACEOE(0). */
#define R92C_FPGA0_RFIFACEOE0_ANT_M 0x00000300
#define R92C_FPGA0_RFIFACEOE0_ANT_S 8
/* Bits for R92C_FPGA0_ANAPARAM2. */
#define R92C_FPGA0_ANAPARAM2_CBW20 0x00000400
/* Bits for R92C_LSSI_READBACK(i). */
#define R92C_LSSI_READBACK_DATA_M 0x000fffff
#define R92C_LSSI_READBACK_DATA_S 0
/* Bits for R92C_OFDM0_AGCCORE1(i). */
#define R92C_OFDM0_AGCCORE1_GAIN_M 0x0000007f
#define R92C_OFDM0_AGCCORE1_GAIN_S 0
/*
* RF (6052) registers.
*/
#define R92C_RF_AC 0x00
#define R92C_RF_IQADJ_G(i) (0x01 + (i))
#define R92C_RF_POW_TRSW 0x05
#define R92C_RF_GAIN_RX 0x06
#define R92C_RF_GAIN_TX 0x07
#define R92C_RF_TXM_IDAC 0x08
#define R92C_RF_BS_IQGEN 0x0f
#define R92C_RF_MODE1 0x10
#define R92C_RF_MODE2 0x11
#define R92C_RF_RX_AGC_HP 0x12
#define R92C_RF_TX_AGC 0x13
#define R92C_RF_BIAS 0x14
#define R92C_RF_IPA 0x15
#define R92C_RF_POW_ABILITY 0x17
#define R92C_RF_CHNLBW 0x18
#define R92C_RF_RX_G1 0x1a
#define R92C_RF_RX_G2 0x1b
#define R92C_RF_RX_BB2 0x1c
#define R92C_RF_RX_BB1 0x1d
#define R92C_RF_RCK1 0x1e
#define R92C_RF_RCK2 0x1f
#define R92C_RF_TX_G(i) (0x20 + (i))
#define R92C_RF_TX_BB1 0x23
#define R92C_RF_T_METER 0x24
#define R92C_RF_SYN_G(i) (0x25 + (i))
#define R92C_RF_RCK_OS 0x30
#define R92C_RF_TXPA_G(i) (0x31 + (i))
/* Bits for R92C_RF_AC. */
#define R92C_RF_AC_MODE_M 0x70000
#define R92C_RF_AC_MODE_S 16
#define R92C_RF_AC_MODE_STANDBY 1
/* Bits for R92C_RF_CHNLBW. */
#define R92C_RF_CHNLBW_CHNL_M 0x003ff
#define R92C_RF_CHNLBW_CHNL_S 0
#define R92C_RF_CHNLBW_BW20 0x00400
#define R92C_RF_CHNLBW_LCSTART 0x08000
/* Bits for R92C_RF_T_METER. */
#define R92C_RF_T_METER_START 0x60
#define R92C_RF_T_METER_VAL_M 0x1f
#define R92C_RF_T_METER_VAL_S 0
#endif /* R92C_REG_H */

View File

@ -0,0 +1,95 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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>
#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
uint32_t
r92c_rf_read(struct rtwn_softc *sc, int chain, uint8_t addr)
{
struct r92c_softc *rs = sc->sc_priv;
uint32_t reg[R92C_MAX_CHAINS], val;
reg[0] = rtwn_bb_read(sc, R92C_HSSI_PARAM2(0));
if (chain != 0)
reg[chain] = rtwn_bb_read(sc, R92C_HSSI_PARAM2(chain));
rtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
reg[0] & ~R92C_HSSI_PARAM2_READ_EDGE);
rtwn_delay(sc, rs->rf_read_delay[0]);
rtwn_bb_write(sc, R92C_HSSI_PARAM2(chain),
RW(reg[chain], R92C_HSSI_PARAM2_READ_ADDR, addr) |
R92C_HSSI_PARAM2_READ_EDGE);
rtwn_delay(sc, rs->rf_read_delay[1]);
rtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
reg[0] | R92C_HSSI_PARAM2_READ_EDGE);
rtwn_delay(sc, rs->rf_read_delay[2]);
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
r92c_rf_write(struct rtwn_softc *sc, int chain, uint8_t addr,
uint32_t val)
{
rtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
SM(R92C_LSSI_PARAM_ADDR, addr) |
SM(R92C_LSSI_PARAM_DATA, val));
}

View File

@ -0,0 +1,141 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_efuse.h>
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_priv.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/r92c_rom_image.h>
static void
r92c_set_chains(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
if (rs->chip & R92C_CHIP_92C) {
sc->ntxchains = (rs->chip & R92C_CHIP_92C_1T2R) ? 1 : 2;
sc->nrxchains = 2;
} else {
sc->ntxchains = 1;
sc->nrxchains = 1;
}
}
void
r92c_efuse_postread(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
/* XXX Weird but this is what the vendor driver does. */
sc->next_rom_addr = 0x1fa;
(void) rtwn_efuse_read_next(sc, &rs->pa_setting);
RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "%s: PA setting=0x%x\n", __func__,
rs->pa_setting);
}
void
r92c_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
{
struct r92c_softc *rs = sc->sc_priv;
struct rtwn_r92c_txpwr *rt = rs->rs_txpwr;
struct r92c_rom *rom = (struct r92c_rom *)buf;
int i, j;
rs->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE);
rs->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
RTWN_DPRINTF(sc, RTWN_DEBUG_ROM, "%s: regulatory type=%d\n",
__func__, rs->regulatory);
/* Need to be set before postinit() (but after preinit()). */
rtwn_r92c_set_name(sc);
r92c_set_chains(sc);
for (j = 0; j < R92C_GROUP_2G; j++) {
for (i = 0; i < sc->ntxchains; i++) {
rt->cck_tx_pwr[i][j] = rom->cck_tx_pwr[i][j];
rt->ht40_1s_tx_pwr[i][j] = rom->ht40_1s_tx_pwr[i][j];
}
rt->ht40_2s_tx_pwr_diff[0][j] =
MS(rom->ht40_2s_tx_pwr_diff[j], LOW_PART);
rt->ht20_tx_pwr_diff[0][j] =
RTWN_SIGN4TO8(MS(rom->ht20_tx_pwr_diff[j],
LOW_PART));
rt->ofdm_tx_pwr_diff[0][j] =
MS(rom->ofdm_tx_pwr_diff[j], LOW_PART);
rt->ht40_max_pwr[0][j] =
MS(rom->ht40_max_pwr[j], LOW_PART);
rt->ht20_max_pwr[0][j] =
MS(rom->ht20_max_pwr[j], LOW_PART);
if (sc->ntxchains > 1) {
rt->ht40_2s_tx_pwr_diff[1][j] =
MS(rom->ht40_2s_tx_pwr_diff[j], HIGH_PART);
rt->ht20_tx_pwr_diff[1][j] =
RTWN_SIGN4TO8(MS(rom->ht20_tx_pwr_diff[j],
HIGH_PART));
rt->ofdm_tx_pwr_diff[1][j] =
MS(rom->ofdm_tx_pwr_diff[j], HIGH_PART);
rt->ht40_max_pwr[1][j] =
MS(rom->ht40_max_pwr[j], HIGH_PART);
rt->ht20_max_pwr[1][j] =
MS(rom->ht20_max_pwr[j], HIGH_PART);
}
}
sc->thermal_meter = MS(rom->thermal_meter, R92C_ROM_THERMAL_METER);
if (sc->thermal_meter == R92C_ROM_THERMAL_METER_M)
sc->thermal_meter = 0xff;
IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
}

View File

@ -0,0 +1,57 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92C_ROM_DEFS_H
#define R92C_ROM_DEFS_H
#define R92C_MAX_CHAINS 2
#define R92C_GROUP_2G 3
#define R92C_EFUSE_MAX_LEN 512
#define R92C_EFUSE_MAP_LEN 128
/*
* Some generic rom parsing macros.
*/
#define RTWN_GET_ROM_VAR(var, def) (((var) != 0xff) ? (var) : (def))
#define RTWN_SIGN4TO8(val) (((val) & 0x08) ? (val) | 0xf0 : (val))
#define LOW_PART_M 0x0f
#define LOW_PART_S 0
#define HIGH_PART_M 0xf0
#define HIGH_PART_S 4
/* Bits for rf_board_opt (rf_opt1) field. */
#define R92C_ROM_RF1_REGULATORY_M 0x07
#define R92C_ROM_RF1_REGULATORY_S 0
#define R92C_ROM_RF1_BOARD_TYPE_M 0xe0
#define R92C_ROM_RF1_BOARD_TYPE_S 5
/* Generic board types. */
#define R92C_BOARD_TYPE_DONGLE 0
#define R92C_BOARD_TYPE_HIGHPA 1
#define R92C_BOARD_TYPE_MINICARD 2
#define R92C_BOARD_TYPE_SOLO 3
#define R92C_BOARD_TYPE_COMBO 4
/* Bits for channel_plan field. */
#define R92C_CHANNEL_PLAN_BY_HW 0x80
#endif /* R92C_ROM_DEFS_H */

View File

@ -0,0 +1,71 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92C_ROM_IMAGE_H
#define R92C_ROM_IMAGE_H
#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
/*
* RTL8192CU ROM image.
*/
struct r92c_rom {
uint16_t id; /* 0x8192 */
uint8_t reserved1[5];
uint8_t dbg_sel;
uint16_t reserved2;
uint16_t vid;
uint16_t pid;
uint8_t usb_opt;
uint8_t ep_setting;
uint16_t reserved3;
uint8_t usb_phy;
uint8_t reserved4[3];
uint8_t macaddr[IEEE80211_ADDR_LEN];
uint8_t string[61]; /* "Realtek" */
uint8_t subcustomer_id;
uint8_t cck_tx_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
uint8_t ht40_1s_tx_pwr[R92C_MAX_CHAINS][R92C_GROUP_2G];
uint8_t ht40_2s_tx_pwr_diff[R92C_GROUP_2G];
uint8_t ht20_tx_pwr_diff[R92C_GROUP_2G];
uint8_t ofdm_tx_pwr_diff[R92C_GROUP_2G];
uint8_t ht40_max_pwr[R92C_GROUP_2G];
uint8_t ht20_max_pwr[R92C_GROUP_2G];
uint8_t xtal_calib;
uint8_t tssi[R92C_MAX_CHAINS];
uint8_t thermal_meter;
#define R92C_ROM_THERMAL_METER_M 0x1f
#define R92C_ROM_THERMAL_METER_S 0
uint8_t rf_opt1;
uint8_t rf_opt2;
uint8_t rf_opt3;
uint8_t rf_opt4;
uint8_t channel_plan;
#define R92C_CHANNEL_PLAN_BY_HW 0x80
uint8_t version;
uint8_t customer_id;
} __packed;
_Static_assert(sizeof(struct r92c_rom) == R92C_EFUSE_MAP_LEN,
"R92C_EFUSE_MAP_LEN must be equal to sizeof(struct r92c_rom)!");
#endif /* R92C_ROM_IMAGE_H */

View File

@ -0,0 +1,104 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_ridx.h>
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_rx_desc.h>
int8_t
r92c_get_rssi_cck(struct rtwn_softc *sc, void *physt)
{
static const int8_t cckoff[] = { 16, -12, -26, -46 };
struct r92c_rx_cck *cck = (struct r92c_rx_cck *)physt;
uint8_t rpt;
int8_t rssi;
if (sc->sc_flags & RTWN_FLAG_CCK_HIPWR) {
rpt = (cck->agc_rpt >> 5) & 0x03;
rssi = (cck->agc_rpt & 0x1f) << 1;
} else {
rpt = (cck->agc_rpt >> 6) & 0x03;
rssi = cck->agc_rpt & 0x3e;
}
rssi = cckoff[rpt] - rssi;
return (rssi);
}
int8_t
r92c_get_rssi_ofdm(struct rtwn_softc *sc, void *physt)
{
struct r92c_rx_phystat *phy = (struct r92c_rx_phystat *)physt;
int rssi;
/* Get average RSSI. */
rssi = ((phy->pwdb_all >> 1) & 0x7f) - 110;
return (rssi);
}
uint8_t
r92c_rx_radiotap_flags(const void *buf)
{
const struct r92c_rx_stat *stat = buf;
uint8_t flags, rate;
if (!(stat->rxdw3 & htole32(R92C_RXDW3_SPLCP)))
return (0);
rate = MS(le32toh(stat->rxdw3), R92C_RXDW3_RATE);
if (RTWN_RATE_IS_CCK(rate))
flags = IEEE80211_RADIOTAP_F_SHORTPRE;
else
flags = IEEE80211_RADIOTAP_F_SHORTGI;
return (flags);
}

View File

@ -0,0 +1,95 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92C_RX_DESC_H
#define R92C_RX_DESC_H
/* Rx MAC descriptor (common parts / USB). */
struct r92c_rx_stat {
uint32_t rxdw0;
#define R92C_RXDW0_PKTLEN_M 0x00003fff
#define R92C_RXDW0_PKTLEN_S 0
#define R92C_RXDW0_CRCERR 0x00004000
#define R92C_RXDW0_ICVERR 0x00008000
#define R92C_RXDW0_INFOSZ_M 0x000f0000
#define R92C_RXDW0_INFOSZ_S 16
#define R92C_RXDW0_CIPHER_M 0x00700000
#define R92C_RXDW0_CIPHER_S 20
#define R92C_RXDW0_QOS 0x00800000
#define R92C_RXDW0_SHIFT_M 0x03000000
#define R92C_RXDW0_SHIFT_S 24
#define R92C_RXDW0_PHYST 0x04000000
#define R92C_RXDW0_SWDEC 0x08000000
#define R92C_RXDW0_LS 0x10000000
#define R92C_RXDW0_FS 0x20000000
#define R92C_RXDW0_EOR 0x40000000
#define R92C_RXDW0_OWN 0x80000000
uint32_t rxdw1;
#define R92C_RXDW1_MACID_M 0x0000001f
#define R92C_RXDW1_MACID_S 0
#define R92C_RXDW1_MC 0x40000000
#define R92C_RXDW1_BC 0x80000000
uint32_t rxdw2;
uint32_t rxdw3;
#define R92C_RXDW3_RATE_M 0x0000003f
#define R92C_RXDW3_RATE_S 0
#define R92C_RXDW3_HT 0x00000040
#define R92C_RXDW3_SPLCP 0x00000100
#define R92C_RXDW3_HT40 0x00000200
#define R92C_RXDW3_HTC 0x00000400
uint32_t rxdw4;
uint32_t tsf_low;
} __packed __attribute__((aligned(4)));
/* Rx PHY CCK descriptor. */
struct r92c_rx_cck {
uint8_t adc_pwdb[4];
uint8_t sq_rpt;
uint8_t agc_rpt;
} __packed;
/* Rx PHY descriptor. */
struct r92c_rx_phystat {
uint8_t trsw_gain[4];
uint8_t pwdb_all;
uint8_t cfosho[4];
uint8_t cfotail[4];
uint8_t rxevm[2];
uint8_t rxsnr[4];
uint8_t pdsnr[2];
uint8_t csi_current[2];
uint8_t csi_target[2];
uint8_t sigevm;
uint8_t max_ex_pwr;
uint8_t phy_byte28;
#define R92C_PHY_BYTE28_ANTSEL 0x01
#define R92C_PHY_BYTE28_ANTSEL_B 0x02
#define R92C_PHY_BYTE28_ANT_TRAIN_EN 0x04
#define R92C_PHY_BYTE28_IDLE_LONG 0x08
#define R92C_PHY_BYTE28_RXSC_M 0x30
#define R92C_PHY_BYTE28_RXSC_S 4
#define R92C_PHY_BYTE28_SGI_EN 0x40
#define R92C_PHY_BYTE28_EX_INTF_FLG 0x80
} __packed;
#endif /* R92C_RX_DESC_H */

View File

@ -0,0 +1,438 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_ridx.h>
#include <dev/rtwn/if_rtwn_tx.h>
#include <dev/rtwn/rtl8192c/r92c.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
static int
r92c_tx_get_sco(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
if (IEEE80211_IS_CHAN_HT40U(c))
return (R92C_TXDW4_SCO_SCA);
else
return (R92C_TXDW4_SCO_SCB);
}
static void
r92c_tx_set_ht40(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
if (ni->ni_chan != IEEE80211_CHAN_ANYC &&
IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
int extc_offset;
extc_offset = r92c_tx_get_sco(sc, ni->ni_chan);
txd->txdw4 |= htole32(R92C_TXDW4_DATA_BW40);
txd->txdw4 |= htole32(SM(R92C_TXDW4_DATA_SCO, extc_offset));
}
}
static void
r92c_tx_protection(struct rtwn_softc *sc, struct r92c_tx_desc *txd,
enum ieee80211_protmode mode, uint8_t ridx)
{
struct ieee80211com *ic = &sc->sc_ic;
uint8_t rate;
switch (mode) {
case IEEE80211_PROT_CTSONLY:
txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF);
break;
case IEEE80211_PROT_RTSCTS:
txd->txdw4 |= htole32(R92C_TXDW4_RTSEN);
break;
default:
break;
}
if (mode == IEEE80211_PROT_CTSONLY ||
mode == IEEE80211_PROT_RTSCTS) {
if (ridx >= RTWN_RIDX_MCS(0))
rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx);
else
rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]);
ridx = rate2ridx(rate);
txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, ridx));
/* RTS rate fallback limit (max). */
txd->txdw5 |= htole32(SM(R92C_TXDW5_RTSRATE_FB_LMT, 0xf));
if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 &&
(ic->ic_flags & IEEE80211_F_SHPREAMBLE))
txd->txdw4 |= htole32(R92C_TXDW4_RTS_SHORT);
}
}
static void
r92c_tx_raid(struct rtwn_softc *sc, struct r92c_tx_desc *txd,
struct ieee80211_node *ni, int ismcast)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_channel *chan;
enum ieee80211_phymode mode;
uint8_t raid;
chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
ni->ni_chan : ic->ic_curchan;
mode = ieee80211_chan2mode(chan);
/* NB: group addressed frames are done at 11bg rates for now */
if (ismcast || !(ni->ni_flags & IEEE80211_NODE_HT)) {
switch (mode) {
case IEEE80211_MODE_11B:
case IEEE80211_MODE_11G:
break;
case IEEE80211_MODE_11NG:
mode = IEEE80211_MODE_11G;
break;
default:
device_printf(sc->sc_dev, "unknown mode(1) %d!\n",
ic->ic_curmode);
return;
}
}
switch (mode) {
case IEEE80211_MODE_11B:
raid = R92C_RAID_11B;
break;
case IEEE80211_MODE_11G:
if (vap->iv_flags & IEEE80211_F_PUREG)
raid = R92C_RAID_11G;
else
raid = R92C_RAID_11BG;
break;
case IEEE80211_MODE_11NG:
if (vap->iv_flags_ht & IEEE80211_FHT_PUREN)
raid = R92C_RAID_11N;
else
raid = R92C_RAID_11BGN;
break;
default:
device_printf(sc->sc_dev, "unknown mode(2) %d!\n", mode);
return;
}
txd->txdw1 |= htole32(SM(R92C_TXDW1_RAID, raid));
}
/* XXX move to device-independent layer */
static void
r92c_tx_set_sgi(struct rtwn_softc *sc, void *buf, struct ieee80211_node *ni)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
struct ieee80211vap *vap = ni->ni_vap;
if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) && /* HT20 */
(ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20))
txd->txdw5 |= htole32(R92C_TXDW5_SGI);
else if (ni->ni_chan != IEEE80211_CHAN_ANYC && /* HT40 */
IEEE80211_IS_CHAN_HT40(ni->ni_chan) &&
(ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) &&
(vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40))
txd->txdw5 |= htole32(R92C_TXDW5_SGI);
}
void
r92c_tx_enable_ampdu(void *buf, int enable)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
if (enable)
txd->txdw1 |= htole32(R92C_TXDW1_AGGEN);
else
txd->txdw1 |= htole32(R92C_TXDW1_AGGBK);
}
void
r92c_tx_setup_hwseq(void *buf)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ_EN);
}
void
r92c_tx_setup_macid(void *buf, int id)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
txd->txdw1 |= htole32(SM(R92C_TXDW1_MACID, id));
}
void
r92c_fill_tx_desc(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m, void *buf, uint8_t ridx, int maxretry)
{
#ifndef RTWN_WITHOUT_UCODE
struct r92c_softc *rs = sc->sc_priv;
#endif
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct rtwn_vap *uvp = RTWN_VAP(vap);
struct ieee80211_frame *wh;
struct r92c_tx_desc *txd;
enum ieee80211_protmode prot;
uint8_t type, tid, qos, qsel;
int hasqos, ismcast, macid;
wh = mtod(m, struct ieee80211_frame *);
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
hasqos = IEEE80211_QOS_HAS_SEQ(wh);
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
/* Select TX ring for this frame. */
if (hasqos) {
qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
tid = qos & IEEE80211_QOS_TID;
} else {
qos = 0;
tid = 0;
}
/* Fill Tx descriptor. */
txd = (struct r92c_tx_desc *)buf;
txd->flags0 |= R92C_FLAGS0_LSG | R92C_FLAGS0_FSG;
if (ismcast)
txd->flags0 |= R92C_FLAGS0_BMCAST;
if (!ismcast) {
/* Unicast frame, check if an ACK is expected. */
if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) !=
IEEE80211_QOS_ACKPOLICY_NOACK) {
txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA);
txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT,
maxretry));
}
struct rtwn_node *un = RTWN_NODE(ni);
macid = un->id;
if (type == IEEE80211_FC0_TYPE_DATA) {
qsel = tid % RTWN_MAX_TID;
rtwn_r92c_tx_enable_ampdu(sc, buf,
(m->m_flags & M_AMPDU_MPDU) != 0);
if (m->m_flags & M_AMPDU_MPDU) {
txd->txdw2 |= htole32(SM(R92C_TXDW2_AMPDU_DEN,
vap->iv_ampdu_density));
txd->txdw6 |= htole32(SM(R92C_TXDW6_MAX_AGG,
0x1f)); /* XXX */
}
if (sc->sc_ratectl == RTWN_RATECTL_NET80211) {
txd->txdw2 |= htole32(R92C_TXDW2_CCX_RPT);
sc->sc_tx_n_active++;
#ifndef RTWN_WITHOUT_UCODE
rs->rs_c2h_pending++;
#endif
}
if (RTWN_RATE_IS_CCK(ridx) && ridx != RTWN_RIDX_CCK1 &&
(ic->ic_flags & IEEE80211_F_SHPREAMBLE))
txd->txdw4 |= htole32(R92C_TXDW4_DATA_SHPRE);
prot = IEEE80211_PROT_NONE;
if (ridx >= RTWN_RIDX_MCS(0)) {
r92c_tx_set_ht40(sc, txd, ni);
r92c_tx_set_sgi(sc, txd, ni);
prot = ic->ic_htprotmode;
} else if (ic->ic_flags & IEEE80211_F_USEPROT)
prot = ic->ic_protmode;
/* XXX fix last comparison for A-MSDU (in net80211) */
/* XXX A-MPDU? */
if (m->m_pkthdr.len + IEEE80211_CRC_LEN >
vap->iv_rtsthreshold &&
vap->iv_rtsthreshold != IEEE80211_RTS_MAX)
prot = IEEE80211_PROT_RTSCTS;
/* NB: checks for ht40 / short bits (set above). */
if (prot != IEEE80211_PROT_NONE)
r92c_tx_protection(sc, txd, prot, ridx);
} else /* IEEE80211_FC0_TYPE_MGT */
qsel = R92C_TXDW1_QSEL_MGNT;
} else {
macid = RTWN_MACID_BC;
qsel = R92C_TXDW1_QSEL_MGNT;
}
txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, qsel));
rtwn_r92c_tx_setup_macid(sc, txd, macid);
txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx));
/* Data rate fallback limit (max). */
txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE_FB_LMT, 0x1f));
txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, uvp->id));
r92c_tx_raid(sc, txd, ni, ismcast);
/* Force this rate if needed. */
if (sc->sc_ratectl != RTWN_RATECTL_FW)
txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
if (!hasqos) {
/* Use HW sequence numbering for non-QoS frames. */
rtwn_r92c_tx_setup_hwseq(sc, txd);
txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, uvp->id));
} else {
uint16_t seqno;
if (m->m_flags & M_AMPDU_MPDU) {
seqno = ni->ni_txseqs[tid];
/* NB: clear Fragment Number field. */
*(uint16_t *)wh->i_seq = 0;
ni->ni_txseqs[tid]++;
} else
seqno = M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE;
/* Set sequence number. */
txd->txdseq = htole16(seqno);
}
}
void
r92c_fill_tx_desc_raw(struct rtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m, void *buf, const struct ieee80211_bpf_params *params)
{
struct ieee80211vap *vap = ni->ni_vap;
struct rtwn_vap *uvp = RTWN_VAP(vap);
struct ieee80211_frame *wh;
struct r92c_tx_desc *txd;
uint8_t ridx;
int ismcast;
/* XXX TODO: 11n checks, matching r92c_fill_tx_desc() */
wh = mtod(m, struct ieee80211_frame *);
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
ridx = rate2ridx(params->ibp_rate0);
/* Fill Tx descriptor. */
txd = (struct r92c_tx_desc *)buf;
txd->flags0 |= R92C_FLAGS0_LSG | R92C_FLAGS0_FSG;
if (ismcast)
txd->flags0 |= R92C_FLAGS0_BMCAST;
if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) {
txd->txdw5 |= htole32(R92C_TXDW5_RTY_LMT_ENA);
txd->txdw5 |= htole32(SM(R92C_TXDW5_RTY_LMT,
params->ibp_try0));
}
if (params->ibp_flags & IEEE80211_BPF_RTS)
r92c_tx_protection(sc, txd, IEEE80211_PROT_RTSCTS, ridx);
if (params->ibp_flags & IEEE80211_BPF_CTS)
r92c_tx_protection(sc, txd, IEEE80211_PROT_CTSONLY, ridx);
rtwn_r92c_tx_setup_macid(sc, txd, RTWN_MACID_BC);
txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT));
/* Set TX rate index. */
txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, ridx));
txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE_FB_LMT, 0x1f));
txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, uvp->id));
txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
r92c_tx_raid(sc, txd, ni, ismcast);
if (!IEEE80211_QOS_HAS_SEQ(wh)) {
/* Use HW sequence numbering for non-QoS frames. */
rtwn_r92c_tx_setup_hwseq(sc, txd);
txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, uvp->id));
} else {
/* Set sequence number. */
txd->txdseq |= htole16(M_SEQNO_GET(m) % IEEE80211_SEQ_RANGE);
}
}
void
r92c_fill_tx_desc_null(struct rtwn_softc *sc, void *buf, int is11b,
int qos, int id)
{
struct r92c_tx_desc *txd = (struct r92c_tx_desc *)buf;
txd->flags0 = R92C_FLAGS0_FSG | R92C_FLAGS0_LSG | R92C_FLAGS0_OWN;
txd->txdw1 = htole32(
SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT));
txd->txdw4 = htole32(R92C_TXDW4_DRVRATE);
txd->txdw4 |= htole32(SM(R92C_TXDW4_PORT_ID, id));
if (is11b) {
txd->txdw5 = htole32(SM(R92C_TXDW5_DATARATE,
RTWN_RIDX_CCK1));
} else {
txd->txdw5 = htole32(SM(R92C_TXDW5_DATARATE,
RTWN_RIDX_OFDM6));
}
if (!qos) {
rtwn_r92c_tx_setup_hwseq(sc, txd);
txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, id));
}
}
uint8_t
r92c_tx_radiotap_flags(const void *buf)
{
const struct r92c_tx_desc *txd = buf;
uint8_t flags;
flags = 0;
if (txd->txdw4 & htole32(R92C_TXDW4_DATA_SHPRE))
flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
if (txd->txdw5 & htole32(R92C_TXDW5_SGI))
flags |= IEEE80211_RADIOTAP_F_SHORTGI;
return (flags);
}

View File

@ -0,0 +1,122 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92C_TX_DESC_H
#define R92C_TX_DESC_H
/* Tx MAC descriptor (common part). */
struct r92c_tx_desc {
uint16_t pktlen;
uint8_t offset;
uint8_t flags0;
#define R92C_FLAGS0_BMCAST 0x01
#define R92C_FLAGS0_LSG 0x04
#define R92C_FLAGS0_FSG 0x08
#define R92C_FLAGS0_OWN 0x80
uint32_t txdw1;
#define R92C_TXDW1_MACID_M 0x0000001f
#define R92C_TXDW1_MACID_S 0
#define R92C_TXDW1_AGGEN 0x00000020
#define R92C_TXDW1_AGGBK 0x00000040
#define R92C_TXDW1_QSEL_M 0x00001f00
#define R92C_TXDW1_QSEL_S 8
#define R92C_TXDW1_QSEL_BE 0x00 /* or 0x03 */
#define R92C_TXDW1_QSEL_BK 0x01 /* or 0x02 */
#define R92C_TXDW1_QSEL_VI 0x04 /* or 0x05 */
#define R92C_TXDW1_QSEL_VO 0x06 /* or 0x07 */
#define RTWN_MAX_TID 8
#define R92C_TXDW1_QSEL_BEACON 0x10
#define R92C_TXDW1_QSEL_MGNT 0x12
#define R92C_TXDW1_RAID_M 0x000f0000
#define R92C_TXDW1_RAID_S 16
#define R92C_TXDW1_CIPHER_M 0x00c00000
#define R92C_TXDW1_CIPHER_S 22
#define R92C_TXDW1_CIPHER_NONE 0
#define R92C_TXDW1_CIPHER_RC4 1
#define R92C_TXDW1_CIPHER_AES 3
#define R92C_TXDW1_PKTOFF_M 0x7c000000
#define R92C_TXDW1_PKTOFF_S 26
uint32_t txdw2;
#define R92C_TXDW2_CCX_RPT 0x00080000
#define R92C_TXDW2_AMPDU_DEN_M 0x00700000
#define R92C_TXDW2_AMPDU_DEN_S 20
uint16_t txdw3;
uint16_t txdseq;
uint32_t txdw4;
#define R92C_TXDW4_RTSRATE_M 0x0000003f
#define R92C_TXDW4_RTSRATE_S 0
#define R92C_TXDW4_SEQ_SEL_M 0x00000040
#define R92C_TXDW4_SEQ_SEL_S 6
#define R92C_TXDW4_HWSEQ_EN 0x00000080
#define R92C_TXDW4_DRVRATE 0x00000100
#define R92C_TXDW4_CTS2SELF 0x00000800
#define R92C_TXDW4_RTSEN 0x00001000
#define R92C_TXDW4_HWRTSEN 0x00002000
#define R92C_TXDW4_PORT_ID_M 0x00004000
#define R92C_TXDW4_PORT_ID_S 14
#define R92C_TXDW4_DATA_SCO_M 0x00300000
#define R92C_TXDW4_DATA_SCO_S 20
#define R92C_TXDW4_SCO_SCA 1
#define R92C_TXDW4_SCO_SCB 2
#define R92C_TXDW4_DATA_SHPRE 0x01000000
#define R92C_TXDW4_DATA_BW40 0x02000000
#define R92C_TXDW4_RTS_SHORT 0x04000000
#define R92C_TXDW4_RTS_BW40 0x08000000
#define R92C_TXDW4_RTS_SCO_M 0x30000000
#define R92C_TXDW4_RTS_SCO_S 28
uint32_t txdw5;
#define R92C_TXDW5_DATARATE_M 0x0000003f
#define R92C_TXDW5_DATARATE_S 0
#define R92C_TXDW5_SGI 0x00000040
#define R92C_TXDW5_DATARATE_FB_LMT_M 0x00001f00
#define R92C_TXDW5_DATARATE_FB_LMT_S 8
#define R92C_TXDW5_RTSRATE_FB_LMT_M 0x0001e000
#define R92C_TXDW5_RTSRATE_FB_LMT_S 13
#define R92C_TXDW5_RTY_LMT_ENA 0x00020000
#define R92C_TXDW5_RTY_LMT_M 0x00fc0000
#define R92C_TXDW5_RTY_LMT_S 18
#define R92C_TXDW5_AGGNUM_M 0xff000000
#define R92C_TXDW5_AGGNUM_S 24
uint32_t txdw6;
#define R92C_TXDW6_MAX_AGG_M 0x0000f800
#define R92C_TXDW6_MAX_AGG_S 11
} __packed __attribute__((aligned(4)));
/* Rate adaptation modes. */
#define R92C_RAID_11BGN 0
#define R92C_RAID_11GN 1
#define R92C_RAID_11BN 2
#define R92C_RAID_11N 3
#define R92C_RAID_11BG 4
#define R92C_RAID_11G 5 /* "pure" 11g */
#define R92C_RAID_11B 6
#endif /* R92C_TX_DESC_H */

View File

@ -0,0 +1,83 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92C_VAR_H
#define R92C_VAR_H
#include <dev/rtwn/rtl8192c/r92c_rom_defs.h>
struct r92c_softc {
uint8_t rs_flags;
#define R92C_FLAG_ASSOCIATED 0x01
uint8_t chip;
#define R92C_CHIP_92C 0x01
#define R92C_CHIP_92C_1T2R 0x02
#define R92C_CHIP_UMC_A_CUT 0x04
#ifndef RTWN_WITHOUT_UCODE
struct callout rs_c2h_report;
int rs_c2h_timeout;
int rs_c2h_pending;
int rs_c2h_paused;
#endif
#define R92C_TX_PAUSED_THRESHOLD 20
void *rs_txpwr;
const void *rs_txagc;
uint8_t board_type;
uint8_t regulatory;
uint8_t crystalcap;
uint8_t pa_setting;
void (*rs_scan_start)(struct ieee80211com *);
void (*rs_scan_end)(struct ieee80211com *);
void (*rs_set_bw20)(struct rtwn_softc *, uint8_t);
void (*rs_get_txpower)(struct rtwn_softc *, int,
struct ieee80211_channel *, uint16_t[]);
void (*rs_set_gain)(struct rtwn_softc *, uint8_t);
void (*rs_tx_enable_ampdu)(void *, int);
void (*rs_tx_setup_hwseq)(void *);
void (*rs_tx_setup_macid)(void *, int);
void (*rs_set_name)(struct rtwn_softc *);
int rf_read_delay[3];
uint32_t rf_chnlbw[R92C_MAX_CHAINS];
};
#define R92C_SOFTC(_sc) ((struct r92c_softc *)((_sc)->sc_priv))
#define rtwn_r92c_set_bw20(_sc, _chan) \
((R92C_SOFTC(_sc)->rs_set_bw20)((_sc), (_chan)))
#define rtwn_r92c_get_txpower(_sc, _chain, _c, _power) \
((R92C_SOFTC(_sc)->rs_get_txpower)((_sc), (_chain), (_c), (_power)))
#define rtwn_r92c_set_gain(_sc, _gain) \
((R92C_SOFTC(_sc)->rs_set_gain)((_sc), (_gain)))
#define rtwn_r92c_tx_enable_ampdu(_sc, _buf, _enable) \
((R92C_SOFTC(_sc)->rs_tx_enable_ampdu)((_buf), (_enable)))
#define rtwn_r92c_tx_setup_hwseq(_sc, _buf) \
((R92C_SOFTC(_sc)->rs_tx_setup_hwseq)((_buf)))
#define rtwn_r92c_tx_setup_macid(_sc, _buf, _id) \
((R92C_SOFTC(_sc)->rs_tx_setup_macid)((_buf), (_id)))
#define rtwn_r92c_set_name(_sc) \
((R92C_SOFTC(_sc)->rs_set_name)((_sc)))
#endif /* R92C_VAR_H */

View File

@ -0,0 +1,56 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef RTL8192CU_H
#define RTL8192CU_H
#include <dev/rtwn/rtl8192c/r92c.h>
/*
* Global definitions.
*/
#define R92CU_PUBQ_NPAGES 231
#define R92CU_TX_PAGE_COUNT 248
/*
* Function declarations.
*/
/* r92cu_init.c */
void r92cu_init_bb(struct rtwn_softc *);
int r92cu_power_on(struct rtwn_softc *);
void r92cu_power_off(struct rtwn_softc *);
void r92cu_init_intr(struct rtwn_softc *);
void r92cu_init_tx_agg(struct rtwn_softc *);
void r92cu_init_rx_agg(struct rtwn_softc *);
void r92cu_post_init(struct rtwn_softc *);
/* r92cu_led.c */
void r92cu_set_led(struct rtwn_softc *, int, int);
/* r92cu_rx.c */
int r92cu_classify_intr(struct rtwn_softc *, void *, int);
int r92cu_align_rx(int, int);
/* r92cu_tx.c */
void r92cu_dump_tx_desc(struct rtwn_softc *, const void *);
#endif /* RTL8192CU_H */

View File

@ -0,0 +1,247 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_nop.h>
#include <dev/rtwn/usb/rtwn_usb_var.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_priv.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h>
static struct rtwn_r92c_txpwr r92c_txpwr;
void r92cu_attach(struct rtwn_usb_softc *);
static void
r92cu_postattach(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
struct ieee80211com *ic = &sc->sc_ic;
if (!(rs->chip & R92C_CHIP_92C) &&
rs->board_type == R92C_BOARD_TYPE_HIGHPA) {
sc->agc_prog = &rtl8188ru_agc[0];
sc->agc_size = nitems(rtl8188ru_agc);
rs->rs_txagc = &rtl8188ru_txagc[0];
} else {
sc->agc_prog = &rtl8192ce_agc[0];
sc->agc_size = nitems(rtl8192ce_agc);
rs->rs_txagc = &rtl8192cu_txagc[0];
}
if ((rs->chip & (R92C_CHIP_UMC_A_CUT | R92C_CHIP_92C)) ==
R92C_CHIP_UMC_A_CUT) {
sc->fwname = "rtwn-rtl8192cfwU";
} else {
sc->fwname = "rtwn-rtl8192cfwT";
}
sc->fwsig = 0x88c;
rs->rs_scan_start = ic->ic_scan_start;
ic->ic_scan_start = r92c_scan_start;
rs->rs_scan_end = ic->ic_scan_end;
ic->ic_scan_end = r92c_scan_end;
}
static void
r92cu_set_name(struct rtwn_softc *sc)
{
struct r92c_softc *rs = sc->sc_priv;
if (!(rs->chip & R92C_CHIP_92C)) {
if (rs->board_type == R92C_BOARD_TYPE_HIGHPA)
sc->name = "RTL8188RU";
else if (rs->board_type == R92C_BOARD_TYPE_MINICARD)
sc->name = "RTL8188CU-VAU";
else
sc->name = "RTL8188CUS";
} else
sc->name = "RTL8192CU";
}
static void
r92cu_attach_private(struct rtwn_softc *sc)
{
struct r92c_softc *rs;
rs = malloc(sizeof(struct r92c_softc), M_RTWN_PRIV, M_WAITOK | M_ZERO);
rs->rs_txpwr = &r92c_txpwr;
rs->rs_set_bw20 = r92c_set_bw20;
rs->rs_get_txpower = r92c_get_txpower;
rs->rs_set_gain = r92c_set_gain;
rs->rs_tx_enable_ampdu = r92c_tx_enable_ampdu;
rs->rs_tx_setup_hwseq = r92c_tx_setup_hwseq;
rs->rs_tx_setup_macid = r92c_tx_setup_macid;
rs->rs_set_name = r92cu_set_name;
#ifndef RTWN_WITHOUT_UCODE
rs->rs_c2h_timeout = hz;
callout_init_mtx(&rs->rs_c2h_report, &sc->sc_mtx, 0);
#endif
rs->rf_read_delay[0] = 10;
rs->rf_read_delay[1] = 100;
rs->rf_read_delay[2] = 10;
sc->sc_priv = rs;
}
static void
r92cu_adj_devcaps(struct rtwn_softc *sc)
{
/* XXX Currently broken / incomplete. */
sc->sc_ic.ic_caps &= ~IEEE80211_C_PMGT;
}
void
r92cu_attach(struct rtwn_usb_softc *uc)
{
struct rtwn_softc *sc = &uc->uc_sc;
/* USB part. */
uc->uc_align_rx = r92cu_align_rx;
uc->tx_agg_desc_num = 6;
/* Common part. */
sc->sc_flags = RTWN_FLAG_CAM_FIXED;
sc->sc_set_chan = r92c_set_chan;
sc->sc_fill_tx_desc = r92c_fill_tx_desc;
sc->sc_fill_tx_desc_raw = r92c_fill_tx_desc_raw;
sc->sc_fill_tx_desc_null = r92c_fill_tx_desc_null;
sc->sc_dump_tx_desc = r92cu_dump_tx_desc;
sc->sc_tx_radiotap_flags = r92c_tx_radiotap_flags;
sc->sc_rx_radiotap_flags = r92c_rx_radiotap_flags;
sc->sc_get_rssi_cck = r92c_get_rssi_cck;
sc->sc_get_rssi_ofdm = r92c_get_rssi_ofdm;
sc->sc_classify_intr = r92cu_classify_intr;
sc->sc_handle_tx_report = rtwn_nop_softc_uint8_int;
sc->sc_handle_c2h_report = rtwn_nop_softc_uint8_int;
sc->sc_check_frame = rtwn_nop_int_softc_mbuf;
sc->sc_rf_read = r92c_rf_read;
sc->sc_rf_write = r92c_rf_write;
sc->sc_check_condition = r92c_check_condition;
sc->sc_efuse_postread = r92c_efuse_postread;
sc->sc_parse_rom = r92c_parse_rom;
sc->sc_set_led = r92cu_set_led;
sc->sc_power_on = r92cu_power_on;
sc->sc_power_off = r92cu_power_off;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_fw_reset = r92c_fw_reset;
sc->sc_fw_download_enable = r92c_fw_download_enable;
#endif
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 */
sc->sc_read_chipid_vendor = r92c_read_chipid_vendor;
sc->sc_adj_devcaps = r92cu_adj_devcaps;
sc->sc_vap_preattach = rtwn_nop_softc_vap;
sc->sc_postattach = r92cu_postattach;
sc->sc_detach_private = r92c_detach_private;
sc->sc_set_media_status = r92c_joinbss_rpt;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_set_rsvd_page = r92c_set_rsvd_page;
sc->sc_set_pwrmode = r92c_set_pwrmode;
sc->sc_set_rssi = r92c_set_rssi;
#endif
sc->sc_beacon_init = r92c_beacon_init;
sc->sc_beacon_enable = r92c_beacon_enable;
sc->sc_beacon_set_rate = rtwn_nop_void_int;
sc->sc_beacon_select = rtwn_nop_softc_int;
sc->sc_temp_measure = r92c_temp_measure;
sc->sc_temp_read = r92c_temp_read;
sc->sc_init_tx_agg = r92cu_init_tx_agg;
sc->sc_init_rx_agg = r92cu_init_rx_agg;
sc->sc_init_ampdu = r92c_init_ampdu;
sc->sc_init_intr = r92cu_init_intr;
sc->sc_init_edca = r92c_init_edca;
sc->sc_init_bb = r92cu_init_bb;
sc->sc_init_rf = r92c_init_rf;
sc->sc_init_antsel = r92c_init_antsel;
sc->sc_post_init = r92cu_post_init;
sc->sc_init_bcnq1_boundary = rtwn_nop_int_softc;
sc->mac_prog = &rtl8192cu_mac[0];
sc->mac_size = nitems(rtl8192cu_mac);
sc->bb_prog = &rtl8192cu_bb[0];
sc->bb_size = nitems(rtl8192cu_bb);
sc->rf_prog = &rtl8192c_rf[0];
sc->page_count = R92CU_TX_PAGE_COUNT;
sc->pktbuf_count = R92C_TXPKTBUF_COUNT;
sc->ackto = 0x40;
sc->npubqpages = R92CU_PUBQ_NPAGES;
sc->page_size = R92C_TX_PAGE_SIZE;
sc->txdesc_len = sizeof(struct r92cu_tx_desc);
sc->efuse_maxlen = R92C_EFUSE_MAX_LEN;
sc->efuse_maplen = R92C_EFUSE_MAP_LEN;
sc->rx_dma_size = R92C_RX_DMA_BUFFER_SIZE;
sc->macid_limit = R92C_MACID_MAX + 1;
sc->cam_entry_limit = R92C_CAM_ENTRY_COUNT;
sc->fwsize_limit = R92C_MAX_FW_SIZE;
sc->temp_delta = R92C_CALIB_THRESHOLD;
sc->bcn_status_reg[0] = R92C_TDECTRL;
sc->bcn_status_reg[1] = R92C_TDECTRL;
sc->rcr = 0;
r92cu_attach_private(sc);
}

View File

@ -0,0 +1,393 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/usb/rtwn_usb_var.h>
#include <dev/rtwn/rtl8192c/r92c_var.h>
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_reg.h>
void
r92cu_init_bb(struct rtwn_softc *sc)
{
/* 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);
rtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
rtwn_write_1(sc, R92C_RF_CTRL,
R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
rtwn_write_1(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
rtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
rtwn_write_1(sc, 0x15, 0xe9);
rtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
r92c_init_bb_common(sc);
}
int
r92cu_power_on(struct rtwn_softc *sc)
{
#define RTWN_CHK(res) do { \
if (res != 0) \
return (EIO); \
} while(0)
uint32_t reg;
int ntries;
/* Wait for autoload done bit. */
for (ntries = 0; ntries < 5000; ntries++) {
if (rtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
break;
rtwn_delay(sc, 10);
}
if (ntries == 5000) {
device_printf(sc->sc_dev,
"timeout waiting for chip autoload\n");
return (ETIMEDOUT);
}
/* Unlock ISO/CLK/Power control register. */
RTWN_CHK(rtwn_write_1(sc, R92C_RSV_CTRL, 0));
/* Move SPS into PWM mode. */
RTWN_CHK(rtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b));
/* just in case if power_off() was not properly executed. */
rtwn_delay(sc, 100);
reg = rtwn_read_1(sc, R92C_LDOV12D_CTRL);
if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
RTWN_CHK(rtwn_write_1(sc, R92C_LDOV12D_CTRL,
reg | R92C_LDOV12D_CTRL_LDV12_EN));
rtwn_delay(sc, 100);
RTWN_CHK(rtwn_setbits_1(sc, R92C_SYS_ISO_CTRL,
R92C_SYS_ISO_CTRL_MD2PP, 0));
}
/* Auto enable WLAN. */
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) {
device_printf(sc->sc_dev,
"timeout waiting for MAC auto ON\n");
return (ETIMEDOUT);
}
/* Enable radio, GPIO and LED functions. */
RTWN_CHK(rtwn_write_2(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_AFSM_HSUS |
R92C_APS_FSMCO_PDN_EN |
R92C_APS_FSMCO_PFM_ALDN));
/* Release RF digital isolation. */
RTWN_CHK(rtwn_setbits_1_shift(sc, R92C_SYS_ISO_CTRL,
R92C_SYS_ISO_CTRL_DIOR, 0, 1));
/* Initialize MAC. */
RTWN_CHK(rtwn_setbits_1(sc, R92C_APSD_CTRL,
R92C_APSD_CTRL_OFF, 0));
for (ntries = 0; ntries < 1000; ntries++) {
if (!(rtwn_read_1(sc, R92C_APSD_CTRL) &
R92C_APSD_CTRL_OFF_STATUS))
break;
rtwn_delay(sc, 50);
}
if (ntries == 1000) {
device_printf(sc->sc_dev,
"timeout waiting for MAC initialization\n");
return (ETIMEDOUT);
}
/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
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));
RTWN_CHK(rtwn_write_1(sc, 0xfe10, 0x19));
return (0);
#undef RTWN_CHK
}
void
r92cu_power_off(struct rtwn_softc *sc)
{
#ifndef RTWN_WITHOUT_UCODE
struct r92c_softc *rs = sc->sc_priv;
#endif
uint32_t reg;
int error;
/* Deinit C2H event handler. */
#ifndef RTWN_WITHOUT_UCODE
callout_stop(&rs->rs_c2h_report);
rs->rs_c2h_paused = 0;
rs->rs_c2h_pending = 0;
rs->rs_c2h_timeout = hz;
#endif
/* Block all Tx queues. */
error = rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
if (error == ENXIO) /* hardware gone */
return;
/* Disable RF */
rtwn_rf_write(sc, 0, 0, 0);
rtwn_write_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF);
/* Reset BB state machine */
rtwn_write_1(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA |
R92C_SYS_FUNC_EN_BB_GLB_RST);
rtwn_write_1(sc, R92C_SYS_FUNC_EN,
R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA);
/*
* Reset digital sequence
*/
#ifndef RTWN_WITHOUT_UCODE
if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) {
/* Reset MCU ready status */
rtwn_write_1(sc, R92C_MCUFWDL, 0);
/* If firmware in ram code, do reset */
r92c_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN);
}
#endif
/* Reset MAC and Enable 8051 */
rtwn_write_1(sc, R92C_SYS_FUNC_EN + 1,
(R92C_SYS_FUNC_EN_CPUEN |
R92C_SYS_FUNC_EN_ELDR |
R92C_SYS_FUNC_EN_HWPDN) >> 8);
/* Reset MCU ready status */
rtwn_write_1(sc, R92C_MCUFWDL, 0);
/* Disable MAC clock */
rtwn_write_2(sc, R92C_SYS_CLKR,
R92C_SYS_CLKR_ANAD16V_EN |
R92C_SYS_CLKR_ANA8M |
R92C_SYS_CLKR_LOADER_EN |
R92C_SYS_CLKR_80M_SSC_DIS |
R92C_SYS_CLKR_SYS_EN |
R92C_SYS_CLKR_RING_EN |
0x4000);
/* Disable AFE PLL */
rtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x80);
/* Gated AFE DIG_CLOCK */
rtwn_write_2(sc, R92C_AFE_XTAL_CTRL, 0x880F);
/* Isolated digital to PON */
rtwn_write_1(sc, R92C_SYS_ISO_CTRL,
R92C_SYS_ISO_CTRL_MD2PP |
R92C_SYS_ISO_CTRL_PA2PCIE |
R92C_SYS_ISO_CTRL_PD2CORE |
R92C_SYS_ISO_CTRL_IP2MAC |
R92C_SYS_ISO_CTRL_DIOP |
R92C_SYS_ISO_CTRL_DIOE);
/*
* Pull GPIO PIN to balance level and LED control
*/
/* 1. Disable GPIO[7:0] */
rtwn_write_2(sc, R92C_GPIO_IOSEL, 0x0000);
reg = rtwn_read_4(sc, R92C_GPIO_PIN_CTRL) & ~0x0000ff00;
reg |= ((reg << 8) & 0x0000ff00) | 0x00ff0000;
rtwn_write_4(sc, R92C_GPIO_PIN_CTRL, reg);
/* Disable GPIO[10:8] */
rtwn_write_1(sc, R92C_MAC_PINMUX_CFG, 0x00);
reg = rtwn_read_2(sc, R92C_GPIO_IO_SEL) & ~0x00f0;
reg |= (((reg & 0x000f) << 4) | 0x0780);
rtwn_write_2(sc, R92C_GPIO_IO_SEL, reg);
/* Disable LED0 & 1 */
rtwn_write_2(sc, R92C_LEDCFG0, 0x8080);
/*
* Reset digital sequence
*/
/* Disable ELDR clock */
rtwn_write_2(sc, R92C_SYS_CLKR,
R92C_SYS_CLKR_ANAD16V_EN |
R92C_SYS_CLKR_ANA8M |
R92C_SYS_CLKR_LOADER_EN |
R92C_SYS_CLKR_80M_SSC_DIS |
R92C_SYS_CLKR_SYS_EN |
R92C_SYS_CLKR_RING_EN |
0x4000);
/* Isolated ELDR to PON */
rtwn_write_1(sc, R92C_SYS_ISO_CTRL + 1,
(R92C_SYS_ISO_CTRL_DIOR |
R92C_SYS_ISO_CTRL_PWC_EV12V) >> 8);
/*
* Disable analog sequence
*/
/* Disable A15 power */
rtwn_write_1(sc, R92C_LDOA15_CTRL, R92C_LDOA15_CTRL_OBUF);
/* Disable digital core power */
rtwn_setbits_1(sc, R92C_LDOV12D_CTRL,
R92C_LDOV12D_CTRL_LDV12_EN, 0);
/* Enter PFM mode */
rtwn_write_1(sc, R92C_SPS0_CTRL, 0x23);
/* Set USB suspend */
rtwn_write_2(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_APDM_HOST |
R92C_APS_FSMCO_AFSM_HSUS |
R92C_APS_FSMCO_PFM_ALDN);
/* Lock ISO/CLK/Power control register. */
rtwn_write_1(sc, R92C_RSV_CTRL, 0x0E);
}
void
r92cu_init_intr(struct rtwn_softc *sc)
{
rtwn_write_4(sc, R92C_HISR, 0xffffffff);
rtwn_write_4(sc, R92C_HIMR, 0xffffffff);
}
void
r92cu_init_tx_agg(struct rtwn_softc *sc)
{
struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
uint32_t reg;
reg = rtwn_read_4(sc, R92C_TDECTRL);
reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, uc->tx_agg_desc_num);
rtwn_write_4(sc, R92C_TDECTRL, reg);
}
void
r92cu_init_rx_agg(struct rtwn_softc *sc)
{
/* Rx aggregation (DMA & USB). */
rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0,
R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0,
R92C_USB_SPECIAL_OPTION_AGG_EN);
/* XXX dehardcode */
rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
rtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
rtwn_write_1(sc, R92C_USB_AGG_TH, 8);
rtwn_write_1(sc, R92C_USB_AGG_TO, 6);
}
void
r92cu_post_init(struct rtwn_softc *sc)
{
/* Perform LO and IQ calibrations. */
r92c_iq_calib(sc);
/* Perform LC calibration. */
r92c_lc_calib(sc);
/* Fix USB interference issue. */
rtwn_write_1(sc, 0xfe40, 0xe0);
rtwn_write_1(sc, 0xfe41, 0x8d);
rtwn_write_1(sc, 0xfe42, 0x80);
r92c_pa_bias_init(sc);
/* Fix for lower temperature. */
rtwn_write_1(sc, 0x15, 0xe9);
#ifndef RTWN_WITHOUT_UCODE
if (sc->sc_flags & RTWN_FW_LOADED) {
struct r92c_softc *rs = sc->sc_priv;
if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) {
/* XXX firmware RA does not work yet */
sc->sc_ratectl = RTWN_RATECTL_NET80211;
} else
sc->sc_ratectl = sc->sc_ratectl_sysctl;
/* Start C2H event handling. */
callout_reset(&rs->rs_c2h_report, rs->rs_c2h_timeout,
r92c_handle_c2h_report, sc);
} else
#endif
sc->sc_ratectl = RTWN_RATECTL_NONE;
}

View File

@ -0,0 +1,68 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8192c/r92c_reg.h>
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
void
r92cu_set_led(struct rtwn_softc *sc, int led, int on)
{
uint8_t reg;
if (led == RTWN_LED_LINK) {
reg = rtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
if (!on)
reg |= R92C_LEDCFG0_DIS;
rtwn_write_1(sc, R92C_LEDCFG0, reg);
sc->ledlink = on; /* Save LED state. */
}
}

View File

@ -0,0 +1,322 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92CU_PRIV_H
#define R92CU_PRIV_H
#include <dev/rtwn/rtl8192c/r92c_priv.h>
/*
* MAC initialization values.
*/
static const struct rtwn_mac_prog rtl8192cu_mac[] = {
{ 0x420, 0x80 }, { 0x423, 0x00 }, { 0x430, 0x00 }, { 0x431, 0x00 },
{ 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, { 0x435, 0x05 },
{ 0x436, 0x06 }, { 0x437, 0x07 }, { 0x438, 0x00 }, { 0x439, 0x00 },
{ 0x43a, 0x00 }, { 0x43b, 0x01 }, { 0x43c, 0x04 }, { 0x43d, 0x05 },
{ 0x43e, 0x06 }, { 0x43f, 0x07 }, { 0x440, 0x5d }, { 0x441, 0x01 },
{ 0x442, 0x00 }, { 0x444, 0x15 }, { 0x445, 0xf0 }, { 0x446, 0x0f },
{ 0x447, 0x00 }, { 0x458, 0x41 }, { 0x459, 0xa8 }, { 0x45a, 0x72 },
{ 0x45b, 0xb9 }, { 0x460, 0x66 }, { 0x461, 0x66 }, { 0x462, 0x08 },
{ 0x463, 0x03 }, { 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 },
{ 0x515, 0x10 }, { 0x516, 0x0a }, { 0x517, 0x10 }, { 0x51a, 0x16 },
{ 0x524, 0x0f }, { 0x525, 0x4f }, { 0x546, 0x40 }, { 0x547, 0x00 },
{ 0x550, 0x10 }, { 0x551, 0x10 }, { 0x559, 0x02 }, { 0x55a, 0x02 },
{ 0x55d, 0xff }, { 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a },
{ 0x652, 0x20 }, { 0x63c, 0x0a }, { 0x63d, 0x0e }, { 0x63e, 0x0a },
{ 0x63f, 0x0e }, { 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 rtl8192cu_bb_regs0_88ru[] = {
0x024, 0x028, 0x040, 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, 0x89c, 0x900, 0x904,
0x908, 0x90c, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18,
0xa1c, 0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 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
}, rtl8192cu_bb_regs0[] = {
0x024, 0x028, 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, 0x89c, 0x900, 0x904, 0x908,
0x90c, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, 0xa18, 0xa1c,
0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 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
}, rtl8192cu_bb_regs1[] = {
0xc74, 0xc78, 0xc7c, 0xc80, 0xc84, 0xc88
}, rtl8192cu_bb_regs2[] = {
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
}, rtl8192cu_bb_regs5_88ru[] = {
0xe60, 0xe68, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec, 0xee8,
0xf14, 0xf4c, 0xf00
};
static const uint32_t rtl8192cu_bb_vals0_88cu[] = {
0x0011800d, 0x00ffdb83, 0x80040000, 0x00000001, 0x0000fc00,
0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
0x01000100, 0x00390004, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x569a569a,
0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000, 0x32323200,
0x07000700, 0x22004000, 0x00000808, 0x00000000, 0xc0083070,
0x000004d5, 0x00000000, 0xccc000c0, 0x00000800, 0xfffffffe,
0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
0x48071d40, 0x03a05611, 0x000000e4, 0x6c6c6c6c, 0x08800000,
0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf, 0x49795994,
0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
0x6954341e, 0x43bc0094, 0x6954341e, 0x433c0094, 0x00000000,
0x5116848b, 0x47c00bff, 0x00000036, 0x2c7f000d
}, rtl8192cu_bb_vals0_88ru[] = {
0x0011800d, 0x00ffdb83, 0x000c0004, 0x80040000, 0x00000001,
0x0000fc00, 0x0000000a, 0x10005388, 0x020c3d10, 0x02200385,
0x00000000, 0x01000100, 0x00390204, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x569a569a, 0x001b25a4, 0x66e60230, 0x061f0130, 0x00000000,
0x32323200, 0x03000300, 0x22004000, 0x00000808, 0x00ffc3f1,
0xc0083070, 0x000004d5, 0x00000000, 0xccc000c0, 0x00000800,
0xfffffffe, 0x40302010, 0x00706050, 0x00000000, 0x00000023,
0x00000000, 0x81121111, 0x00d047c8, 0x80ff000c, 0x8c838300,
0x2e68120f, 0x9500bb78, 0x11144028, 0x00881117, 0x89140f00,
0x15160000, 0x070b0f12, 0x00000104, 0x00d30000, 0x101fbf00,
0x00000007, 0x48071d40, 0x03a05611, 0x000000e4, 0x6c6c6c6c,
0x08800000, 0x40000100, 0x08800000, 0x40000100, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf,
0x49795994, 0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107,
0x007f037f, 0x6954342e, 0x43bc0094, 0x6954342f, 0x433c0094,
0x00000000, 0x5116848b, 0x47c00bff, 0x00000036, 0x2c56000d
}, rtl8192cu_bb_vals0_92ce_92cu[] = {
0x0011800d, 0x00ffdb83, 0x80040002, 0x00000003, 0x0000fc00,
0x0000000a, 0x10005388, 0x020c3d10, 0x02200385, 0x00000000,
0x01000100, 0x00390004, 0x01000100, 0x00390004, 0x27272727,
0x27272727, 0x27272727, 0x27272727, 0x00010000, 0x00010000,
0x27272727, 0x27272727, 0x00000000, 0x00000000, 0x569a569a,
0x0c1b25a4, 0x66e60230, 0x061f0130, 0x27272727, 0x2b2b2b27,
0x07000700, 0x22184000, 0x08080808, 0x00000000, 0xc0083070,
0x000004d5, 0x00000000, 0xcc0000c0, 0x00000800, 0xfffffffe,
0x40302010, 0x00706050, 0x00000000, 0x00000023, 0x00000000,
0x81121313, 0x00d047c8, 0x80ff000c, 0x8c838300, 0x2e68120f,
0x9500bb78, 0x11144028, 0x00881117, 0x89140f00, 0x1a1b0000,
0x090e1317, 0x00000204, 0x00d30000, 0x101fbf00, 0x00000007,
0x48071d40, 0x03a05633, 0x000000e4, 0x6c6c6c6c, 0x08800000,
0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x69e9ac44, 0x469652cf, 0x49795994,
0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f,
0x6954341e, 0x43bc0094, 0x6954341e, 0x433c0094, 0x00000000,
0x5116848b, 0x47c00bff, 0x00000036, 0x2c7f000d
}, rtl8192cu_bb_vals1_88ru[] = {
0x018610db, 0x0000001f, 0x00b91612, 0x24000090, 0x20f60000,
0x24000090
}, rtl8192cu_bb_vals1_92cu[] = {
0x0186115b, 0x0000001f, 0x00b99612, 0x40000100, 0x20f60000,
0x40000100
}, rtl8192cu_bb_vals1_88cu_92ce[] = {
0x018610db, 0x0000001f, 0x00b91612, 0x40000100, 0x20f60000,
0x40000100
}, rtl8192cu_bb_vals2[] = {
0x20200000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f,
0x00000000, 0x00000080, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427,
0x00766932, 0x00222222, 0x00000000, 0x37644302, 0x2f97d40c,
0x00080740
}, rtl8192cu_bb_vals5_88cu[] = {
0x00000008, 0x001b25a4, 0x631b25a0, 0x631b25a0, 0x081b25a0,
0x081b25a0, 0x081b25a0, 0x081b25a0, 0x631b25a0, 0x081b25a0,
0x631b25a0, 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x001b25a0,
0x001b25a0, 0x6b1b25a0, 0x00000003, 0x00000000, 0x00000300
}, rtl8192cu_bb_vals5_88ru[] = {
0x00000010, 0x001b25a4, 0x631b25a0, 0x631b25a0, 0x081b25a0,
0x081b25a0, 0x081b25a0, 0x081b25a0, 0x631b25a0, 0x081b25a0,
0x631b25a0, 0x631b25a0, 0x631b25a0, 0x631b25a0, 0x001b25a0,
0x001b25a0, 0x6b1b25a0, 0x31555448, 0x00000003, 0x00000000,
0x00000300
};
static const struct rtwn_bb_prog rtl8192cu_bb[] = {
/* RTL8188CE / RTL8188CU. */
{
nitems(rtl8192cu_bb_regs0),
rtl8192cu_bb_regs0,
rtl8192cu_bb_vals0_88cu,
{ R92C_COND_RTL8188CU | R92C_COND_RTL8188CE },
/* RTL8188RU. */
&(const struct rtwn_bb_prog){
nitems(rtl8192cu_bb_regs0_88ru),
rtl8192cu_bb_regs0_88ru,
rtl8192cu_bb_vals0_88ru,
{ R92C_COND_RTL8188RU },
/* Others. */
&(const struct rtwn_bb_prog){
nitems(rtl8192cu_bb_regs0),
rtl8192cu_bb_regs0,
rtl8192cu_bb_vals0_92ce_92cu,
{ 0 },
NULL
}
}
},
/* RTL8188RU. */
{
nitems(rtl8192cu_bb_regs1),
rtl8192cu_bb_regs1,
rtl8192cu_bb_vals1_88ru,
{ R92C_COND_RTL8188RU },
/* RTL8192CU. */
&(const struct rtwn_bb_prog){
nitems(rtl8192cu_bb_regs1),
rtl8192cu_bb_regs1,
rtl8192cu_bb_vals1_92cu,
{ R92C_COND_RTL8192CU },
/* Others. */
&(const struct rtwn_bb_prog){
nitems(rtl8192cu_bb_regs1),
rtl8192cu_bb_regs1,
rtl8192cu_bb_vals1_88cu_92ce,
{ 0 },
NULL
}
}
},
{
nitems(rtl8192cu_bb_regs2),
rtl8192cu_bb_regs2,
rtl8192cu_bb_vals2,
{ 0 },
NULL
},
/* RTL8192CE / RTL8192CU. */
{
nitems(rtl8192c_bb_regs3),
rtl8192c_bb_regs3,
rtl8192c_bb_vals3_92ce_92cu,
{ R92C_COND_RTL8192C },
/* Others. */
&(const struct rtwn_bb_prog){
nitems(rtl8192c_bb_regs3),
rtl8192c_bb_regs3,
rtl8192c_bb_vals3_88cu_88ru,
{ 0 },
NULL
}
},
{
nitems(rtl8192c_bb_regs4),
rtl8192c_bb_regs4,
rtl8192c_bb_vals4,
{ 0 },
NULL
},
/* RTL8188CE / RTL8188CU. */
{
nitems(rtl8192c_bb_regs5),
rtl8192c_bb_regs5,
rtl8192cu_bb_vals5_88cu,
{ R92C_COND_RTL8188CU | R92C_COND_RTL8188CE },
/* RTL8188RU. */
&(const struct rtwn_bb_prog){
nitems(rtl8192cu_bb_regs5_88ru),
rtl8192cu_bb_regs5_88ru,
rtl8192cu_bb_vals5_88ru,
{ R92C_COND_RTL8188RU },
/* Others. */
&(const struct rtwn_bb_prog){
nitems(rtl8192c_bb_regs5),
rtl8192c_bb_regs5,
rtl8192c_bb_vals5_92ce_92cu,
{ 0 },
NULL
}
}
}
};
static const uint32_t rtl8188ru_agc_vals[] = {
0x7b000001, 0x7b010001, 0x7b020001, 0x7b030001, 0x7b040001,
0x7b050001, 0x7b060001, 0x7b070001, 0x7b080001, 0x7a090001,
0x790a0001, 0x780b0001, 0x770c0001, 0x760d0001, 0x750e0001,
0x740f0001, 0x73100001, 0x72110001, 0x71120001, 0x70130001,
0x6f140001, 0x6e150001, 0x6d160001, 0x6c170001, 0x6b180001,
0x6a190001, 0x691a0001, 0x681b0001, 0x671c0001, 0x661d0001,
0x651e0001, 0x641f0001, 0x63200001, 0x62210001, 0x61220001,
0x60230001, 0x46240001, 0x45250001, 0x44260001, 0x43270001,
0x42280001, 0x41290001, 0x402a0001, 0x262b0001, 0x252c0001,
0x242d0001, 0x232e0001, 0x222f0001, 0x21300001, 0x20310001,
0x06320001, 0x05330001, 0x04340001, 0x03350001, 0x02360001,
0x01370001, 0x00380001, 0x00390001, 0x003a0001, 0x003b0001,
0x003c0001, 0x003d0001, 0x003e0001, 0x003f0001, 0x7b400001,
0x7b410001, 0x7b420001, 0x7b430001, 0x7b440001, 0x7b450001,
0x7b460001, 0x7b470001, 0x7b480001, 0x7a490001, 0x794a0001,
0x784b0001, 0x774c0001, 0x764d0001, 0x754e0001, 0x744f0001,
0x73500001, 0x72510001, 0x71520001, 0x70530001, 0x6f540001,
0x6e550001, 0x6d560001, 0x6c570001, 0x6b580001, 0x6a590001,
0x695a0001, 0x685b0001, 0x675c0001, 0x665d0001, 0x655e0001,
0x645f0001, 0x63600001, 0x62610001, 0x61620001, 0x60630001,
0x46640001, 0x45650001, 0x44660001, 0x43670001, 0x42680001,
0x41690001, 0x406a0001, 0x266b0001, 0x256c0001, 0x246d0001,
0x236e0001, 0x226f0001, 0x21700001, 0x20710001, 0x06720001,
0x05730001, 0x04740001, 0x03750001, 0x02760001, 0x01770001,
0x00780001, 0x00790001, 0x007a0001, 0x007b0001, 0x007c0001,
0x007d0001, 0x007e0001, 0x007f0001, 0x3800001e, 0x3801001e,
0x3802001e, 0x3803001e, 0x3804001e, 0x3805001e, 0x3806001e,
0x3807001e, 0x3808001e, 0x3c09001e, 0x3e0a001e, 0x400b001e,
0x440c001e, 0x480d001e, 0x4c0e001e, 0x500f001e, 0x5210001e,
0x5611001e, 0x5a12001e, 0x5e13001e, 0x6014001e, 0x6015001e,
0x6016001e, 0x6217001e, 0x6218001e, 0x6219001e, 0x621a001e,
0x621b001e, 0x621c001e, 0x621d001e, 0x621e001e, 0x621f001e
};
static const struct rtwn_agc_prog rtl8188ru_agc[] = {
{
nitems(rtl8188ru_agc_vals),
rtl8188ru_agc_vals,
{ 0 },
NULL
}
};
#endif /* R92CU_PRIV_H */

View File

@ -0,0 +1,65 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92CU_REG_H
#define R92CU_REG_H
#include <dev/rtwn/rtl8192c/r92c_reg.h>
/*
* MAC registers.
*/
/* System Configuration. */
#define R92C_USB_SIE_INTF 0x0e0
/*
* USB registers.
*/
#define R92C_USB_SUSPEND 0xfe10
#define R92C_USB_INFO 0xfe17
#define R92C_USB_SPECIAL_OPTION 0xfe55
#define R92C_USB_HCPWM 0xfe57
#define R92C_USB_HRPWM 0xfe58
#define R92C_USB_DMA_AGG_TO 0xfe5b
#define R92C_USB_AGG_TO 0xfe5c
#define R92C_USB_AGG_TH 0xfe5d
#define R92C_USB_VID 0xfe60
#define R92C_USB_PID 0xfe62
#define R92C_USB_OPTIONAL 0xfe64
#define R92C_USB_EP 0xfe65
#define R92C_USB_PHY 0xfe68
#define R92C_USB_MAC_ADDR 0xfe70
#define R92C_USB_STRING 0xfe80
/* Bits for R92C_USB_SPECIAL_OPTION. */
#define R92C_USB_SPECIAL_OPTION_AGG_EN 0x08
#define R92C_USB_SPECIAL_OPTION_INT_BULK_SEL 0x10
/* Bits for R92C_USB_EP. */
#define R92C_USB_EP_HQ_M 0x000f
#define R92C_USB_EP_HQ_S 0
#define R92C_USB_EP_NQ_M 0x00f0
#define R92C_USB_EP_NQ_S 4
#define R92C_USB_EP_LQ_M 0x0f00
#define R92C_USB_EP_LQ_S 8
#endif /* R92CU_REG_H */

View File

@ -0,0 +1,65 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8192c/usb/r92cu.h>
int
r92cu_classify_intr(struct rtwn_softc *sc, void *buf, int len)
{
/* NB: reports are fetched from C2H_MSG register. */
return (RTWN_RX_DATA);
}
int
r92cu_align_rx(int totlen, int len)
{
return (roundup2(totlen, 128));
}

View File

@ -0,0 +1,66 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* Copyright (c) 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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/if_rtwn_debug.h>
#include <dev/rtwn/rtl8192c/usb/r92cu.h>
#include <dev/rtwn/rtl8192c/usb/r92cu_tx_desc.h>
void
r92cu_dump_tx_desc(struct rtwn_softc *sc, const void *desc)
{
#ifdef RTWN_DEBUG
const struct r92cu_tx_desc *txd = desc;
RTWN_DPRINTF(sc, RTWN_DEBUG_XMIT_DESC,
"%s: len %d, off %d, flags0 %02X, dw: 1 %08X, 2 %08X, 3 %04X "
"(seq %04X), 4 %08X, 5 %08X, 6 %08X, sum %04X, pad %04X\n",
__func__, le16toh(txd->pktlen), txd->offset, txd->flags0,
le32toh(txd->txdw1), le32toh(txd->txdw2), le16toh(txd->txdw3),
le16toh(txd->txdseq), le32toh(txd->txdw4), le32toh(txd->txdw5),
le32toh(txd->txdw6), le16toh(txd->txdsum), le16toh(txd->pad));
#endif
}

View File

@ -0,0 +1,45 @@
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 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.
*
* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
* $FreeBSD$
*/
#ifndef R92CU_TX_DESC_H
#define R92CU_TX_DESC_H
#include <dev/rtwn/rtl8192c/r92c_tx_desc.h>
/* Tx MAC descriptor (USB). */
struct r92cu_tx_desc {
uint16_t pktlen;
uint8_t offset;
uint8_t flags0;
uint32_t txdw1;
uint32_t txdw2;
uint16_t txdw3;
uint16_t txdseq;
uint32_t txdw4;
uint32_t txdw5;
uint32_t txdw6;
uint16_t txdsum;
uint16_t pad;
} __packed __attribute__((aligned(4)));
#endif /* R92CU_TX_DESC_H */

View File

@ -0,0 +1,140 @@
/*-
* Copyright (c) 2016 Andriy Voskoboinyk <avos@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 RTL8812A_H
#define RTL8812A_H
/*
* Global definitions.
*/
#define R12A_PUBQ_NPAGES 219
#define R12A_TXPKTBUF_COUNT 255
#define R12A_TX_PAGE_COUNT 248
#define R12A_TX_PAGE_SIZE 512
#define R12A_RX_DMA_BUFFER_SIZE 0x3e80
#define R12A_MAX_FW_SIZE 0x8000
#define R12A_MACID_MAX 127
#define R12A_CAM_ENTRY_COUNT 64
#define R12A_INTR_MSG_LEN 60
static const uint8_t r12a_chan_5ghz_0[] =
{ 36, 40, 44, 48, 52, 56, 60, 64 };
static const uint8_t r12a_chan_5ghz_1[] =
{ 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144 };
static const uint8_t r12a_chan_5ghz_2[] =
{ 149, 153, 157, 161, 165, 169, 173, 177 };
/*
* Function declarations.
*/
/* r12a_attach.c */
void r12a_vap_preattach(struct rtwn_softc *, struct ieee80211vap *);
void r12a_detach_private(struct rtwn_softc *);
/* r12a_beacon.c */
void r12a_beacon_init(struct rtwn_softc *, void *, int);
void r12a_beacon_set_rate(void *, int);
/* r12a_calib.c */
void r12a_save_bb_afe_vals(struct rtwn_softc *, uint32_t[],
const uint16_t[], int);
void r12a_restore_bb_afe_vals(struct rtwn_softc *, uint32_t[],
const uint16_t[], int);
void r12a_save_rf_vals(struct rtwn_softc *, uint32_t[],
const uint8_t[], int);
void r12a_restore_rf_vals(struct rtwn_softc *, uint32_t[],
const uint8_t[], int);
void r12a_lc_calib(struct rtwn_softc *);
#ifndef RTWN_WITHOUT_UCODE
int r12a_iq_calib_fw_supported(struct rtwn_softc *);
#endif
void r12a_iq_calib_sw(struct rtwn_softc *);
void r12a_iq_calib(struct rtwn_softc *);
/* r12a_caps.c */
int r12a_ioctl_net(struct ieee80211com *, u_long, void *);
/* r12a_chan.c */
void r12a_fix_spur(struct rtwn_softc *, struct ieee80211_channel *);
void r12a_set_chan(struct rtwn_softc *, struct ieee80211_channel *);
void r12a_set_band_2ghz(struct rtwn_softc *, uint32_t);
void r12a_set_band_5ghz(struct rtwn_softc *, uint32_t);
/* r12a_fw.c */
#ifndef RTWN_WITHOUT_UCODE
void r12a_fw_reset(struct rtwn_softc *, int);
void r12a_fw_download_enable(struct rtwn_softc *, int);
void r12a_set_media_status(struct rtwn_softc *, int);
int r12a_set_pwrmode(struct rtwn_softc *, struct ieee80211vap *,
int);
void r12a_iq_calib_fw(struct rtwn_softc *);
#endif
/* r12a_init.c */
int r12a_check_condition(struct rtwn_softc *, const uint8_t[]);
int r12a_set_page_size(struct rtwn_softc *);
void r12a_init_edca(struct rtwn_softc *);
void r12a_init_bb(struct rtwn_softc *);
void r12a_init_rf(struct rtwn_softc *);
void r12a_crystalcap_write(struct rtwn_softc *);
int r12a_power_on(struct rtwn_softc *);
void r12a_power_off(struct rtwn_softc *);
void r12a_init_intr(struct rtwn_softc *);
void r12a_init_antsel(struct rtwn_softc *);
/* r12a_led.c */
void r12a_set_led(struct rtwn_softc *, int, int);
/* r12a_rf.c */
uint32_t r12a_rf_read(struct rtwn_softc *, int, uint8_t);
uint32_t r12a_c_cut_rf_read(struct rtwn_softc *, int, uint8_t);
void r12a_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t);
/* r12a_rom.c */
void r12a_parse_rom_common(struct rtwn_softc *, uint8_t *);
void r12a_parse_rom(struct rtwn_softc *, uint8_t *);
/* r12a_rx.c */
void r12a_ratectl_tx_complete(struct rtwn_softc *, uint8_t *, int);
void r12a_handle_c2h_report(struct rtwn_softc *, uint8_t *, int);
int r12a_check_frame_checksum(struct rtwn_softc *, struct mbuf *);
uint8_t r12a_rx_radiotap_flags(const void *);
/* r12a_tx.c */
void r12a_fill_tx_desc(struct rtwn_softc *, struct ieee80211_node *,
struct mbuf *, void *, uint8_t, int);
void r12a_fill_tx_desc_raw(struct rtwn_softc *, struct ieee80211_node *,
struct mbuf *, void *, const struct ieee80211_bpf_params *);
void r12a_fill_tx_desc_null(struct rtwn_softc *, void *, int, int, int);
uint8_t r12a_tx_radiotap_flags(const void *);
#endif /* RTL8812A_H */

View File

@ -0,0 +1,96 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* Copyright (c) 2016 Andriy Voskoboinyk <avos@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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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_ridx.h>
#include <dev/rtwn/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_tx_desc.h>
void
r12a_beacon_init(struct rtwn_softc *sc, void *buf, int id)
{
struct r12a_tx_desc *txd = (struct r12a_tx_desc *)buf;
txd->flags0 = R12A_FLAGS0_LSG | R12A_FLAGS0_FSG | R12A_FLAGS0_BMCAST;
/*
* NB: there is no need to setup HWSEQ_EN bit;
* QSEL_BEACON already implies it.
*/
txd->txdw1 = htole32(SM(R12A_TXDW1_QSEL, R12A_TXDW1_QSEL_BEACON));
txd->txdw1 |= htole32(SM(R12A_TXDW1_MACID, RTWN_MACID_BC));
txd->txdw3 = htole32(R12A_TXDW3_DRVRATE);
txd->txdw3 |= htole32(SM(R12A_TXDW3_SEQ_SEL, id));
txd->txdw6 = htole32(SM(R21A_TXDW6_MBSSID, id));
}
void
r12a_beacon_set_rate(void *buf, int is5ghz)
{
struct r12a_tx_desc *txd = (struct r12a_tx_desc *)buf;
txd->txdw4 &= ~htole32(R12A_TXDW4_DATARATE_M);
if (is5ghz) {
txd->txdw4 = htole32(SM(R12A_TXDW4_DATARATE,
RTWN_RIDX_OFDM6));
} else
txd->txdw4 = htole32(SM(R12A_TXDW4_DATARATE, RTWN_RIDX_CCK1));
}

View File

@ -0,0 +1,288 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* Copyright (c) 2016 Andriy Voskoboinyk <avos@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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8812a/r12a_priv.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_var.h>
void
r12a_lc_calib(struct rtwn_softc *sc)
{
uint32_t chnlbw;
uint8_t txmode;
RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
"%s: LC calibration started\n", __func__);
txmode = rtwn_read_1(sc, R12A_SINGLETONE_CONT_TX + 2);
if ((txmode & 0x07) != 0) {
/* Disable all continuous Tx. */
/*
* Skipped because BB turns off continuous Tx until
* next packet comes in.
*/
} else {
/* Block all Tx queues. */
rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL);
}
/* Enter LCK mode. */
rtwn_rf_setbits(sc, 0, R12A_RF_LCK, 0, R12A_RF_LCK_MODE);
/* Start calibration. */
chnlbw = rtwn_rf_read(sc, 0, R92C_RF_CHNLBW);
rtwn_rf_write(sc, 0, R92C_RF_CHNLBW, chnlbw | R92C_RF_CHNLBW_LCSTART);
/* Give calibration the time to complete. */
rtwn_delay(sc, 150000); /* 150 ms */
/* Leave LCK mode. */
rtwn_rf_setbits(sc, 0, R12A_RF_LCK, R12A_RF_LCK_MODE, 0);
/* Restore configuration. */
if ((txmode & 0x07) != 0) {
/* Continuous Tx case. */
/*
* Skipped because BB turns off continuous Tx until
* next packet comes in.
*/
} else {
/* Unblock all Tx queues. */
rtwn_write_1(sc, R92C_TXPAUSE, 0);
}
/* Recover channel number. */
rtwn_rf_write(sc, 0, R92C_RF_CHNLBW, chnlbw);
RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
"%s: LC calibration finished\n", __func__);
}
#ifndef RTWN_WITHOUT_UCODE
int
r12a_iq_calib_fw_supported(struct rtwn_softc *sc)
{
if (sc->fwver == 0x19)
return (1);
return (0);
}
#endif
void
r12a_save_bb_afe_vals(struct rtwn_softc *sc, uint32_t vals[],
const uint16_t regs[], int size)
{
int i;
/* Select page C. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0x80000000, 0);
for (i = 0; i < size; i++)
vals[i] = rtwn_bb_read(sc, regs[i]);
}
void
r12a_restore_bb_afe_vals(struct rtwn_softc *sc, uint32_t vals[],
const uint16_t regs[], int size)
{
int i;
/* Select page C. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0x80000000, 0);
for (i = 0; i < size; i++)
rtwn_bb_write(sc, regs[i], vals[i]);
}
void
r12a_save_rf_vals(struct rtwn_softc *sc, uint32_t vals[],
const uint8_t regs[], int size)
{
int c, i;
/* Select page C. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0x80000000, 0);
for (c = 0; c < sc->nrxchains; c++)
for (i = 0; i < size; i++)
vals[c * size + i] = rtwn_rf_read(sc, c, regs[i]);
}
void
r12a_restore_rf_vals(struct rtwn_softc *sc, uint32_t vals[],
const uint8_t regs[], int size)
{
int c, i;
/* Select page C. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0x80000000, 0);
for (c = 0; c < sc->nrxchains; c++)
for (i = 0; i < size; i++)
rtwn_rf_write(sc, c, regs[i], vals[c * size + i]);
}
#ifdef RTWN_TODO
static void
r12a_iq_tx(struct rtwn_softc *sc)
{
/* TODO */
}
static void
r12a_iq_config_mac(struct rtwn_softc *sc)
{
/* Select page C. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0x80000000, 0);
rtwn_write_1(sc, R92C_TXPAUSE,
R92C_TX_QUEUE_AC | R92C_TX_QUEUE_MGT | R92C_TX_QUEUE_HIGH);
/* BCN_CTRL & BCN_CTRL1 */
rtwn_setbits_1(sc, R92C_BCN_CTRL(0), R92C_BCN_CTRL_EN_BCN, 0);
rtwn_setbits_1(sc, R92C_BCN_CTRL(1), R92C_BCN_CTRL_EN_BCN, 0);
/* Rx ant off */
rtwn_write_1(sc, R12A_OFDMCCK_EN, 0);
/* CCA off */
rtwn_bb_setbits(sc, R12A_CCA_ON_SEC, 0x03, 0x0c);
/* CCK RX Path off */
rtwn_write_1(sc, R12A_CCK_RX_PATH + 3, 0x0f);
}
#endif
void
r12a_iq_calib_sw(struct rtwn_softc *sc)
{
#define R12A_MAX_NRXCHAINS 2
uint32_t bb_vals[nitems(r12a_iq_bb_regs)];
uint32_t afe_vals[nitems(r12a_iq_afe_regs)];
uint32_t rf_vals[nitems(r12a_iq_rf_regs) * R12A_MAX_NRXCHAINS];
uint32_t rfe[2];
KASSERT(sc->nrxchains <= R12A_MAX_NRXCHAINS,
("nrxchains > %d (%d)\n", R12A_MAX_NRXCHAINS, sc->nrxchains));
/* Save registers. */
r12a_save_bb_afe_vals(sc, bb_vals, r12a_iq_bb_regs,
nitems(r12a_iq_bb_regs));
/* Select page C1. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0, 0x80000000);
rfe[0] = rtwn_bb_read(sc, R12A_RFE(0));
rfe[1] = rtwn_bb_read(sc, R12A_RFE(1));
r12a_save_bb_afe_vals(sc, afe_vals, r12a_iq_afe_regs,
nitems(r12a_iq_afe_regs));
r12a_save_rf_vals(sc, rf_vals, r12a_iq_rf_regs,
nitems(r12a_iq_rf_regs));
#ifdef RTWN_TODO
/* Configure MAC. */
rtwn_iq_config_mac(sc);
rtwn_iq_tx(sc);
#endif
r12a_restore_rf_vals(sc, rf_vals, r12a_iq_rf_regs,
nitems(r12a_iq_rf_regs));
r12a_restore_bb_afe_vals(sc, afe_vals, r12a_iq_afe_regs,
nitems(r12a_iq_afe_regs));
/* Select page C1. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0, 0x80000000);
/* Chain 0. */
rtwn_bb_write(sc, R12A_SLEEP_NAV(0), 0);
rtwn_bb_write(sc, R12A_PMPD(0), 0);
rtwn_bb_write(sc, 0xc88, 0);
rtwn_bb_write(sc, 0xc8c, 0x3c000000);
rtwn_bb_setbits(sc, 0xc90, 0, 0x00000080);
rtwn_bb_setbits(sc, 0xcc4, 0, 0x20040000);
rtwn_bb_setbits(sc, 0xcc8, 0, 0x20000000);
/* Chain 1. */
rtwn_bb_write(sc, R12A_SLEEP_NAV(1), 0);
rtwn_bb_write(sc, R12A_PMPD(1), 0);
rtwn_bb_write(sc, 0xe88, 0);
rtwn_bb_write(sc, 0xe8c, 0x3c000000);
rtwn_bb_setbits(sc, 0xe90, 0, 0x00000080);
rtwn_bb_setbits(sc, 0xec4, 0, 0x20040000);
rtwn_bb_setbits(sc, 0xec8, 0, 0x20000000);
rtwn_bb_write(sc, R12A_RFE(0), rfe[0]);
rtwn_bb_write(sc, R12A_RFE(1), rfe[1]);
r12a_restore_bb_afe_vals(sc, bb_vals, r12a_iq_bb_regs,
nitems(r12a_iq_bb_regs));
#undef R12A_MAX_NRXCHAINS
}
void
r12a_iq_calib(struct rtwn_softc *sc)
{
#ifndef RTWN_WITHOUT_UCODE
if ((sc->sc_flags & RTWN_FW_LOADED) &&
rtwn_r12a_iq_calib_fw_supported(sc))
r12a_iq_calib_fw(sc);
else
#endif
rtwn_r12a_iq_calib_sw(sc);
}

View File

@ -0,0 +1,122 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* Copyright (c) 2016 Andriy Voskoboinyk <avos@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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <sys/sockio.h>
#include <rtems/bsd/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/if_var.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/if_rtwn_rx.h>
#include <dev/rtwn/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_var.h>
int
r12a_ioctl_net(struct ieee80211com *ic, u_long cmd, void *data)
{
struct rtwn_softc *sc = ic->ic_softc;
struct r12a_softc *rs = sc->sc_priv;
struct ifreq *ifr = (struct ifreq *)data;
int error;
error = 0;
switch (cmd) {
case SIOCSIFCAP:
{
struct ieee80211vap *vap;
int changed, rxmask;
rxmask = ifr->ifr_reqcap & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
RTWN_LOCK(sc);
changed = 0;
if (!(rs->rs_flags & R12A_RXCKSUM_EN) ^
!(ifr->ifr_reqcap & IFCAP_RXCSUM)) {
rs->rs_flags ^= R12A_RXCKSUM_EN;
changed = 1;
}
if (!(rs->rs_flags & R12A_RXCKSUM6_EN) ^
!(ifr->ifr_reqcap & IFCAP_RXCSUM_IPV6)) {
rs->rs_flags ^= R12A_RXCKSUM6_EN;
changed = 1;
}
if (changed) {
if (rxmask == 0)
sc->rcr &= ~R12A_RCR_TCP_OFFLD_EN;
else
sc->rcr |= R12A_RCR_TCP_OFFLD_EN;
if (sc->sc_flags & RTWN_RUNNING)
rtwn_rxfilter_set(sc);
}
RTWN_UNLOCK(sc);
IEEE80211_LOCK(ic); /* XXX */
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
struct ifnet *ifp = vap->iv_ifp;
ifp->if_capenable &=
~(IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6);
ifp->if_capenable |= rxmask;
}
IEEE80211_UNLOCK(ic);
break;
}
default:
error = ENOTTY; /* for net80211 */
break;
}
return (error);
}

View File

@ -0,0 +1,603 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* Copyright (c) 2016 Andriy Voskoboinyk <avos@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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_var.h>
static void
r12a_write_txpower(struct rtwn_softc *sc, int chain,
struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
{
if (IEEE80211_IS_CHAN_2GHZ(c)) {
/* Write per-CCK rate Tx power. */
rtwn_bb_write(sc, R12A_TXAGC_CCK11_1(chain),
SM(R12A_TXAGC_CCK1, power[RTWN_RIDX_CCK1]) |
SM(R12A_TXAGC_CCK2, power[RTWN_RIDX_CCK2]) |
SM(R12A_TXAGC_CCK55, power[RTWN_RIDX_CCK55]) |
SM(R12A_TXAGC_CCK11, power[RTWN_RIDX_CCK11]));
}
/* Write per-OFDM rate Tx power. */
rtwn_bb_write(sc, R12A_TXAGC_OFDM18_6(chain),
SM(R12A_TXAGC_OFDM06, power[RTWN_RIDX_OFDM6]) |
SM(R12A_TXAGC_OFDM09, power[RTWN_RIDX_OFDM9]) |
SM(R12A_TXAGC_OFDM12, power[RTWN_RIDX_OFDM12]) |
SM(R12A_TXAGC_OFDM18, power[RTWN_RIDX_OFDM18]));
rtwn_bb_write(sc, R12A_TXAGC_OFDM54_24(chain),
SM(R12A_TXAGC_OFDM24, power[RTWN_RIDX_OFDM24]) |
SM(R12A_TXAGC_OFDM36, power[RTWN_RIDX_OFDM36]) |
SM(R12A_TXAGC_OFDM48, power[RTWN_RIDX_OFDM48]) |
SM(R12A_TXAGC_OFDM54, power[RTWN_RIDX_OFDM54]));
/* Write per-MCS Tx power. */
rtwn_bb_write(sc, R12A_TXAGC_MCS3_0(chain),
SM(R12A_TXAGC_MCS0, power[RTWN_RIDX_MCS(0)]) |
SM(R12A_TXAGC_MCS1, power[RTWN_RIDX_MCS(1)]) |
SM(R12A_TXAGC_MCS2, power[RTWN_RIDX_MCS(2)]) |
SM(R12A_TXAGC_MCS3, power[RTWN_RIDX_MCS(3)]));
rtwn_bb_write(sc, R12A_TXAGC_MCS7_4(chain),
SM(R12A_TXAGC_MCS4, power[RTWN_RIDX_MCS(4)]) |
SM(R12A_TXAGC_MCS5, power[RTWN_RIDX_MCS(5)]) |
SM(R12A_TXAGC_MCS6, power[RTWN_RIDX_MCS(6)]) |
SM(R12A_TXAGC_MCS7, power[RTWN_RIDX_MCS(7)]));
if (sc->ntxchains >= 2) {
rtwn_bb_write(sc, R12A_TXAGC_MCS11_8(chain),
SM(R12A_TXAGC_MCS8, power[RTWN_RIDX_MCS(8)]) |
SM(R12A_TXAGC_MCS9, power[RTWN_RIDX_MCS(9)]) |
SM(R12A_TXAGC_MCS10, power[RTWN_RIDX_MCS(10)]) |
SM(R12A_TXAGC_MCS11, power[RTWN_RIDX_MCS(11)]));
rtwn_bb_write(sc, R12A_TXAGC_MCS15_12(chain),
SM(R12A_TXAGC_MCS12, power[RTWN_RIDX_MCS(12)]) |
SM(R12A_TXAGC_MCS13, power[RTWN_RIDX_MCS(13)]) |
SM(R12A_TXAGC_MCS14, power[RTWN_RIDX_MCS(14)]) |
SM(R12A_TXAGC_MCS15, power[RTWN_RIDX_MCS(15)]));
}
/* TODO: VHT rates */
}
static int
r12a_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 if (IEEE80211_IS_CHAN_5GHZ(c)) {
if (chan < 36)
return (-1);
if (chan <= 42) group = 0;
else if (chan <= 48) group = 1;
else if (chan <= 58) group = 2;
else if (chan <= 64) group = 3;
else if (chan <= 106) group = 4;
else if (chan <= 114) group = 5;
else if (chan <= 122) group = 6;
else if (chan <= 130) group = 7;
else if (chan <= 138) group = 8;
else if (chan <= 144) group = 9;
else if (chan <= 155) group = 10;
else if (chan <= 161) group = 11;
else if (chan <= 171) group = 12;
else if (chan <= 177) group = 13;
else {
KASSERT(0, ("wrong 5GHz channel %d!\n", chan));
return (-1);
}
} else {
KASSERT(0, ("wrong channel band (flags %08X)\n", c->ic_flags));
return (-1);
}
return (group);
}
static void
r12a_get_txpower(struct rtwn_softc *sc, int chain,
struct ieee80211_channel *c, uint8_t power[RTWN_RIDX_COUNT])
{
struct r12a_softc *rs = sc->sc_priv;
int i, ridx, group, max_mcs;
/* Determine channel group. */
group = r12a_get_power_group(sc, c);
if (group == -1) { /* shouldn't happen */
device_printf(sc->sc_dev, "%s: incorrect channel\n", __func__);
return;
}
/* TODO: VHT rates. */
max_mcs = RTWN_RIDX_MCS(sc->ntxchains * 8 - 1);
/* XXX regulatory */
/* XXX net80211 regulatory */
if (IEEE80211_IS_CHAN_2GHZ(c)) {
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;
#ifdef notyet
if (IEEE80211_IS_CHAN_HT80(c)) {
/* Vendor driver uses HT40 values here. */
pwr_diff = rs->bw40_tx_pwr_diff_2g[chain][i];
} else
#endif
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;
}
} else { /* 5GHz */
for (ridx = RTWN_RIDX_OFDM6; ridx <= max_mcs; ridx++)
power[ridx] = rs->ht40_tx_pwr_5g[chain][group];
for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++)
power[ridx] += rs->ofdm_tx_pwr_diff_5g[chain][0];
for (i = 0; i < sc->ntxchains; i++) {
uint8_t min_mcs;
uint8_t pwr_diff;
#ifdef notyet
if (IEEE80211_IS_CHAN_HT80(c)) {
/* TODO: calculate base value. */
pwr_diff = rs->bw80_tx_pwr_diff_5g[chain][i];
} else
#endif
if (IEEE80211_IS_CHAN_HT40(c))
pwr_diff = rs->bw40_tx_pwr_diff_5g[chain][i];
else
pwr_diff = rs->bw20_tx_pwr_diff_5g[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
r12a_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. */
r12a_get_txpower(sc, i, c, power);
/* Write per-rate Tx power values to hardware. */
r12a_write_txpower(sc, i, c, power);
}
}
void
r12a_fix_spur(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
struct r12a_softc *rs = sc->sc_priv;
uint16_t chan = rtwn_chan2centieee(c);
if (rs->chip & R12A_CHIP_C_CUT) {
if (IEEE80211_IS_CHAN_HT40(c) && chan == 11) {
rtwn_bb_setbits(sc, R12A_RFMOD, 0, 0xc00);
rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK, 0, 0x40000000);
} else {
rtwn_bb_setbits(sc, R12A_RFMOD, 0x400, 0x800);
if (!IEEE80211_IS_CHAN_HT40(c) && /* 20 MHz */
(chan == 13 || chan == 14)) {
rtwn_bb_setbits(sc, R12A_RFMOD, 0, 0x300);
rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK,
0, 0x40000000);
} else { /* !80 Mhz */
rtwn_bb_setbits(sc, R12A_RFMOD, 0x100, 0x200);
rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK,
0x40000000, 0);
}
}
} else {
/* Set ADC clock to 160M to resolve 2480 MHz spur. */
if (!IEEE80211_IS_CHAN_HT40(c) && /* 20 MHz */
(chan == 13 || chan == 14))
rtwn_bb_setbits(sc, R12A_RFMOD, 0, 0x300);
else if (IEEE80211_IS_CHAN_2GHZ(c))
rtwn_bb_setbits(sc, R12A_RFMOD, 0x100, 0x200);
}
}
static void
r12a_set_band(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
struct ieee80211com *ic = &sc->sc_ic;
struct r12a_softc *rs = sc->sc_priv;
uint32_t basicrates;
uint8_t swing;
int i;
/* Check if band was changed. */
if ((sc->sc_flags & (RTWN_STARTED | RTWN_RUNNING)) !=
RTWN_STARTED && IEEE80211_IS_CHAN_5GHZ(c) ^
!(rtwn_read_1(sc, R12A_CCK_CHECK) & R12A_CCK_CHECK_5GHZ))
return;
rtwn_get_rates(sc, ieee80211_get_suprates(ic, c), NULL, &basicrates,
NULL, 1);
if (IEEE80211_IS_CHAN_2GHZ(c)) {
rtwn_r12a_set_band_2ghz(sc, basicrates);
swing = rs->tx_bbswing_2g;
} else if (IEEE80211_IS_CHAN_5GHZ(c)) {
rtwn_r12a_set_band_5ghz(sc, basicrates);
swing = rs->tx_bbswing_5g;
} else {
KASSERT(0, ("wrong channel flags %08X\n", c->ic_flags));
return;
}
/* XXX PATH_B is set by vendor driver. */
for (i = 0; i < 2; i++) {
uint16_t val = 0;
switch ((swing >> i * 2) & 0x3) {
case 0:
val = 0x200; /* 0 dB */
break;
case 1:
val = 0x16a; /* -3 dB */
break;
case 2:
val = 0x101; /* -6 dB */
break;
case 3:
val = 0xb6; /* -9 dB */
break;
}
rtwn_bb_setbits(sc, R12A_TX_SCALE(i), R12A_TX_SCALE_SWING_M,
val << R12A_TX_SCALE_SWING_S);
}
}
void
r12a_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
uint32_t val;
uint16_t chan;
int i;
r12a_set_band(sc, c);
chan = rtwn_chan2centieee(c);
if (36 <= chan && chan <= 48)
val = 0x09280000;
else if (50 <= chan && chan <= 64)
val = 0x08a60000;
else if (100 <= chan && chan <= 116)
val = 0x08a40000;
else if (118 <= chan)
val = 0x08240000;
else
val = 0x12d40000;
rtwn_bb_setbits(sc, R12A_FC_AREA, 0x1ffe0000, val);
for (i = 0; i < sc->nrxchains; i++) {
if (36 <= chan && chan <= 64)
val = 0x10100;
else if (100 <= chan && chan <= 140)
val = 0x30100;
else if (140 < chan)
val = 0x50100;
else
val = 0x00000;
rtwn_rf_setbits(sc, i, R92C_RF_CHNLBW, 0x70300, val);
/* RTL8812AU-specific */
rtwn_r12a_fix_spur(sc, c);
KASSERT(chan <= 0xff, ("%s: chan %d\n", __func__, chan));
rtwn_rf_setbits(sc, i, R92C_RF_CHNLBW, 0xff, chan);
}
#ifdef notyet
if (IEEE80211_IS_CHAN_HT80(c)) { /* 80 MHz */
rtwn_setbits_2(sc, R92C_WMAC_TRXPTCL_CTL, 0x80, 0x100);
/* TODO */
val = 0x0;
} else
#endif
if (IEEE80211_IS_CHAN_HT40(c)) { /* 40 MHz */
uint8_t ext_chan;
if (IEEE80211_IS_CHAN_HT40U(c))
ext_chan = R12A_DATA_SEC_PRIM_DOWN_20;
else
ext_chan = R12A_DATA_SEC_PRIM_UP_20;
rtwn_setbits_2(sc, R92C_WMAC_TRXPTCL_CTL, 0x100, 0x80);
rtwn_write_1(sc, R12A_DATA_SEC, ext_chan);
rtwn_bb_setbits(sc, R12A_RFMOD, 0x003003c3, 0x00300201);
rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK, 0x40000000, 0);
/* discard high 4 bits */
val = rtwn_bb_read(sc, R12A_RFMOD);
val = RW(val, R12A_RFMOD_EXT_CHAN, ext_chan);
rtwn_bb_write(sc, R12A_RFMOD, val);
val = rtwn_bb_read(sc, R12A_CCA_ON_SEC);
val = RW(val, R12A_CCA_ON_SEC_EXT_CHAN, ext_chan);
rtwn_bb_write(sc, R12A_CCA_ON_SEC, val);
if (rtwn_read_1(sc, 0x837) & 0x04)
val = 0x01800000;
else if (sc->nrxchains == 2 && sc->ntxchains == 2)
val = 0x01c00000;
else
val = 0x02000000;
rtwn_bb_setbits(sc, R12A_L1_PEAK_TH, 0x03c00000, val);
if (IEEE80211_IS_CHAN_HT40U(c))
rtwn_bb_setbits(sc, R92C_CCK0_SYSTEM, 0x10, 0);
else
rtwn_bb_setbits(sc, R92C_CCK0_SYSTEM, 0, 0x10);
val = 0x400;
} else { /* 20 MHz */
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, R12A_RFMOD, 0x003003c3, 0x00300200);
rtwn_bb_setbits(sc, R12A_ADC_BUF_CLK, 0x40000000, 0);
if (sc->nrxchains == 2 && sc->ntxchains == 2)
val = 0x01c00000;
else
val = 0x02000000;
rtwn_bb_setbits(sc, R12A_L1_PEAK_TH, 0x03c00000, val);
val = 0xc00;
}
/* RTL8812AU-specific */
rtwn_r12a_fix_spur(sc, c);
for (i = 0; i < sc->nrxchains; i++)
rtwn_rf_setbits(sc, i, R92C_RF_CHNLBW, 0xc00, val);
/* Set Tx power for this new channel. */
r12a_set_txpower(sc, c);
}
void
r12a_set_band_2ghz(struct rtwn_softc *sc, uint32_t basicrates)
{
struct r12a_softc *rs = sc->sc_priv;
/* Enable CCK / OFDM. */
rtwn_bb_setbits(sc, R12A_OFDMCCK_EN,
0, R12A_OFDMCCK_EN_CCK | R12A_OFDMCCK_EN_OFDM);
rtwn_bb_setbits(sc, R12A_BW_INDICATION, 0x02, 0x01);
rtwn_bb_setbits(sc, R12A_PWED_TH, 0x3e000, 0x2e000);
/* Select AGC table. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0x03, 0);
switch (rs->rfe_type) {
case 0:
case 1:
case 2:
rtwn_bb_write(sc, R12A_RFE_PINMUX(0), 0x77777777);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x77777777);
rtwn_bb_setbits(sc, R12A_RFE_INV(0), 0x3ff00000, 0);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0);
break;
case 3:
rtwn_bb_write(sc, R12A_RFE_PINMUX(0), 0x54337770);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x54337770);
rtwn_bb_setbits(sc, R12A_RFE_INV(0), 0x3ff00000, 0x01000000);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0x01000000);
rtwn_bb_setbits(sc, R12A_ANTSEL_SW, 0x0303, 0x01);
break;
case 4:
rtwn_bb_write(sc, R12A_RFE_PINMUX(0), 0x77777777);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x77777777);
rtwn_bb_setbits(sc, R12A_RFE_INV(0), 0x3ff00000, 0x00100000);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0x00100000);
break;
case 5:
rtwn_write_1(sc, R12A_RFE_PINMUX(0) + 2, 0x77);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x77777777);
rtwn_setbits_1(sc, R12A_RFE_INV(0) + 3, 0x01, 0);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0);
break;
default:
break;
}
rtwn_bb_setbits(sc, R12A_TX_PATH, 0xf0, 0x10);
rtwn_bb_setbits(sc, R12A_CCK_RX_PATH, 0x0f000000, 0x01000000);
/* Write basic rates. */
rtwn_set_basicrates(sc, basicrates);
rtwn_write_1(sc, R12A_CCK_CHECK, 0);
}
void
r12a_set_band_5ghz(struct rtwn_softc *sc, uint32_t basicrates)
{
struct r12a_softc *rs = sc->sc_priv;
int ntries;
rtwn_write_1(sc, R12A_CCK_CHECK, R12A_CCK_CHECK_5GHZ);
for (ntries = 0; ntries < 100; ntries++) {
if ((rtwn_read_2(sc, R12A_TXPKT_EMPTY) & 0x30) == 0x30)
break;
rtwn_delay(sc, 25);
}
if (ntries == 100) {
device_printf(sc->sc_dev,
"%s: TXPKT_EMPTY check failed (%04X)\n",
__func__, rtwn_read_2(sc, R12A_TXPKT_EMPTY));
}
/* Enable OFDM. */
rtwn_bb_setbits(sc, R12A_OFDMCCK_EN, R12A_OFDMCCK_EN_CCK,
R12A_OFDMCCK_EN_OFDM);
rtwn_bb_setbits(sc, R12A_BW_INDICATION, 0x01, 0x02);
rtwn_bb_setbits(sc, R12A_PWED_TH, 0x3e000, 0x2a000);
/* Select AGC table. */
rtwn_bb_setbits(sc, R12A_TXAGC_TABLE_SELECT, 0x03, 0x01);
switch (rs->rfe_type) {
case 0:
rtwn_bb_write(sc, R12A_RFE_PINMUX(0), 0x77337717);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x77337717);
rtwn_bb_setbits(sc, R12A_RFE_INV(0), 0x3ff00000, 0x01000000);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0x01000000);
break;
case 1:
rtwn_bb_write(sc, R12A_RFE_PINMUX(0), 0x77337717);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x77337717);
rtwn_bb_setbits(sc, R12A_RFE_INV(0), 0x3ff00000, 0);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0);
break;
case 2:
case 4:
rtwn_bb_write(sc, R12A_RFE_PINMUX(0), 0x77337777);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x77337777);
rtwn_bb_setbits(sc, R12A_RFE_INV(0), 0x3ff00000, 0x01000000);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0x01000000);
break;
case 3:
rtwn_bb_write(sc, R12A_RFE_PINMUX(0), 0x54337717);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x54337717);
rtwn_bb_setbits(sc, R12A_RFE_INV(0), 0x3ff00000, 0x01000000);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0x01000000);
rtwn_bb_setbits(sc, R12A_ANTSEL_SW, 0x0303, 0x01);
break;
case 5:
rtwn_write_1(sc, R12A_RFE_PINMUX(0) + 2, 0x33);
rtwn_bb_write(sc, R12A_RFE_PINMUX(1), 0x77337777);
rtwn_setbits_1(sc, R12A_RFE_INV(0) + 3, 0, 0x01);
rtwn_bb_setbits(sc, R12A_RFE_INV(1), 0x3ff00000, 0x01000000);
break;
default:
break;
}
rtwn_bb_setbits(sc, R12A_TX_PATH, 0xf0, 0);
rtwn_bb_setbits(sc, R12A_CCK_RX_PATH, 0, 0x0f000000);
/* Write basic rates. */
rtwn_set_basicrates(sc, basicrates);
}

View File

@ -0,0 +1,196 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* Copyright (c) 2016 Andriy Voskoboinyk <avos@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 <rtems/bsd/local/opt_wlan.h>
#include <rtems/bsd/sys/param.h>
#include <rtems/bsd/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/rtl8812a/r12a.h>
#include <dev/rtwn/rtl8812a/r12a_reg.h>
#include <dev/rtwn/rtl8812a/r12a_var.h>
#include <dev/rtwn/rtl8812a/r12a_fw_cmd.h>
#ifndef RTWN_WITHOUT_UCODE
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 + 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 + 1, 0, 0x08);
rtwn_setbits_1_shift(sc, R92C_SYS_FUNC_EN,
0, R92C_SYS_FUNC_EN_CPUEN, 1);
}
void
r12a_fw_download_enable(struct rtwn_softc *sc, int enable)
{
if (enable) {
/* MCU firmware download enable. */
rtwn_setbits_1(sc, R92C_MCUFWDL, 0, R92C_MCUFWDL_EN);
/* 8051 reset. */
rtwn_setbits_1_shift(sc, R92C_MCUFWDL, R92C_MCUFWDL_ROM_DLEN,
0, 2);
} else {
/* MCU download disable. */
rtwn_setbits_1(sc, R92C_MCUFWDL, R92C_MCUFWDL_EN, 0);
}
}
void
r12a_set_media_status(struct rtwn_softc *sc, int macid)
{
struct r12a_fw_cmd_msrrpt status;
int error;
if (macid & RTWN_MACID_VALID)
status.msrb0 = R12A_MSRRPT_B0_ASSOC;
else
status.msrb0 = R12A_MSRRPT_B0_DISASSOC;
status.macid = (macid & ~RTWN_MACID_VALID);
status.macid_end = 0;
error = r88e_fw_cmd(sc, R12A_CMD_MSR_RPT, &status, sizeof(status));
if (error != 0)
device_printf(sc->sc_dev, "cannot change media status!\n");
}
int
r12a_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 = R12A_PWRMODE_B5_NO_BTCOEX;
error = r88e_fw_cmd(sc, R12A_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);
}
void
r12a_iq_calib_fw(struct rtwn_softc *sc)
{
struct r12a_softc *rs = sc->sc_priv;
struct ieee80211_channel *c = sc->sc_ic.ic_curchan;
struct r12a_fw_cmd_iq_calib cmd;
if (rs->rs_flags & R12A_IQK_RUNNING)
return;
RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB, "Starting IQ calibration (FW)\n");
cmd.chan = rtwn_chan2centieee(c);
if (IEEE80211_IS_CHAN_5GHZ(c))
cmd.band_bw = RTWN_CMD_IQ_BAND_5GHZ;
else
cmd.band_bw = RTWN_CMD_IQ_BAND_2GHZ;
/* TODO: 80/160 MHz. */
if (IEEE80211_IS_CHAN_HT40(c))
cmd.band_bw |= RTWN_CMD_IQ_CHAN_WIDTH_40;
else
cmd.band_bw |= RTWN_CMD_IQ_CHAN_WIDTH_20;
cmd.ext_5g_pa_lna = RTWN_CMD_IQ_EXT_PA_5G(rs->ext_pa_5g);
cmd.ext_5g_pa_lna |= RTWN_CMD_IQ_EXT_LNA_5G(rs->ext_lna_5g);
if (r88e_fw_cmd(sc, R12A_CMD_IQ_CALIBRATE, &cmd, sizeof(cmd)) != 0) {
RTWN_DPRINTF(sc, RTWN_DEBUG_CALIB,
"error while sending IQ calibration command to FW!\n");
return;
}
rs->rs_flags |= R12A_IQK_RUNNING;
}
#endif

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