Exemplo n.º 1
0
static void
ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
	const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf)
{
#define	CHAN_HT20	htole32(IEEE80211_CHAN_HT20)
#define	CHAN_HT40U	htole32(IEEE80211_CHAN_HT40U)
#define	CHAN_HT40D	htole32(IEEE80211_CHAN_HT40D)
#define	CHAN_HT		(CHAN_HT20|CHAN_HT40U|CHAN_HT40D)
	struct ath_softc *sc = ifp->if_softc;
	const HAL_RATE_TABLE *rt;
	uint8_t rix;

	rt = sc->sc_currates;
	KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
	rix = rt->rateCodeToIndex[rs->rs_rate];
	sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate;
	sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags;
#ifdef AH_SUPPORT_AR5416
	sc->sc_rx_th.wr_chan_flags &= ~CHAN_HT;
	if (rs->rs_status & HAL_RXERR_PHY) {
		/*
		 * PHY error - make sure the channel flags
		 * reflect the actual channel configuration,
		 * not the received frame.
		 */
		if (IEEE80211_IS_CHAN_HT40U(sc->sc_curchan))
			sc->sc_rx_th.wr_chan_flags |= CHAN_HT40U;
		else if (IEEE80211_IS_CHAN_HT40D(sc->sc_curchan))
			sc->sc_rx_th.wr_chan_flags |= CHAN_HT40D;
		else if (IEEE80211_IS_CHAN_HT20(sc->sc_curchan))
			sc->sc_rx_th.wr_chan_flags |= CHAN_HT20;
	} else if (sc->sc_rx_th.wr_rate & IEEE80211_RATE_MCS) {	/* HT rate */
		struct ieee80211com *ic = ifp->if_l2com;

		if ((rs->rs_flags & HAL_RX_2040) == 0)
			sc->sc_rx_th.wr_chan_flags |= CHAN_HT20;
		else if (IEEE80211_IS_CHAN_HT40U(ic->ic_curchan))
			sc->sc_rx_th.wr_chan_flags |= CHAN_HT40U;
		else
			sc->sc_rx_th.wr_chan_flags |= CHAN_HT40D;
		if ((rs->rs_flags & HAL_RX_GI) == 0)
			sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
	}

#endif
	sc->sc_rx_th.wr_tsf = htole64(ath_extend_tsf(sc, rs->rs_tstamp, tsf));
	if (rs->rs_status & HAL_RXERR_CRC)
		sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
	/* XXX propagate other error flags from descriptor */
	sc->sc_rx_th.wr_antnoise = nf;
	sc->sc_rx_th.wr_antsignal = nf + rs->rs_rssi;
	sc->sc_rx_th.wr_antenna = rs->rs_antenna;
#undef CHAN_HT
#undef CHAN_HT20
#undef CHAN_HT40U
#undef CHAN_HT40D
}
Exemplo n.º 2
0
static int
r12a_get_primary_channel(struct rtwn_softc *sc, struct ieee80211_channel *c)
{
	/* XXX 80 MHz */
	if (IEEE80211_IS_CHAN_HT40U(c))
		return (R12A_TXDW5_PRIM_CHAN_20_80_2);
	else
		return (R12A_TXDW5_PRIM_CHAN_20_80_3);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
/*
 * Fill in 802.11 available channel set, mark
 * all available channels as active, and pick
 * a default channel if not already specified.
 */
static void
ieee80211_chan_init(struct ieee80211com *ic)
{
#define	DEFAULTRATES(m, def) do { \
	if (ic->ic_sup_rates[m].rs_nrates == 0) \
		ic->ic_sup_rates[m] = def; \
} while (0)
	struct ieee80211_channel *c;
	int i;

	KASSERT(0 < ic->ic_nchans && ic->ic_nchans <= IEEE80211_CHAN_MAX,
		("invalid number of channels specified: %u", ic->ic_nchans));
	memset(ic->ic_chan_avail, 0, sizeof(ic->ic_chan_avail));
	memset(ic->ic_modecaps, 0, sizeof(ic->ic_modecaps));
	setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
	for (i = 0; i < ic->ic_nchans; i++) {
		c = &ic->ic_channels[i];
		KASSERT(c->ic_flags != 0, ("channel with no flags"));
		/*
		 * Help drivers that work only with frequencies by filling
		 * in IEEE channel #'s if not already calculated.  Note this
		 * mimics similar work done in ieee80211_setregdomain when
		 * changing regulatory state.
		 */
		if (c->ic_ieee == 0)
			c->ic_ieee = ieee80211_mhz2ieee(c->ic_freq,c->ic_flags);
		if (IEEE80211_IS_CHAN_HT40(c) && c->ic_extieee == 0)
			c->ic_extieee = ieee80211_mhz2ieee(c->ic_freq +
			    (IEEE80211_IS_CHAN_HT40U(c) ? 20 : -20),
			    c->ic_flags);
		/* default max tx power to max regulatory */
		if (c->ic_maxpower == 0)
			c->ic_maxpower = 2*c->ic_maxregpower;
		setbit(ic->ic_chan_avail, c->ic_ieee);
		/*
		 * Identify mode capabilities.
		 */
		if (IEEE80211_IS_CHAN_A(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_11A);
		if (IEEE80211_IS_CHAN_B(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_11B);
		if (IEEE80211_IS_CHAN_ANYG(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_11G);
		if (IEEE80211_IS_CHAN_FHSS(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_FH);
		if (IEEE80211_IS_CHAN_108A(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_A);
		if (IEEE80211_IS_CHAN_108G(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_TURBO_G);
		if (IEEE80211_IS_CHAN_ST(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_STURBO_A);
		if (IEEE80211_IS_CHAN_HALF(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_HALF);
		if (IEEE80211_IS_CHAN_QUARTER(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_QUARTER);
		if (IEEE80211_IS_CHAN_HTA(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_11NA);
		if (IEEE80211_IS_CHAN_HTG(c))
			setbit(ic->ic_modecaps, IEEE80211_MODE_11NG);
	}
	/* initialize candidate channels to all available */
	memcpy(ic->ic_chan_active, ic->ic_chan_avail,
		sizeof(ic->ic_chan_avail));

	/* sort channel table to allow lookup optimizations */
	ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);

	/* invalidate any previous state */
	ic->ic_bsschan = IEEE80211_CHAN_ANYC;
	ic->ic_prevchan = NULL;
	ic->ic_csa_newchan = NULL;
	/* arbitrarily pick the first channel */
	ic->ic_curchan = &ic->ic_channels[0];
	ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan);

	/* fillin well-known rate sets if driver has not specified */
	DEFAULTRATES(IEEE80211_MODE_11B,	 ieee80211_rateset_11b);
	DEFAULTRATES(IEEE80211_MODE_11G,	 ieee80211_rateset_11g);
	DEFAULTRATES(IEEE80211_MODE_11A,	 ieee80211_rateset_11a);
	DEFAULTRATES(IEEE80211_MODE_TURBO_A,	 ieee80211_rateset_11a);
	DEFAULTRATES(IEEE80211_MODE_TURBO_G,	 ieee80211_rateset_11g);
	DEFAULTRATES(IEEE80211_MODE_STURBO_A,	 ieee80211_rateset_11a);
	DEFAULTRATES(IEEE80211_MODE_HALF,	 ieee80211_rateset_half);
	DEFAULTRATES(IEEE80211_MODE_QUARTER,	 ieee80211_rateset_quarter);
	DEFAULTRATES(IEEE80211_MODE_11NA,	 ieee80211_rateset_11a);
	DEFAULTRATES(IEEE80211_MODE_11NG,	 ieee80211_rateset_11g);

	/*
	 * Set auto mode to reset active channel state and any desired channel.
	 */
	(void) ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
#undef DEFAULTRATES
}
Exemplo n.º 5
0
/*
 * rt2860_rf_set_chan
 */
void rt2860_rf_set_chan(struct rt2860_softc *sc,
	struct ieee80211_channel *c)
{
	struct ifnet *ifp;
	struct ieee80211com *ic;
	const struct rt2860_rf_prog *prog;
	uint32_t r1, r2, r3, r4;
	int8_t txpow1, txpow2;
	int i, chan;

	if (sc->mac_rev == 0x28720200) {
		rt2872_rf_set_chan(sc, c);
		return;
	} 

	ifp = sc->ifp;
	ic = ifp->if_l2com;
	prog = rt2860_rf_2850;

	/* get central channel position */

	chan = ieee80211_chan2ieee(ic, c);

	if ((sc->mac_rev & 0xffff0000) >= 0x30710000) {
		rt3090_set_chan(sc, chan);
		return;
	}

	if (IEEE80211_IS_CHAN_HT40U(c))
		chan += 2;
	else if (IEEE80211_IS_CHAN_HT40D(c))
		chan -= 2;

	RT2860_DPRINTF(sc, RT2860_DEBUG_CHAN,
		"%s: RF set channel: channel=%u, HT%s%s\n",
		device_get_nameunit(sc->dev),
		ieee80211_chan2ieee(ic, c),
		!IEEE80211_IS_CHAN_HT(c) ? " disabled" :
			IEEE80211_IS_CHAN_HT20(c) ? "20":
				IEEE80211_IS_CHAN_HT40U(c) ? "40U" : "40D",
		(ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");

	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
		return;

	for (i = 0; prog[i].chan != chan; i++);

	r1 = prog[i].r1;
	r2 = prog[i].r2;
	r3 = prog[i].r3;
	r4 = prog[i].r4;

	txpow1 = sc->txpow1[i];
	txpow2 = sc->txpow2[i];

	if (sc->ntxpath == 1)
		r2 |= (1 << 14);

	if (sc->nrxpath == 2)
		r2 |= (1 << 6);
	else if (sc->nrxpath == 1)
		r2 |= (1 << 17) | (1 << 6);

	if (IEEE80211_IS_CHAN_2GHZ(c))
	{
		r3 = (r3 & 0xffffc1ff) | (txpow1 << 9);
		r4 = (r4 & ~0x001f87c0) | (sc->rf_freq_off << 15) |
		    (txpow2 << 6);
	}
	else
	{
		r3 = r3 & 0xffffc1ff;
		r4 = (r4 & ~0x001f87c0) | (sc->rf_freq_off << 15);

		if (txpow1 >= RT2860_EEPROM_TXPOW_5GHZ_MIN && txpow1 < 0)
		{
			txpow1 = (-RT2860_EEPROM_TXPOW_5GHZ_MIN + txpow1);
			if (txpow1 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
				txpow1 = RT2860_EEPROM_TXPOW_5GHZ_MAX;

			r3 |= (txpow1 << 10);
		}
		else
		{
			if (txpow1 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
				txpow1 = RT2860_EEPROM_TXPOW_5GHZ_MAX;

			r3 |= (txpow1 << 10) | (1 << 9);
		}

		if (txpow2 >= RT2860_EEPROM_TXPOW_5GHZ_MIN && txpow2 < 0)
		{
			txpow2 = (-RT2860_EEPROM_TXPOW_5GHZ_MIN + txpow2);
			if (txpow2 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
				txpow2 = RT2860_EEPROM_TXPOW_5GHZ_MAX;

			r4 |= (txpow2 << 7);
		}
		else
		{
			if (txpow2 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
				txpow2 = RT2860_EEPROM_TXPOW_5GHZ_MAX;

			r4 |= (txpow2 << 7) | (1 << 6);
		}
	}

	if (!(ic->ic_flags & IEEE80211_F_SCAN) && IEEE80211_IS_CHAN_HT40(c))
		r4 |= (1 << 21);

	rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
	rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
	rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 & ~(1 << 2));
	rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);

	DELAY(200);

	rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
	rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
	rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 | (1 << 2));
	rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);

	DELAY(200);

	rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
	rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
	rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 & ~(1 << 2));
	rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);

	rt2860_rf_select_chan_group(sc, c);

	DELAY(1000);
}
Exemplo n.º 6
0
/*
 * rt2860_rf_select_chan_group
 */
void rt2860_rf_select_chan_group(struct rt2860_softc *sc,
	struct ieee80211_channel *c)
{
	struct ifnet *ifp;
	struct ieee80211com *ic;
	int chan, group;
	uint32_t tmp;

	ifp = sc->ifp;
	ic = ifp->if_l2com;

	chan = ieee80211_chan2ieee(ic, c);
	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
		return;

	if (chan <= 14)
		group = 0;
	else if (chan <= 64)
		group = 1;
	else if (chan <= 128)
		group = 2;
	else
		group = 3;

	rt2860_io_bbp_write(sc, 62, 0x37 - sc->lna_gain[group]);
	rt2860_io_bbp_write(sc, 63, 0x37 - sc->lna_gain[group]);
	rt2860_io_bbp_write(sc, 64, 0x37 - sc->lna_gain[group]);
	rt2860_io_bbp_write(sc, 86, 0x00);

	if (group == 0)
	{
		if (sc->ext_lna_2ghz)
		{
			rt2860_io_bbp_write(sc, 82, 0x62);
			rt2860_io_bbp_write(sc, 75, 0x46);
		}
		else
		{
			rt2860_io_bbp_write(sc, 82, 0x84);
			rt2860_io_bbp_write(sc, 75, 0x50);
		}
	}
	else
	{
		rt2860_io_bbp_write(sc, 82, 0xf2);

		if (sc->ext_lna_5ghz)
			rt2860_io_bbp_write(sc, 75, 0x46);
		else
			rt2860_io_bbp_write(sc, 75, 0x50);
	}

	if (group == 0)
	{
		tmp = 0x2e + sc->lna_gain[group];
	}
	else
	{
		if ((ic->ic_flags & IEEE80211_F_SCAN) || !IEEE80211_IS_CHAN_HT40(c))
			tmp = 0x32 + sc->lna_gain[group] * 5 / 3;
		else
			tmp = 0x3a + sc->lna_gain[group] * 5 / 3;
	}

	rt2860_io_bbp_write(sc, 66, tmp);

	tmp = RT2860_REG_RFTR_ENABLE |
		RT2860_REG_TRSW_ENABLE |
		RT2860_REG_LNA_PE_G1_ENABLE |
		RT2860_REG_LNA_PE_A1_ENABLE |
		RT2860_REG_LNA_PE_G0_ENABLE |
		RT2860_REG_LNA_PE_A0_ENABLE;

	if (group == 0)
		tmp |= RT2860_REG_PA_PE_G1_ENABLE |
			RT2860_REG_PA_PE_G0_ENABLE;
	else
		tmp |= RT2860_REG_PA_PE_A1_ENABLE |
			RT2860_REG_PA_PE_A0_ENABLE;

	if (sc->ntxpath == 1)
		tmp &= ~(RT2860_REG_PA_PE_G1_ENABLE | RT2860_REG_PA_PE_A1_ENABLE);

	if (sc->nrxpath == 1)
		tmp &= ~(RT2860_REG_LNA_PE_G1_ENABLE | RT2860_REG_LNA_PE_A1_ENABLE);

	rt2860_io_mac_write(sc, RT2860_REG_TX_PIN_CFG, tmp);

	tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_BAND_CFG);

	tmp &= ~(RT2860_REG_TX_BAND_BG | RT2860_REG_TX_BAND_A | RT2860_REG_TX_BAND_HT40_ABOVE);

	if (group == 0)
		tmp |= RT2860_REG_TX_BAND_BG;
	else
		tmp |= RT2860_REG_TX_BAND_A;

	/* set central channel position */

	if (IEEE80211_IS_CHAN_HT40U(c))
		tmp |= RT2860_REG_TX_BAND_HT40_BELOW;
	else if (IEEE80211_IS_CHAN_HT40D(c))
		tmp |= RT2860_REG_TX_BAND_HT40_ABOVE;
	else
		tmp |= RT2860_REG_TX_BAND_HT40_BELOW;

	rt2860_io_mac_write(sc, RT2860_REG_TX_BAND_CFG, tmp);

	/* set bandwidth (20MHz or 40MHz) */

	tmp = rt2860_io_bbp_read(sc, 4);

	tmp &= ~0x18;

	if (IEEE80211_IS_CHAN_HT40(c))
		tmp |= 0x10;

	rt2860_io_bbp_write(sc, 4, tmp);

	/* set central channel position */

	tmp = rt2860_io_bbp_read(sc, 3);

	tmp &= ~0x20;

	if (IEEE80211_IS_CHAN_HT40D(c))
		tmp |= 0x20;

	rt2860_io_bbp_write(sc, 3, tmp);

	if (sc->mac_rev == 0x28600100)
	{
		if (!IEEE80211_IS_CHAN_HT40(c))
		{
			rt2860_io_bbp_write(sc, 69, 0x16);
			rt2860_io_bbp_write(sc, 70, 0x08);
			rt2860_io_bbp_write(sc, 73, 0x12);
		}
		else
		{
			rt2860_io_bbp_write(sc, 69, 0x1a);
			rt2860_io_bbp_write(sc, 70, 0x0a);
			rt2860_io_bbp_write(sc, 73, 0x16);
		}
	}

}
Exemplo n.º 7
0
/*
 * rt2872_rf_set_chan
 */
static void 
rt2872_rf_set_chan(struct rt2860_softc *sc,
	struct ieee80211_channel *c)
{
	struct ifnet *ifp;
	struct ieee80211com *ic;
	const struct rt2860_rf_prog *prog;
	uint32_t r1, r2, r3, r4;
	uint32_t r6, r7, r12, r13, r23, r24;
	int8_t txpow1, txpow2;
	int i, chan;

	ifp = sc->ifp;
	ic = ifp->if_l2com;
	prog = rt2860_rf_2850;

	/* get central channel position */

	chan = ieee80211_chan2ieee(ic, c);

	if (IEEE80211_IS_CHAN_HT40U(c))
		chan += 2;
	else if (IEEE80211_IS_CHAN_HT40D(c))
		chan -= 2;

	RT2860_DPRINTF(sc, RT2860_DEBUG_CHAN,
		"%s: RF set channel: channel=%u, HT%s%s\n",
		device_get_nameunit(sc->dev),
		ieee80211_chan2ieee(ic, c),
		!IEEE80211_IS_CHAN_HT(c) ? " disabled" :
			IEEE80211_IS_CHAN_HT20(c) ? "20":
				IEEE80211_IS_CHAN_HT40U(c) ? "40U" : "40D",
		(ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");

	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
		return;

	for (i = 0; prog[i].chan != chan; i++);

	r1 = prog[i].r1;
	r2 = prog[i].r2;
	r3 = prog[i].r3;
	r4 = prog[i].r4;

	txpow1 = sc->txpow1[i];
	txpow2 = sc->txpow2[i];

	for (i = 0; rt2860_rf_fi3020[i].channel != chan; i++);

	/* Programm channel parameters */
	r2 = rt2860_rf_fi3020[i].n;
	rt2860_io_rf_write(sc, 2 , r2 );
	r3 = rt2860_rf_fi3020[i].k;
	rt2860_io_rf_write(sc, 3 , r3 );

	r6 = (rt3052_rf_default[6] & 0xFC) | (rt2860_rf_fi3020[i].r & 0x03);
	rt2860_io_rf_write(sc, 6 , r6 );

	/* Set Tx Power */
	r12 = (rt3052_rf_default[12] & 0xE0) | (txpow1 & 0x1f);
	rt2860_io_rf_write(sc, 12, r12);

	/* Set Tx1 Power */
	r13 = (rt3052_rf_default[13] & 0xE0) | (txpow2 & 0x1f);
	rt2860_io_rf_write(sc, 13, r13);

	/* Set RF offset */
	r23 = (rt3052_rf_default[23] & 0x80) | (sc->rf_freq_off);
	rt2860_io_rf_write(sc, 23, r23);

	/* Set BW */
	r24 = (rt3052_rf_default[24] & 0xDF);
	if (!(ic->ic_flags & IEEE80211_F_SCAN) && IEEE80211_IS_CHAN_HT40(c))
	    r24 |= 0x20;
	rt2860_io_rf_write(sc, 24, r24);

	/* Enable RF tuning */
	r7 = (rt3052_rf_default[7]) | 1;
	rt2860_io_rf_write(sc, 7 , r7 );

	/* Antenna */
	r1 = (rt3052_rf_default[1] & 0xab) | ((sc->nrxpath == 1)?0x10:0) |
	    ((sc->ntxpath == 1)?0x20:0);
	rt2860_io_rf_write(sc, 1 , r1 );

	DELAY(200);

	rt2860_rf_select_chan_group(sc, c);

	DELAY(1000);
}