示例#1
0
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);
}
示例#2
0
void
r21a_parse_rom(struct rtwn_softc *sc, uint8_t *buf)
{
	struct r12a_softc *rs = sc->sc_priv;
	struct r12a_rom *rom = (struct r12a_rom *)buf;
	uint8_t pa_type, lna_type_2g, lna_type_5g;

	/* Read PA/LNA types. */
	pa_type = RTWN_GET_ROM_VAR(rom->pa_type, 0);
	lna_type_2g = RTWN_GET_ROM_VAR(rom->lna_type_2g, 0);
	lna_type_5g = RTWN_GET_ROM_VAR(rom->lna_type_5g, 0);

	rs->ext_pa_2g = R21A_ROM_IS_PA_EXT_2GHZ(pa_type);
	rs->ext_pa_5g = R21A_ROM_IS_PA_EXT_5GHZ(pa_type);
	rs->ext_lna_2g = R21A_ROM_IS_LNA_EXT(lna_type_2g);
	rs->ext_lna_5g = R21A_ROM_IS_LNA_EXT(lna_type_5g);

	RTWN_LOCK(sc);
	rs->bt_coex =
	    !!(rtwn_read_4(sc, R92C_MULTI_FUNC_CTRL) & R92C_MULTI_BT_FUNC_EN);
	RTWN_UNLOCK(sc);
	rs->bt_ant_num = (rom->rf_bt_opt & R12A_RF_BT_OPT_ANT_NUM);

	/* Read MAC address. */
	IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr_21a);

	/* Execute common part of initialization. */
	r12a_parse_rom_common(sc, buf);
}
示例#3
0
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);
}
示例#4
0
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);
}
示例#5
0
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);
}
示例#6
0
void
r12a_vap_preattach(struct rtwn_softc *sc, struct ieee80211vap *vap)
{
	struct r12a_softc *rs = sc->sc_priv;
	struct ifnet *ifp = vap->iv_ifp;

	ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6;
	RTWN_LOCK(sc);
	if (rs->rs_flags & R12A_RXCKSUM_EN)
		ifp->if_capenable |= IFCAP_RXCSUM;
	if (rs->rs_flags & R12A_RXCKSUM6_EN)
		ifp->if_capenable |= IFCAP_RXCSUM_IPV6;
	RTWN_UNLOCK(sc);
}
示例#7
0
static void
rtwn_usb_abort_xfers(struct rtwn_softc *sc)
{
	struct rtwn_usb_softc *uc = RTWN_USB_SOFTC(sc);
	int i;

	RTWN_ASSERT_LOCKED(sc);

	/* abort any pending transfers */
	RTWN_UNLOCK(sc);
	for (i = 0; i < RTWN_N_TRANSFER; i++)
		usbd_transfer_drain(uc->uc_xfer[i]);
	RTWN_LOCK(sc);
}
示例#8
0
void
rtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
	struct rtwn_usb_softc *uc = usbd_xfer_softc(xfer);
	struct rtwn_softc *sc = &uc->uc_sc;
	struct ieee80211com *ic = &sc->sc_ic;
	struct ieee80211_node *ni;
	struct mbuf *m = NULL, *next;
	struct rtwn_data *data;
	int8_t nf, rssi;

	RTWN_ASSERT_LOCKED(sc);

	switch (USB_GET_STATE(xfer)) {
	case USB_ST_TRANSFERRED:
		data = STAILQ_FIRST(&uc->uc_rx_active);
		if (data == NULL)
			goto tr_setup;
		STAILQ_REMOVE_HEAD(&uc->uc_rx_active, next);
		m = rtwn_report_intr(uc, xfer, data);
		STAILQ_INSERT_TAIL(&uc->uc_rx_inactive, data, next);
		/* FALLTHROUGH */
	case USB_ST_SETUP:
tr_setup:
		data = STAILQ_FIRST(&uc->uc_rx_inactive);
		if (data == NULL) {
			KASSERT(m == NULL, ("mbuf isn't NULL"));
			goto finish;
		}
		STAILQ_REMOVE_HEAD(&uc->uc_rx_inactive, next);
		STAILQ_INSERT_TAIL(&uc->uc_rx_active, data, next);
		usbd_xfer_set_frame_data(xfer, 0, data->buf,
		    usbd_xfer_max_len(xfer));
		usbd_transfer_submit(xfer);

		/*
		 * To avoid LOR we should unlock our private mutex here to call
		 * ieee80211_input() because here is at the end of a USB
		 * callback and safe to unlock.
		 */
		while (m != NULL) {
			next = m->m_next;
			m->m_next = NULL;

			ni = rtwn_rx_frame(sc, m, &rssi);

			RTWN_UNLOCK(sc);

			nf = RTWN_NOISE_FLOOR;
			if (ni != NULL) {
				if (ni->ni_flags & IEEE80211_NODE_HT)
					m->m_flags |= M_AMPDU;
				(void)ieee80211_input(ni, m, rssi - nf, nf);
				ieee80211_free_node(ni);
			} else {
				(void)ieee80211_input_all(ic, m,
				    rssi - nf, nf);
			}
			RTWN_LOCK(sc);
			m = next;
		}
		break;
	default:
		/* needs it to the inactive queue due to a error. */
		data = STAILQ_FIRST(&uc->uc_rx_active);
		if (data != NULL) {
			STAILQ_REMOVE_HEAD(&uc->uc_rx_active, next);
			STAILQ_INSERT_TAIL(&uc->uc_rx_inactive, data, next);
		}
		if (error != USB_ERR_CANCELLED) {
			usbd_xfer_set_stall(xfer);
			counter_u64_add(ic->ic_ierrors, 1);
			goto tr_setup;
		}
		break;
	}
finish:
	/* 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

	/* Kick-start more transmit in case we stalled */
	rtwn_start(sc);
}