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

Commit 7e9ed188 authored by Daniel Drake's avatar Daniel Drake Committed by David S. Miller
Browse files

[MAC80211]: improved short preamble handling



Similarly to CTS protection, whether short preambles are used for 802.11b
transmissions should be a per-subif setting, not device global.

For STAs, this patch makes short preamble handling automatic based on the ERP
IE. For APs, hostapd still uses the prism ioctls, but the write ioctl has been
restricted to AP-only subifs.

ieee80211_txrx_data.short_preamble (an unused field) was removed.

Unfortunately, some API changes were required for the following functions:
 - ieee80211_generic_frame_duration
 - ieee80211_rts_duration
 - ieee80211_ctstoself_duration
 - ieee80211_rts_get
 - ieee80211_ctstoself_get
Affected drivers were updated accordingly.

Signed-off-by: default avatarDaniel Drake <dsd@gentoo.org>
Signed-off-by: default avatarJiri Benc <jbenc@suse.cz>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d5d08def
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -67,6 +67,7 @@ struct rtl8187_priv {
	struct rtl818x_csr *map;
	struct rtl818x_csr *map;
	void (*rf_init)(struct ieee80211_hw *);
	void (*rf_init)(struct ieee80211_hw *);
	int mode;
	int mode;
	int if_id;


	/* rtl8187 specific */
	/* rtl8187 specific */
	struct ieee80211_channel channels[14];
	struct ieee80211_channel channels[14];
+3 −1
Original line number Original line Diff line number Diff line
@@ -96,7 +96,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
	if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
	if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
		tmp |= RTL8187_TX_FLAG_RTS;
		tmp |= RTL8187_TX_FLAG_RTS;
		hdr->rts_duration =
		hdr->rts_duration =
			ieee80211_rts_duration(dev, skb->len, control);
			ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
	}
	}
	if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
	if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
		tmp |= RTL8187_TX_FLAG_CTS;
		tmp |= RTL8187_TX_FLAG_CTS;
@@ -510,6 +510,8 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id,
	struct rtl8187_priv *priv = dev->priv;
	struct rtl8187_priv *priv = dev->priv;
	int i;
	int i;


	priv->if_id = if_id;

	for (i = 0; i < ETH_ALEN; i++)
	for (i = 0; i < ETH_ALEN; i++)
		rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
		rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);


+10 −5
Original line number Original line Diff line number Diff line
@@ -835,6 +835,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
/**
/**
 * ieee80211_rts_get - RTS frame generation function
 * ieee80211_rts_get - RTS frame generation function
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @if_id: interface ID from &struct ieee80211_if_init_conf.
 * @frame: pointer to the frame that is going to be protected by the RTS.
 * @frame: pointer to the frame that is going to be protected by the RTS.
 * @frame_len: the frame length (in octets).
 * @frame_len: the frame length (in octets).
 * @frame_txctl: &struct ieee80211_tx_control of the frame.
 * @frame_txctl: &struct ieee80211_tx_control of the frame.
@@ -845,7 +846,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
 * the next RTS frame from the 802.11 code. The low-level is responsible
 * the next RTS frame from the 802.11 code. The low-level is responsible
 * for calling this function before and RTS frame is needed.
 * for calling this function before and RTS frame is needed.
 */
 */
void ieee80211_rts_get(struct ieee80211_hw *hw,
void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
		       const void *frame, size_t frame_len,
		       const void *frame, size_t frame_len,
		       const struct ieee80211_tx_control *frame_txctl,
		       const struct ieee80211_tx_control *frame_txctl,
		       struct ieee80211_rts *rts);
		       struct ieee80211_rts *rts);
@@ -853,6 +854,7 @@ void ieee80211_rts_get(struct ieee80211_hw *hw,
/**
/**
 * ieee80211_rts_duration - Get the duration field for an RTS frame
 * ieee80211_rts_duration - Get the duration field for an RTS frame
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @if_id: interface ID from &struct ieee80211_if_init_conf.
 * @frame_len: the length of the frame that is going to be protected by the RTS.
 * @frame_len: the length of the frame that is going to be protected by the RTS.
 * @frame_txctl: &struct ieee80211_tx_control of the frame.
 * @frame_txctl: &struct ieee80211_tx_control of the frame.
 *
 *
@@ -860,13 +862,14 @@ void ieee80211_rts_get(struct ieee80211_hw *hw,
 * the duration field, the low-level driver uses this function to receive
 * the duration field, the low-level driver uses this function to receive
 * the duration field value in little-endian byteorder.
 * the duration field value in little-endian byteorder.
 */
 */
__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
			      size_t frame_len,
			      size_t frame_len,
			      const struct ieee80211_tx_control *frame_txctl);
			      const struct ieee80211_tx_control *frame_txctl);


/**
/**
 * ieee80211_ctstoself_get - CTS-to-self frame generation function
 * ieee80211_ctstoself_get - CTS-to-self frame generation function
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @if_id: interface ID from &struct ieee80211_if_init_conf.
 * @frame: pointer to the frame that is going to be protected by the CTS-to-self.
 * @frame: pointer to the frame that is going to be protected by the CTS-to-self.
 * @frame_len: the frame length (in octets).
 * @frame_len: the frame length (in octets).
 * @frame_txctl: &struct ieee80211_tx_control of the frame.
 * @frame_txctl: &struct ieee80211_tx_control of the frame.
@@ -877,7 +880,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
 * the next CTS-to-self frame from the 802.11 code. The low-level is responsible
 * the next CTS-to-self frame from the 802.11 code. The low-level is responsible
 * for calling this function before and CTS-to-self frame is needed.
 * for calling this function before and CTS-to-self frame is needed.
 */
 */
