d80211: Add software sequence support
Subsystems (2)
PATCH 2/2 d80211: Add software sequence support
Most hardware can keep track of sequence numbers themselves, unfortunately *most* doesn't cover all devices. ;) This patch will keep track of the sequence number if the flag IEEE80211_HW_SOFTWARE_SEQUENCE has been set.
Signed-off-by Ivo van Doorn <[email protected]>
---
include/net/d80211.h +3 -0
@@ -534,6 +534,9 @@/* Does the device need the stack to create a RTS frame */ #define IEEE80211_HW_SOFTWARE_RTS (1<<15) +/* Does the HOST need to insert the frame sequence counter */ +#define IEEE80211_HW_SOFTWARE_SEQUENCE (1<<16) +u32 flags;/* hardware flags defined above */ /* Set to the size of a needed device specific skb headroom for TX skbs. */
net/d80211/ieee80211.c +22 -1
@@ -441,6 +441,7 @@size_t hdrlen, per_fragm, num_fragm, payload_len, left;struct sk_buff **frags, *first, *frag;int i; +u16 seq;u8 *pos;int frag_threshold = tx->local->fragmentation_threshold;
@@ -458,6 +459,7 @@if (!frags) goto fail; + seq =le16_to_cpu (hdr->seq_ctrl) &IEEE80211_SCTL_SEQ ; hdr->frame_control |=cpu_to_le16 (IEEE80211_FCTL_MOREFRAGS ); pos = first->data + hdrlen + per_fragm; left = payload_len - per_fragm;
@@ -486,7 +488,7 @@memcpy (fhdr, first->data, hdrlen);if (i == num_fragm -2 ) fhdr->frame_control &=cpu_to_le16 (~IEEE80211_FCTL_MOREFRAGS ); - fhdr->seq_ctrl =cpu_to_le16 (i +1 ); + fhdr->seq_ctrl =cpu_to_le16 (seq + ((i +1 ) &IEEE80211_SCTL_FRAG )); copylen = left > per_fragm ? per_fragm : left;memcpy (skb_put (frag, copylen), pos, copylen);
@@ -933,6 +935,19 @@return TXRX_CONTINUE ; } +static ieee80211_txrx_result +ieee80211_tx_h_sequence (struct ieee80211_txrx_data *tx) +{ +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; + +if (!(tx->local->hw.flags &IEEE80211_HW_SOFTWARE_SEQUENCE ) || +ieee80211_get_hdrlen (le16_to_cpu (hdr->frame_control)) <24 ) +return TXRX_CONTINUE ; + +ieee80211_include_sequence (tx->local, hdr); + +return TXRX_CONTINUE ; +}/* This function is called whenever the AP is about to exceed the maximum limit * of buffered frames for power saving STAs. This situation should not really
@@ -1806,6 +1821,10 @@memcpy (skb_put (skb, bh_len), b_head, bh_len); +if (!(hw->flags &IEEE80211_HW_SOFTWARE_SEQUENCE )) +ieee80211_include_sequence (local, + (struct ieee80211_hdr *)skb->data); +ieee80211_beacon_add_tim (local, ap, skb);if (b_tail) {
@@ -4323,6 +4342,7 @@static ieee80211_tx_handler ieee80211_tx_handlers[] = { ieee80211_tx_h_check_assoc, + ieee80211_tx_h_sequence, ieee80211_tx_h_ps_buf, ieee80211_tx_h_select_key, ieee80211_tx_h_michael_mic_add,
@@ -4497,6 +4517,7 @@ local->bridge_packets =1 ; + local->seq_counter =0 ; local->rts_threshold =IEEE80211_MAX_RTS_THRESHOLD ; local->fragmentation_threshold =IEEE80211_MAX_FRAG_THRESHOLD ; local->short_retry_limit =7 ;
net/d80211/ieee80211_i.h +15 -0
@@ -405,6 +405,7 @@int *supp_rates[NUM_IEEE80211_MODES ];int *basic_rates[NUM_IEEE80211_MODES ]; +u16 seq_counter;int rts_threshold;int cts_protect_erp_frames;int fragmentation_threshold;
@@ -601,6 +602,20 @@spin_unlock_bh (&local->sta_lock); } +static inline void ieee80211_include_sequence (struct ieee80211_local *local, +struct ieee80211_hdr *hdr) +{ +/* +* Set the sequence number for this frame. +*/ + hdr->seq_ctrl =cpu_to_le16 (local->seq_counter &IEEE80211_SCTL_SEQ ); + +/* +* Increase the sequence number. +*/ + local->seq_counter = (local->seq_counter +0x10 ) &IEEE80211_SCTL_SEQ ; +} +/* ieee80211.c */ void ieee80211_release_hw (struct ieee80211_local *local);int ieee80211_hw_config (struct ieee80211_local *local);
Quoted 6 lines · Ivo van Doorn
Most hardware can keep track of sequence numbers themselves, unfortunately *most* doesn't cover all devices. ;) This patch will keep track of the sequence number if the flag
IEEE80211_HW_SOFTWARE_SEQUENCEhas been set.Signed-off-by Ivo van Doorn <[email protected]>
Previous version had a small bug in it.
Signed-off-by Ivo van Doorn <[email protected]>
---
include/net/d80211.h +3 -0
@@ -534,6 +534,9 @@/* Does the device need the stack to create a RTS frame */ #define IEEE80211_HW_SOFTWARE_RTS (1<<15) +/* Does the HOST need to insert the frame sequence counter */ +#define IEEE80211_HW_SOFTWARE_SEQUENCE (1<<16) +u32 flags;/* hardware flags defined above */ /* Set to the size of a needed device specific skb headroom for TX skbs. */
net/d80211/ieee80211.c +20 -1
@@ -441,6 +441,7 @@size_t hdrlen, per_fragm, num_fragm, payload_len, left;struct sk_buff **frags, *first, *frag;int i; +u16 seq;u8 *pos;int frag_threshold = tx->local->fragmentation_threshold;
@@ -458,6 +459,7 @@if (!frags) goto fail; + seq =le16_to_cpu (hdr->seq_ctrl) &IEEE80211_SCTL_SEQ ; hdr->frame_control |=cpu_to_le16 (IEEE80211_FCTL_MOREFRAGS ); pos = first->data + hdrlen + per_fragm; left = payload_len - per_fragm;
@@ -486,7 +488,7 @@memcpy (fhdr, first->data, hdrlen);if (i == num_fragm -2 ) fhdr->frame_control &=cpu_to_le16 (~IEEE80211_FCTL_MOREFRAGS ); - fhdr->seq_ctrl =cpu_to_le16 (i +1 ); + fhdr->seq_ctrl =cpu_to_le16 (seq + ((i +1 ) &IEEE80211_SCTL_FRAG )); copylen = left > per_fragm ? per_fragm : left;memcpy (skb_put (frag, copylen), pos, copylen);
@@ -933,6 +935,17 @@return TXRX_CONTINUE ; } +static ieee80211_txrx_result +ieee80211_tx_h_sequence (struct ieee80211_txrx_data *tx) +{ +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; + +if ((tx->local->hw.flags &IEEE80211_HW_SOFTWARE_SEQUENCE ) && +ieee80211_get_hdrlen (le16_to_cpu (hdr->frame_control)) >24 ) +ieee80211_include_sequence (tx->local, hdr); + +return TXRX_CONTINUE ; +}/* This function is called whenever the AP is about to exceed the maximum limit * of buffered frames for power saving STAs. This situation should not really
@@ -1806,6 +1819,10 @@memcpy (skb_put (skb, bh_len), b_head, bh_len); +if (hw->flags &IEEE80211_HW_SOFTWARE_SEQUENCE ) +ieee80211_include_sequence (local, + (struct ieee80211_hdr *)skb->data); +ieee80211_beacon_add_tim (local, ap, skb);if (b_tail) {
@@ -4323,6 +4340,7 @@static ieee80211_tx_handler ieee80211_tx_handlers[] = { ieee80211_tx_h_check_assoc, + ieee80211_tx_h_sequence, ieee80211_tx_h_ps_buf, ieee80211_tx_h_select_key, ieee80211_tx_h_michael_mic_add,
@@ -4497,6 +4515,7 @@ local->bridge_packets =1 ; + local->seq_counter =0 ; local->rts_threshold =IEEE80211_MAX_RTS_THRESHOLD ; local->fragmentation_threshold =IEEE80211_MAX_FRAG_THRESHOLD ; local->short_retry_limit =7 ;
net/d80211/ieee80211_i.h +15 -0
@@ -405,6 +405,7 @@int *supp_rates[NUM_IEEE80211_MODES ];int *basic_rates[NUM_IEEE80211_MODES ]; +u16 seq_counter;int rts_threshold;int cts_protect_erp_frames;int fragmentation_threshold;
@@ -601,6 +602,20 @@spin_unlock_bh (&local->sta_lock); } +static inline void ieee80211_include_sequence (struct ieee80211_local *local, +struct ieee80211_hdr *hdr) +{ +/* +* Set the sequence number for this frame. +*/ + hdr->seq_ctrl =cpu_to_le16 (local->seq_counter &IEEE80211_SCTL_SEQ ); + +/* +* Increase the sequence number. +*/ + local->seq_counter = (local->seq_counter +0x10 ) &IEEE80211_SCTL_SEQ ; +} +/* ieee80211.c */ void ieee80211_release_hw (struct ieee80211_local *local);int ieee80211_hw_config (struct ieee80211_local *local);
net/d80211/ieee80211_i.h line 408
Quoted 7 lines · Ivo van Doorn
net/d80211/ieee80211_i.h +1
-0@@ -405,6 +405,7 @@int *supp_rates[NUM_IEEE80211_MODES ];int *basic_rates[NUM_IEEE80211_MODES ]; +u16 seq_counter;
Shouldn't this be per-BSS?
Jiri
Signature · 2 lines
Jiri Benc SUSE Labs
Quoted 10 lines · Jiri Benc
net/d80211/ieee80211_i.h line 408
Quoted 7 lines · Ivo van Doorn
net/d80211/ieee80211_i.h +1
-0@@ -405,6 +405,7 @@int *supp_rates[NUM_IEEE80211_MODES ];int *basic_rates[NUM_IEEE80211_MODES ]; +u16 seq_counter;Shouldn't this be per-BSS?
Ok I'll try to get a per-BSS sequence counter working, I'll need some time to figure out how the per-BSS code is working.
Ivo