Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9fe60de authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

802.11: clean up/fix HT support



This patch cleans up a number of things:
 * the unusable definition of the HT capabilities/HT information
   information elements
 * variable names that are hard to understand
 * mac80211: move ieee80211_handle_ht to ht.c and remove the unused
             enable_ht parameter
 * mac80211: fix bug with MCS rate 32 in ieee80211_handle_ht
 * mac80211: fix bug with casting the result of ieee80211_bss_get_ie
             to an information element _contents_ rather than the
             whole element, add size checking (another out-of-bounds
             access bug fixed!)
 * mac80211: remove some unused return values in favour of BUG_ON
             checking
 * a few minor other things

Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 40333e4f
Loading
Loading
Loading
Loading
+27 −30
Original line number Diff line number Diff line
@@ -61,24 +61,24 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,

	switch (chan->band) {
	case IEEE80211_BAND_2GHZ:
		if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) &&
		if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) &&
		    (tx_chan_width == ATH9K_HT_MACMODE_20))
			chanmode = CHANNEL_G_HT20;
		if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) &&
		if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) &&
		    (tx_chan_width == ATH9K_HT_MACMODE_2040))
			chanmode = CHANNEL_G_HT40PLUS;
		if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) &&
		if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) &&
		    (tx_chan_width == ATH9K_HT_MACMODE_2040))
			chanmode = CHANNEL_G_HT40MINUS;
		break;
	case IEEE80211_BAND_5GHZ:
		if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) &&
		if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) &&
		    (tx_chan_width == ATH9K_HT_MACMODE_20))
			chanmode = CHANNEL_A_HT20;
		if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) &&
		if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) &&
		    (tx_chan_width == ATH9K_HT_MACMODE_2040))
			chanmode = CHANNEL_A_HT40PLUS;
		if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) &&
		if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) &&
		    (tx_chan_width == ATH9K_HT_MACMODE_2040))
			chanmode = CHANNEL_A_HT40MINUS;
		break;
@@ -215,24 +215,24 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
	ath_key_reset(sc, key->keyidx, freeslot);
}

static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
{
#define	ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3	/* 2 ^ 16 */
#define	ATH9K_HT_CAP_MPDUDENSITY_8 0x6		/* 8 usec */

	ht_info->ht_supported = 1;
	ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH
			|(u16)IEEE80211_HT_CAP_SM_PS
			|(u16)IEEE80211_HT_CAP_SGI_40
			|(u16)IEEE80211_HT_CAP_DSSSCCK40;
	ht_info->ht_supported = true;
	ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
		       IEEE80211_HT_CAP_SM_PS |
		       IEEE80211_HT_CAP_SGI_40 |
		       IEEE80211_HT_CAP_DSSSCCK40;

	ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
	ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
	/* set up supported mcs set */
	memset(ht_info->supp_mcs_set, 0, 16);
	ht_info->supp_mcs_set[0] = 0xff;
	ht_info->supp_mcs_set[1] = 0xff;
	ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED;
	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
	ht_info->mcs.rx_mask[0] = 0xff;
	ht_info->mcs.rx_mask[1] = 0xff;
	ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
}

static int ath_rate2idx(struct ath_softc *sc, int rate)
@@ -328,31 +328,28 @@ static u8 parse_mpdudensity(u8 mpdudensity)
static void ath9k_ht_conf(struct ath_softc *sc,
			  struct ieee80211_bss_conf *bss_conf)
{
#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14)
	struct ath_ht_info *ht_info = &sc->sc_ht_info;

	if (bss_conf->assoc_ht) {
		ht_info->ext_chan_offset =
			bss_conf->ht_bss_conf->bss_cap &
				IEEE80211_HT_IE_CHA_SEC_OFFSET;
				IEEE80211_HT_PARAM_CHA_SEC_OFFSET;

		if (!(bss_conf->ht_conf->cap &
		if (!(bss_conf->ht_cap->cap &
			IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
			    (bss_conf->ht_bss_conf->bss_cap &
				IEEE80211_HT_IE_CHA_WIDTH))
				IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
			ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040;
		else
			ht_info->tx_chan_width = ATH9K_HT_MACMODE_20;

		ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width);
		ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
					bss_conf->ht_conf->ampdu_factor);
					bss_conf->ht_cap->ampdu_factor);
		ht_info->mpdudensity =
			parse_mpdudensity(bss_conf->ht_conf->ampdu_density);
			parse_mpdudensity(bss_conf->ht_cap->ampdu_density);

	}

#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT
}

