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

Commit 0fb8ca45 authored by Jouni Malinen's avatar Jouni Malinen Committed by John W. Linville
Browse files

mac80211: Add HT rates into RX status reporting



This patch adds option for HT-enabled drivers to report HT rates
(HT20/HT40, short GI, MCS index) to mac80211. These rates are
currently not in the rate table, so the rate_idx is used to indicate
MCS index.

Signed-off-by: default avatarJouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9d8eed12
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -436,6 +436,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
 *	is valid. This is useful in monitor mode and necessary for beacon frames
 *	to enable IBSS merging.
 * @RX_FLAG_SHORTPRE: Short preamble was used for this frame
 * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
 * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
 * @RX_FLAG_SHORT_GI: Short guard interval was used
 */
enum mac80211_rx_flags {
	RX_FLAG_MMIC_ERROR	= 1<<0,
@@ -446,7 +449,10 @@ enum mac80211_rx_flags {
	RX_FLAG_FAILED_FCS_CRC	= 1<<5,
	RX_FLAG_FAILED_PLCP_CRC = 1<<6,
	RX_FLAG_TSFT		= 1<<7,
	RX_FLAG_SHORTPRE	= 1<<8
	RX_FLAG_SHORTPRE	= 1<<8,
	RX_FLAG_HT		= 1<<9,
	RX_FLAG_40MHZ		= 1<<10,
	RX_FLAG_SHORT_GI	= 1<<11,
};

/**
@@ -466,7 +472,8 @@ enum mac80211_rx_flags {
 * @noise: noise when receiving this frame, in dBm.
 * @qual: overall signal quality indication, in percent (0-100).
 * @antenna: antenna used
 * @rate_idx: index of data rate into band's supported rates
 * @rate_idx: index of data rate into band's supported rates or MCS index if
 *	HT rates are use (RX_FLAG_HT)
 * @flag: %RX_FLAG_*
 */
struct ieee80211_rx_status {
+6 −1
Original line number Diff line number Diff line
@@ -1613,8 +1613,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
			 * e.g: at 1 MBit that means mactime is 192 usec earlier
			 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
			 */
			int rate = local->hw.wiphy->bands[band]->
			int rate;
			if (rx_status->flag & RX_FLAG_HT) {
				rate = 65; /* TODO: HT rates */
			} else {
				rate = local->hw.wiphy->bands[band]->
					bitrates[rx_status->rate_idx].bitrate;
			}
			rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
		} else if (local && local->ops && local->ops->get_tsf)
			/* second best option: get current TSF */
+46 −10
Original line number Diff line number Diff line
@@ -149,6 +149,16 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
	pos++;

	/* IEEE80211_RADIOTAP_RATE */
	if (status->flag & RX_FLAG_HT) {
		/*
		 * TODO: add following information into radiotap header once
		 * suitable fields are defined for it:
		 * - MCS index (status->rate_idx)
		 * - HT40 (status->flag & RX_FLAG_40MHZ)
		 * - short-GI (status->flag & RX_FLAG_SHORT_GI)
		 */
		*pos = 0;
	} else
		*pos = rate->bitrate / 5;
	pos++;

@@ -1849,9 +1859,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
			if (!(sdata->dev->flags & IFF_PROMISC))
				return 0;
			rx->flags &= ~IEEE80211_RX_RA_MATCH;
		} else if (!rx->sta)
		} else if (!rx->sta) {
			int rate_idx;
			if (rx->status->flag & RX_FLAG_HT)
				rate_idx = 0; /* TODO: HT rates */
			else
				rate_idx = rx->status->rate_idx;
			rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2,
				BIT(rx->status->rate_idx));
				BIT(rate_idx));
		}
		break;
	case NL80211_IFTYPE_MESH_POINT:
		if (!multicast &&
@@ -2057,7 +2073,13 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
					tid_agg_rx->reorder_buf[index]->cb,
					sizeof(status));
				sband = local->hw.wiphy->bands[status.band];
				rate = &sband->bitrates[status.rate_idx];
				if (status.flag & RX_FLAG_HT) {
					/* TODO: HT rates */
					rate = sband->bitrates;
				} else {
					rate = &sband->bitrates
						[status.rate_idx];
				}
				__ieee80211_rx_handle_packet(hw,
					tid_agg_rx->reorder_buf[index],
					&status, rate);
@@ -2101,6 +2123,9 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
		memcpy(&status, tid_agg_rx->reorder_buf[index]->cb,
			sizeof(status));
		sband = local->hw.wiphy->bands[status.band];
		if (status.flag & RX_FLAG_HT)
			rate = sband->bitrates; /* TODO: HT rates */
		else
			rate = &sband->bitrates[status.rate_idx];
		__ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
					     &status, rate);
@@ -2189,15 +2214,26 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
	}

	sband = local->hw.wiphy->bands[status->band];

	if (!sband ||
	    status->rate_idx < 0 ||
	    status->rate_idx >= sband->n_bitrates) {
	if (!sband) {
		WARN_ON(1);
		return;
	}

	if (status->flag & RX_FLAG_HT) {
		/* rate_idx is MCS index */
		if (WARN_ON(status->rate_idx < 0 ||
			    status->rate_idx >= 76))
			return;
		/* HT rates are not in the table - use the highest legacy rate
		 * for now since other parts of mac80211 may not yet be fully
		 * MCS aware. */
		rate = &sband->bitrates[sband->n_bitrates - 1];
	} else {
		if (WARN_ON(status->rate_idx < 0 ||
			    status->rate_idx >= sband->n_bitrates))
			return;
		rate = &sband->bitrates[status->rate_idx];
	}

	/*
	 * key references and virtual interfaces are protected using RCU