示例#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
}
示例#2
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);
		}
	}

}
示例#3
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);
}
示例#4
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);
}