rtwn: add HOSTAP / IBSS mode support for RTL8188CE.
NOTE: some multi-vap configurations (e.g., STA+IBSS) are not stable; that will be fixed later. Tested with: - RTL8188CE, STA + AP mode; - RTL8188CE, IBSS mode; - RTL8188CUS, IBSS mode; - RTL8188EU, IBSS mode. Relnotes: yes
This commit is contained in:
parent
fafbeccf90
commit
d067ef0f0d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=308389
@ -628,10 +628,10 @@ rtwn_vap_delete(struct ieee80211vap *vap)
|
|||||||
ieee80211_draintask(ic, &ic->ic_parent_task);
|
ieee80211_draintask(ic, &ic->ic_parent_task);
|
||||||
|
|
||||||
RTWN_LOCK(sc);
|
RTWN_LOCK(sc);
|
||||||
if (uvp->bcn_mbuf != NULL)
|
|
||||||
m_freem(uvp->bcn_mbuf);
|
|
||||||
/* Cancel any unfinished Tx. */
|
/* Cancel any unfinished Tx. */
|
||||||
rtwn_reset_lists(sc, vap);
|
rtwn_reset_lists(sc, vap);
|
||||||
|
if (uvp->bcn_mbuf != NULL)
|
||||||
|
m_freem(uvp->bcn_mbuf);
|
||||||
rtwn_vap_decrement_counters(sc, vap->iv_opmode, uvp->id);
|
rtwn_vap_decrement_counters(sc, vap->iv_opmode, uvp->id);
|
||||||
rtwn_set_ic_opmode(sc);
|
rtwn_set_ic_opmode(sc);
|
||||||
if (sc->sc_flags & RTWN_RUNNING)
|
if (sc->sc_flags & RTWN_RUNNING)
|
||||||
@ -822,8 +822,10 @@ rtwn_push_nulldata(struct rtwn_softc *sc, struct ieee80211vap *vap)
|
|||||||
rtwn_setbits_1_shift(sc, R92C_FWHW_TXQ_CTRL,
|
rtwn_setbits_1_shift(sc, R92C_FWHW_TXQ_CTRL,
|
||||||
R92C_FWHW_TXQ_CTRL_REAL_BEACON, 0, 2);
|
R92C_FWHW_TXQ_CTRL_REAL_BEACON, 0, 2);
|
||||||
|
|
||||||
if (uvp->bcn_mbuf != NULL)
|
if (uvp->bcn_mbuf != NULL) {
|
||||||
|
rtwn_beacon_unload(sc, uvp->id);
|
||||||
m_freem(uvp->bcn_mbuf);
|
m_freem(uvp->bcn_mbuf);
|
||||||
|
}
|
||||||
|
|
||||||
m->m_pkthdr.len = m->m_len = required_size - sc->txdesc_len;
|
m->m_pkthdr.len = m->m_len = required_size - sc->txdesc_len;
|
||||||
uvp->bcn_mbuf = m;
|
uvp->bcn_mbuf = m;
|
||||||
@ -1268,6 +1270,9 @@ rtwn_run(struct rtwn_softc *sc, struct ieee80211vap *vap)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Enable TSF synchronization. */
|
||||||
|
rtwn_tsf_sync_enable(sc, vap);
|
||||||
|
|
||||||
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
|
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
|
||||||
vap->iv_opmode == IEEE80211_M_IBSS) {
|
vap->iv_opmode == IEEE80211_M_IBSS) {
|
||||||
error = rtwn_setup_beacon(sc, ni);
|
error = rtwn_setup_beacon(sc, ni);
|
||||||
@ -1282,9 +1287,6 @@ rtwn_run(struct rtwn_softc *sc, struct ieee80211vap *vap)
|
|||||||
/* Set ACK preamble type. */
|
/* Set ACK preamble type. */
|
||||||
rtwn_set_ack_preamble(sc);
|
rtwn_set_ack_preamble(sc);
|
||||||
|
|
||||||
/* Enable TSF synchronization. */
|
|
||||||
rtwn_tsf_sync_enable(sc, vap);
|
|
||||||
|
|
||||||
/* Set basic rates mask. */
|
/* Set basic rates mask. */
|
||||||
rtwn_calc_basicrates(sc);
|
rtwn_calc_basicrates(sc);
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ rtwn_reset_beacon_valid(struct rtwn_softc *sc, int id)
|
|||||||
|
|
||||||
KASSERT (id == 0 || id == 1, ("wrong port id %d\n", 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],
|
rtwn_setbits_1_shift(sc, sc->bcn_status_reg[id],
|
||||||
R92C_TDECTRL_BCN_VALID, 0, 2);
|
R92C_TDECTRL_BCN_VALID, 0, 2);
|
||||||
|
|
||||||
@ -79,7 +80,7 @@ rtwn_check_beacon_valid(struct rtwn_softc *sc, int id)
|
|||||||
__func__, id);
|
__func__, id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rtwn_delay(sc, 100);
|
rtwn_delay(sc, sc->bcn_check_interval);
|
||||||
}
|
}
|
||||||
if (ntries == 10)
|
if (ntries == 10)
|
||||||
return (ETIMEDOUT);
|
return (ETIMEDOUT);
|
||||||
@ -123,8 +124,10 @@ rtwn_setup_beacon(struct rtwn_softc *sc, struct ieee80211_node *ni)
|
|||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uvp->bcn_mbuf != NULL)
|
if (uvp->bcn_mbuf != NULL) {
|
||||||
|
rtwn_beacon_unload(sc, uvp->id);
|
||||||
m_freem(uvp->bcn_mbuf);
|
m_freem(uvp->bcn_mbuf);
|
||||||
|
}
|
||||||
|
|
||||||
uvp->bcn_mbuf = m;
|
uvp->bcn_mbuf = m;
|
||||||
|
|
||||||
@ -173,6 +176,7 @@ rtwn_update_beacon(struct ieee80211vap *vap, int item)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rtwn_beacon_update_begin(sc, vap);
|
||||||
RTWN_UNLOCK(sc);
|
RTWN_UNLOCK(sc);
|
||||||
|
|
||||||
if (item == IEEE80211_BEACON_TIM)
|
if (item == IEEE80211_BEACON_TIM)
|
||||||
@ -183,6 +187,7 @@ rtwn_update_beacon(struct ieee80211vap *vap, int item)
|
|||||||
|
|
||||||
RTWN_LOCK(sc);
|
RTWN_LOCK(sc);
|
||||||
rtwn_tx_beacon(sc, uvp);
|
rtwn_tx_beacon(sc, uvp);
|
||||||
|
rtwn_beacon_update_end(sc, vap);
|
||||||
RTWN_UNLOCK(sc);
|
RTWN_UNLOCK(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,6 +277,14 @@ struct rtwn_softc {
|
|||||||
uint16_t (*sc_get_qmap)(struct rtwn_softc *);
|
uint16_t (*sc_get_qmap)(struct rtwn_softc *);
|
||||||
void (*sc_set_desc_addr)(struct rtwn_softc *);
|
void (*sc_set_desc_addr)(struct rtwn_softc *);
|
||||||
void (*sc_drop_incorrect_tx)(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. */
|
/* Device-specific. */
|
||||||
uint32_t (*sc_rf_read)(struct rtwn_softc *, int, uint8_t);
|
uint32_t (*sc_rf_read)(struct rtwn_softc *, int, uint8_t);
|
||||||
@ -445,6 +453,12 @@ void rtwn_suspend(struct rtwn_softc *);
|
|||||||
(((_sc)->sc_set_desc_addr)((_sc)))
|
(((_sc)->sc_set_desc_addr)((_sc)))
|
||||||
#define rtwn_drop_incorrect_tx(_sc) \
|
#define rtwn_drop_incorrect_tx(_sc) \
|
||||||
(((_sc)->sc_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. */
|
/* Aliases. */
|
||||||
#define rtwn_bb_write rtwn_write_4
|
#define rtwn_bb_write rtwn_write_4
|
||||||
|
@ -87,6 +87,10 @@ static int rtwn_pci_fw_write_block(struct rtwn_softc *,
|
|||||||
const uint8_t *, uint16_t, int);
|
const uint8_t *, uint16_t, int);
|
||||||
static uint16_t rtwn_pci_get_qmap(struct rtwn_softc *);
|
static uint16_t rtwn_pci_get_qmap(struct rtwn_softc *);
|
||||||
static void rtwn_pci_set_desc_addr(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 void rtwn_pci_attach_methods(struct rtwn_softc *);
|
||||||
|
|
||||||
|
|
||||||
@ -538,6 +542,27 @@ rtwn_pci_set_desc_addr(struct rtwn_softc *sc)
|
|||||||
rtwn_pci_write_4(sc, R92C_RX_DESA, pc->rx_ring.paddr);
|
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
|
static void
|
||||||
rtwn_pci_attach_methods(struct rtwn_softc *sc)
|
rtwn_pci_attach_methods(struct rtwn_softc *sc)
|
||||||
{
|
{
|
||||||
@ -555,6 +580,11 @@ rtwn_pci_attach_methods(struct rtwn_softc *sc)
|
|||||||
sc->sc_get_qmap = rtwn_pci_get_qmap;
|
sc->sc_get_qmap = rtwn_pci_get_qmap;
|
||||||
sc->sc_set_desc_addr = rtwn_pci_set_desc_addr;
|
sc->sc_set_desc_addr = rtwn_pci_set_desc_addr;
|
||||||
sc->sc_drop_incorrect_tx = rtwn_nop_softc;
|
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
|
static int
|
||||||
|
@ -59,8 +59,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rtwn_pci_tx_start_common(struct rtwn_softc *sc, struct ieee80211_node *ni,
|
rtwn_pci_tx_start_frame(struct rtwn_softc *sc, struct ieee80211_node *ni,
|
||||||
struct mbuf *m, uint8_t *tx_desc, uint8_t type, int id)
|
struct mbuf *m, uint8_t *tx_desc, uint8_t type)
|
||||||
{
|
{
|
||||||
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
|
struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
|
||||||
struct rtwn_tx_ring *ring;
|
struct rtwn_tx_ring *ring;
|
||||||
@ -75,16 +75,13 @@ rtwn_pci_tx_start_common(struct rtwn_softc *sc, struct ieee80211_node *ni,
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case IEEE80211_FC0_TYPE_CTL:
|
case IEEE80211_FC0_TYPE_CTL:
|
||||||
case IEEE80211_FC0_TYPE_MGT:
|
case IEEE80211_FC0_TYPE_MGT:
|
||||||
qid = RTWN_PCI_VO_QUEUE;
|
qid = RTWN_PCI_MGNT_QUEUE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qid = M_WME_GETAC(m);
|
qid = M_WME_GETAC(m);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ni == NULL) /* beacon frame */
|
|
||||||
qid = RTWN_PCI_BEACON_QUEUE;
|
|
||||||
|
|
||||||
ring = &pc->tx_ring[qid];
|
ring = &pc->tx_ring[qid];
|
||||||
data = &ring->tx_data[ring->cur];
|
data = &ring->tx_data[ring->cur];
|
||||||
if (data->m != NULL) {
|
if (data->m != NULL) {
|
||||||
@ -151,19 +148,16 @@ rtwn_pci_tx_start_common(struct rtwn_softc *sc, struct ieee80211_node *ni,
|
|||||||
|
|
||||||
data->m = m;
|
data->m = m;
|
||||||
data->ni = ni;
|
data->ni = ni;
|
||||||
data->id = id;
|
|
||||||
|
|
||||||
ring->cur = (ring->cur + 1) % RTWN_PCI_TX_LIST_COUNT;
|
ring->cur = (ring->cur + 1) % RTWN_PCI_TX_LIST_COUNT;
|
||||||
|
|
||||||
if (qid != RTWN_PCI_BEACON_QUEUE) {
|
ring->queued++;
|
||||||
ring->queued++;
|
if (ring->queued >= (RTWN_PCI_TX_LIST_COUNT - 1))
|
||||||
if (ring->queued >= (RTWN_PCI_TX_LIST_COUNT - 1))
|
sc->qfullmsk |= (1 << qid);
|
||||||
sc->qfullmsk |= (1 << qid);
|
|
||||||
|
|
||||||
#ifndef D4054
|
#ifndef D4054
|
||||||
sc->sc_tx_timer = 5;
|
sc->sc_tx_timer = 5;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
/* Kick TX. */
|
/* Kick TX. */
|
||||||
rtwn_write_2(sc, R92C_PCIE_CTRL_REG, (1 << qid));
|
rtwn_write_2(sc, R92C_PCIE_CTRL_REG, (1 << qid));
|
||||||
@ -171,25 +165,77 @@ rtwn_pci_tx_start_common(struct rtwn_softc *sc, struct ieee80211_node *ni,
|
|||||||
return (0);
|
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
|
int
|
||||||
rtwn_pci_tx_start(struct rtwn_softc *sc, struct ieee80211_node *ni,
|
rtwn_pci_tx_start(struct rtwn_softc *sc, struct ieee80211_node *ni,
|
||||||
struct mbuf *m, uint8_t *tx_desc, uint8_t type, int id)
|
struct mbuf *m, uint8_t *tx_desc, uint8_t type, int id)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
if (ni == NULL) { /* beacon frame */
|
RTWN_ASSERT_LOCKED(sc);
|
||||||
m = m_dup(m, M_NOWAIT);
|
|
||||||
if (__predict_false(m == NULL)) {
|
|
||||||
device_printf(sc->sc_dev,
|
|
||||||
"%s: could not copy beacon frame\n", __func__);
|
|
||||||
return (ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = rtwn_pci_tx_start_common(sc, ni, m, tx_desc, type, id);
|
if (ni == NULL) /* beacon frame */
|
||||||
if (error != 0)
|
error = rtwn_pci_tx_start_beacon(sc, m, tx_desc, id);
|
||||||
m_freem(m);
|
else
|
||||||
} else
|
error = rtwn_pci_tx_start_frame(sc, ni, m, tx_desc, type);
|
||||||
error = rtwn_pci_tx_start_common(sc, ni, m, tx_desc, type, id);
|
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ struct rtwn_tx_data {
|
|||||||
bus_dmamap_t map;
|
bus_dmamap_t map;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
struct ieee80211_node *ni;
|
struct ieee80211_node *ni;
|
||||||
uint8_t id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rtwn_tx_ring {
|
struct rtwn_tx_ring {
|
||||||
|
@ -141,9 +141,7 @@ r92ce_adj_devcaps(struct rtwn_softc *sc)
|
|||||||
/* XXX TODO: test everything that removed here before enabling. */
|
/* XXX TODO: test everything that removed here before enabling. */
|
||||||
/* XX do NOT enable PMGT until RSVD_PAGE command will not be fixed. */
|
/* XX do NOT enable PMGT until RSVD_PAGE command will not be fixed. */
|
||||||
ic->ic_caps &= ~(
|
ic->ic_caps &= ~(
|
||||||
IEEE80211_C_IBSS /* check beaconing / tsf */
|
IEEE80211_C_PMGT /* check null frame / device usability */
|
||||||
| IEEE80211_C_HOSTAP /* the same */
|
|
||||||
| IEEE80211_C_PMGT /* check null frame / device usability */
|
|
||||||
| IEEE80211_C_SWAMSDUTX
|
| IEEE80211_C_SWAMSDUTX
|
||||||
| IEEE80211_C_FF
|
| IEEE80211_C_FF
|
||||||
);
|
);
|
||||||
@ -256,6 +254,12 @@ r92ce_attach(struct rtwn_pci_softc *pc)
|
|||||||
sc->temp_delta = R92C_CALIB_THRESHOLD;
|
sc->temp_delta = R92C_CALIB_THRESHOLD;
|
||||||
|
|
||||||
sc->bcn_status_reg[0] = R92C_TDECTRL;
|
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->bcn_status_reg[1] = R92C_TDECTRL;
|
||||||
sc->rcr = 0;
|
sc->rcr = 0;
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ r92c_beacon_init(struct rtwn_softc *sc, void *buf, int id)
|
|||||||
rtwn_r92c_tx_setup_macid(sc, buf, id);
|
rtwn_r92c_tx_setup_macid(sc, buf, id);
|
||||||
txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
|
txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
|
||||||
txd->txdw4 |= htole32(SM(R92C_TXDW4_SEQ_SEL, id));
|
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));
|
txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, RTWN_RIDX_CCK1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ static void rtwn_usb_start_xfers(struct rtwn_softc *);
|
|||||||
static void rtwn_usb_abort_xfers(struct rtwn_softc *);
|
static void rtwn_usb_abort_xfers(struct rtwn_softc *);
|
||||||
static int rtwn_usb_fw_write_block(struct rtwn_softc *,
|
static int rtwn_usb_fw_write_block(struct rtwn_softc *,
|
||||||
const uint8_t *, uint16_t, int);
|
const uint8_t *, uint16_t, int);
|
||||||
|
static void rtwn_usb_drop_incorrect_tx(struct rtwn_softc *);
|
||||||
static void rtwn_usb_attach_methods(struct rtwn_softc *);
|
static void rtwn_usb_attach_methods(struct rtwn_softc *);
|
||||||
|
|
||||||
#define RTWN_CONFIG_INDEX 0
|
#define RTWN_CONFIG_INDEX 0
|
||||||
@ -318,6 +319,11 @@ rtwn_usb_attach_methods(struct rtwn_softc *sc)
|
|||||||
sc->sc_get_qmap = rtwn_usb_get_qmap;
|
sc->sc_get_qmap = rtwn_usb_get_qmap;
|
||||||
sc->sc_set_desc_addr = rtwn_nop_softc;
|
sc->sc_set_desc_addr = rtwn_nop_softc;
|
||||||
sc->sc_drop_incorrect_tx = rtwn_usb_drop_incorrect_tx;
|
sc->sc_drop_incorrect_tx = rtwn_usb_drop_incorrect_tx;
|
||||||
|
sc->sc_beacon_update_begin = rtwn_nop_softc_vap;
|
||||||
|
sc->sc_beacon_update_end = rtwn_nop_softc_vap;
|
||||||
|
sc->sc_beacon_unload = rtwn_nop_softc_int;
|
||||||
|
|
||||||
|
sc->bcn_check_interval = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user