void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
			     const void *frame, size_t frame_len,
			     const void *frame, size_t frame_len,
			     const struct ieee80211_tx_control *frame_txctl,
			     const struct ieee80211_tx_control *frame_txctl,
			     struct ieee80211_cts *cts);
			     struct ieee80211_cts *cts);
@@ -885,6 +888,7 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
/**
/**
 * ieee80211_ctstoself_duration - Get the duration field for a CTS-to-self frame
 * ieee80211_ctstoself_duration - Get the duration field for a CTS-to-self frame
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @if_id: interface ID from &struct ieee80211_if_init_conf.
 * @frame_len: the length of the frame that is going to be protected by the CTS-to-self.
 * @frame_len: the length of the frame that is going to be protected by the CTS-to-self.
 * @frame_txctl: &struct ieee80211_tx_control of the frame.
 * @frame_txctl: &struct ieee80211_tx_control of the frame.
 *
 *
@@ -892,20 +896,21 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
 * the duration field, the low-level driver uses this function to receive
 * the duration field, the low-level driver uses this function to receive
 * the duration field value in little-endian byteorder.
 * the duration field value in little-endian byteorder.
 */
 */
__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
				    size_t frame_len,
				    size_t frame_len,
				    const struct ieee80211_tx_control *frame_txctl);
				    const struct ieee80211_tx_control *frame_txctl);


/**
/**
 * ieee80211_generic_frame_duration - Calculate the duration field for a frame
 * ieee80211_generic_frame_duration - Calculate the duration field for a frame
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @hw: pointer obtained from ieee80211_alloc_hw().
 * @if_id: interface ID from &struct ieee80211_if_init_conf.
 * @frame_len: the length of the frame.
 * @frame_len: the length of the frame.
 * @rate: the rate (in 100kbps) at which the frame is going to be transmitted.
 * @rate: the rate (in 100kbps) at which the frame is going to be transmitted.
 *
 *
 * Calculate the duration field of some generic frame, given its
 * Calculate the duration field of some generic frame, given its
 * length and transmission rate (in 100kbps).
 * length and transmission rate (in 100kbps).
 */
 */
__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
					size_t frame_len,
					size_t frame_len,
					int rate);
					int rate);


+5 −2
Original line number Original line Diff line number Diff line
@@ -127,7 +127,6 @@ struct ieee80211_txrx_data {
			struct ieee80211_tx_control *control;
			struct ieee80211_tx_control *control;
			unsigned int unicast:1;
			unsigned int unicast:1;
			unsigned int ps_buffered:1;
			unsigned int ps_buffered:1;
			unsigned int short_preamble:1;
			unsigned int probe_last_frag:1;
			unsigned int probe_last_frag:1;
			struct ieee80211_hw_mode *mode;
			struct ieee80211_hw_mode *mode;
			struct ieee80211_rate *rate;
			struct ieee80211_rate *rate;
@@ -286,6 +285,11 @@ struct ieee80211_sub_if_data {
	unsigned int promisc:1;
	unsigned int promisc:1;
	unsigned int use_protection:1; /* CTS protect ERP frames */
	unsigned int use_protection:1; /* CTS protect ERP frames */


	/* use short preamble with IEEE 802.11b: this flag is set when the AP
	 * or beacon generator reports that there are no present stations that
	 * cannot support short preambles */
	unsigned int short_preamble:1;

	struct net_device_stats stats;
	struct net_device_stats stats;
	int drop_unencrypted;
	int drop_unencrypted;
	int eapol; /* 0 = process EAPOL frames as normal data frames,
	int eapol; /* 0 = process EAPOL frames as normal data frames,
@@ -447,7 +451,6 @@ struct ieee80211_local {
	int fragmentation_threshold;
	int fragmentation_threshold;
	int short_retry_limit; /* dot11ShortRetryLimit */
	int short_retry_limit; /* dot11ShortRetryLimit */
	int long_retry_limit; /* dot11LongRetryLimit */
	int long_retry_limit; /* dot11LongRetryLimit */
	int short_preamble; /* use short preamble with IEEE 802.11b */


	struct crypto_blkcipher *wep_tx_tfm;
	struct crypto_blkcipher *wep_tx_tfm;
	struct crypto_blkcipher *wep_rx_tfm;
	struct crypto_blkcipher *wep_rx_tfm;
+5 −2
Original line number Original line Diff line number Diff line
@@ -1061,7 +1061,10 @@ static int ieee80211_ioctl_prism2_param(struct net_device *dev,
		break;
		break;


	case PRISM2_PARAM_PREAMBLE:
	case PRISM2_PARAM_PREAMBLE:
		local->short_preamble = value;
		if (sdata->type != IEEE80211_IF_TYPE_AP)
			ret = -ENOENT;
		else
			sdata->short_preamble = value;
		break;
		break;


	case PRISM2_PARAM_STAT_TIME:
	case PRISM2_PARAM_STAT_TIME:
@@ -1184,7 +1187,7 @@ static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
		break;
		break;


	case PRISM2_PARAM_PREAMBLE:
	case PRISM2_PARAM_PREAMBLE:
		*param = local->short_preamble;
		*param = sdata->short_preamble;
		break;
		break;


	case PRISM2_PARAM_STAT_TIME:
	case PRISM2_PARAM_STAT_TIME:
Loading