static void ath9k_bss_assoc_info(struct ath_softc *sc,
@@ -411,7 +408,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
			return;
		}

		if (hw->conf.ht_conf.ht_supported)
		if (hw->conf.ht_cap.ht_supported)
			sc->sc_ah->ah_channels[pos].chanmode =
				ath_get_extchanmode(sc, curchan);
		else
@@ -534,7 +531,7 @@ int _ath_rx_indicate(struct ath_softc *sc,

	if (an) {
		ath_rx_input(sc, an,
			     hw->conf.ht_conf.ht_supported,
			     hw->conf.ht_cap.ht_supported,
			     skb, status, &st);
	}
	if (!an || (st != ATH_RX_CONSUMED))
@@ -943,7 +940,7 @@ static int ath_attach(u16 devid,

	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
		/* Setup HT capabilities for 2.4Ghz*/
		setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info);
		setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);

	hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
		&sc->sbands[IEEE80211_BAND_2GHZ];
@@ -958,7 +955,7 @@ static int ath_attach(u16 devid,

		if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
			/* Setup HT capabilities for 5Ghz*/
			setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info);
			setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);

		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
			&sc->sbands[IEEE80211_BAND_5GHZ];
@@ -1254,7 +1251,7 @@ static int ath9k_config(struct ieee80211_hw *hw,
		(curchan->band == IEEE80211_BAND_2GHZ) ?
		CHANNEL_G : CHANNEL_A;

	if (sc->sc_curaid && hw->conf.ht_conf.ht_supported)
	if (sc->sc_curaid && hw->conf.ht_cap.ht_supported)
		sc->sc_ah->ah_channels[pos].chanmode =
			ath_get_extchanmode(sc, curchan);

+5 −5
Original line number Diff line number Diff line
@@ -1838,7 +1838,7 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv)
	struct ath_softc *sc = hw->priv;
	u32 capflag = 0;

	if (hw->conf.ht_conf.ht_supported) {
	if (hw->conf.ht_cap.ht_supported) {
		capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG;
		if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040)
			capflag |= ATH_RC_CW40_FLAG;
@@ -1910,7 +1910,7 @@ static void ath_tx_aggr_resp(struct ath_softc *sc,
	 */
	si = container_of(sta, struct sta_info, sta);
	buffersize = IEEE80211_MIN_AMPDU_BUF <<
		sband->ht_info.ampdu_factor; /* FIXME */
		sband->ht_cap.ampdu_factor; /* FIXME */
	state = si->ampdu_mlme.tid_state_tx[tidno];

	if (state & HT_ADDBA_RECEIVED_MSK) {
@@ -1979,7 +1979,7 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,

	/* Check if aggregation has to be enabled for this tid */

	if (hw->conf.ht_conf.ht_supported) {
	if (hw->conf.ht_cap.ht_supported) {
		if (ieee80211_is_data_qos(fc)) {
			qc = ieee80211_get_qos_ctl(hdr);
			tid = qc[0] & 0xf;
@@ -2027,8 +2027,8 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,

	ath_setup_rates(sc, sband, sta, ath_rc_priv);
	if (sc->hw->conf.flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
		for (i = 0; i < MCS_SET_SIZE; i++) {
			if (sc->hw->conf.ht_conf.supp_mcs_set[i/8] & (1<<(i%8)))
		for (i = 0; i < 77; i++) {
			if (sc->hw->conf.ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
				ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
			if (j == ATH_RATE_MAX)
				break;
+0 −1
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ struct ath_softc;
#define FALSE 0

#define ATH_RATE_MAX	30
#define MCS_SET_SIZE	128

enum ieee80211_fixed_rate_mode {
	IEEE80211_FIXED_RATE_NONE  = 0,
+1 −1
Original line number Diff line number Diff line
@@ -1119,7 +1119,7 @@ int ath_rx_aggr_start(struct ath_softc *sc,

	sband = hw->wiphy->bands[hw->conf.channel->band];
	buffersize = IEEE80211_MIN_AMPDU_BUF <<
		sband->ht_info.ampdu_factor; /* FIXME */
		sband->ht_cap.ampdu_factor; /* FIXME */

	rxtid = &an->an_aggr.rx.tid[tid];

+1 −1
Original line number Diff line number Diff line
@@ -300,7 +300,7 @@ static int ath_tx_prepare(struct ath_softc *sc,
	if (ieee80211_is_data(fc) && !txctl->use_minrate) {

		/* Enable HT only for DATA frames and not for EAPOL */
		txctl->ht = (hw->conf.ht_conf.ht_supported &&
		txctl->ht = (hw->conf.ht_cap.ht_supported &&
			    (tx_info->flags & IEEE80211_TX_CTL_AMPDU));

		if (is_multicast_ether_addr(hdr->addr1)) {
Loading