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

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

mac80211: fix TX sequence numbers



This patch makes mac80211 assign proper sequence numbers to
QoS-data frames. It also removes the old sequence number code
because we noticed that only the driver or hardware can assign
sequence numbers to non-QoS-data and especially management
frames in a race-free manner because beacons aren't passed
through mac80211's TX path.

This patch also adds temporary code to the rt2x00 drivers to
not break them completely, that code will have to be reworked
for proper sequence numbers on beacons.

It also moves sequence number assignment down in the TX path
so no sequence numbers are assigned to frames that are dropped.

Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 22bb1be4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -317,7 +317,8 @@ int b43_generate_txhdr(struct b43_wldev *dev,
	/* MAC control */
	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
		mac_ctl |= B43_TXH_MAC_ACK;
	if (!ieee80211_is_pspoll(fctl))
	/* use hardware sequence counter as the non-TID counter */
	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
		mac_ctl |= B43_TXH_MAC_HWSEQ;
	if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
		mac_ctl |= B43_TXH_MAC_STMSDU;
+1 −2
Original line number Diff line number Diff line
@@ -295,8 +295,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
	/* MAC control */
	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
		mac_ctl |= B43legacy_TX4_MAC_ACK;
	if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
	      ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
		mac_ctl |= B43legacy_TX4_MAC_HWSEQ;
	if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
		mac_ctl |= B43legacy_TX4_MAC_STMSDU;
+2 −0
Original line number Diff line number Diff line
@@ -364,6 +364,8 @@ struct rt2x00_intf {
#define DELAYED_UPDATE_BEACON		0x00000001
#define DELAYED_CONFIG_ERP		0x00000002
#define DELAYED_LED_ASSOC		0x00000004

	u16 seqno;
};

static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
+13 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
	enum data_queue_qid qid = skb_get_queue_mapping(skb);
	struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
	struct data_queue *queue;
	u16 frame_control;

@@ -151,6 +152,18 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
		}
	}

	/*
	 * XXX: This is as wrong as the old mac80211 code was,
	 *	due to beacons not getting sequence numbers assigned
	 *	properly.
	 */
	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
		if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
			intf->seqno += 0x10;
		ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
		ieee80211hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
	}

	if (rt2x00queue_write_tx_frame(queue, skb)) {
		ieee80211_stop_queue(rt2x00dev->hw, qid);
		return NETDEV_TX_BUSY;
+12 −0
Original line number Diff line number Diff line
@@ -239,6 +239,17 @@ struct ieee80211_bss_conf {
 * 	is for the whole aggregation.
 * @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned,
 * 	so consider using block ack request (BAR).
 * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence
 *	number to this frame, taking care of not overwriting the fragment
 *	number and increasing the sequence number only when the
 *	IEEE80211_TX_CTL_FIRST_FRAGMENT flags is set. mac80211 will properly
 *	assign sequence numbers to QoS-data frames but cannot do so correctly
 *	for non-QoS-data and management frames because beacons need them from
 *	that counter as well and mac80211 cannot guarantee proper sequencing.
 *	If this flag is set, the driver should instruct the hardware to
 *	assign a sequence number to the frame or assign one itself. Cf. IEEE
 *	802.11-2007 7.1.3.4.1 paragraph 3. This flag will always be set for
 *	beacons always be clear for frames without a sequence number field.
 */
enum mac80211_tx_control_flags {
	IEEE80211_TX_CTL_REQ_TX_STATUS		= BIT(0),
@@ -265,6 +276,7 @@ enum mac80211_tx_control_flags {
	IEEE80211_TX_STAT_ACK			= BIT(21),
	IEEE80211_TX_STAT_AMPDU			= BIT(22),
	IEEE80211_TX_STAT_AMPDU_NO_BACK		= BIT(23),
	IEEE80211_TX_CTL_ASSIGN_SEQ		= BIT(24),
};


Loading