mac80211: provide sequence numbers
authorJohannes Berg <johannes@sipsolutions.net>
Fri, 10 Oct 2008 11:21:59 +0000 (13:21 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 31 Oct 2008 23:00:12 +0000 (19:00 -0400)
I've come to think that not providing sequence numbers for
the normal STA mode case was a mistake, at least two drivers
now had to implement code they wouldn't otherwise need, and
I believe at76_usb and adm8211 might be broken.

This patch makes mac80211 assign a sequence number to all
those frames that need one except beacons. That means that
if a driver only implements modes that do not do beaconing
it need not worry about the sequence number.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/rtl8187.h
drivers/net/wireless/rtl8187_dev.c
net/mac80211/ieee80211_i.h
net/mac80211/tx.c

index 8da4d30..1da96fe 100644 (file)
@@ -67,7 +67,6 @@ struct p54_common {
        int (*open)(struct ieee80211_hw *dev);
        void (*stop)(struct ieee80211_hw *dev);
        int mode;
-       u16 seqno;
        u16 rx_mtu;
        u8 headroom;
        u8 tailroom;
index f8cdd88..7c37d3f 100644 (file)
@@ -856,19 +856,6 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        if (padding)
                txhdr->align[0] = padding;
 
-       /* FIXME: The sequence that follows is needed for this driver to
-        * work with mac80211 since "mac80211: fix TX sequence numbers".
-        * As with the temporary code in rt2x00, changes will be needed
-        * to get proper sequence numbers on beacons. In addition, this
-        * patch places the sequence number in the hardware state, which
-        * limits us to a single virtual state.
-        */
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-                       priv->seqno += 0x10;
-               ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
-       }
        /* modifies skb->cb and with it info, so must be last! */
        p54_assign_address(dev, skb, hdr, skb->len);
 
@@ -1392,6 +1379,11 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
                     IEEE80211_HW_SIGNAL_DBM |
                     IEEE80211_HW_NOISE_DBM;
 
+       /*
+        * XXX: when this driver gets support for any mode that
+        *      requires beacons (AP, MESH, IBSS) then it must
+        *      implement IEEE80211_TX_CTL_ASSIGN_SEQ.
+        */
        dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 
        dev->channel_change_time = 1000;        /* TODO: find actual value */
index e82bb4d..33725d0 100644 (file)
@@ -100,7 +100,6 @@ struct rtl8187_priv {
        struct usb_device *udev;
        u32 rx_conf;
        u16 txpwr_base;
-       u16 seqno;
        u8 asic_rev;
        u8 is_rtl8187b;
        enum {
index 2c69ab3..16f2fe2 100644 (file)
@@ -241,20 +241,6 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
                        ep = epmap[skb_get_queue_mapping(skb)];
        }
 
-       /* FIXME: The sequence that follows is needed for this driver to
-        * work with mac80211 since "mac80211: fix TX sequence numbers".
-        * As with the temporary code in rt2x00, changes will be needed
-        * to get proper sequence numbers on beacons. In addition, this
-        * patch places the sequence number in the hardware state, which
-        * limits us to a single virtual state.
-        */
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-                       priv->seqno += 0x10;
-               ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
-       }
-
        info->driver_data[0] = dev;
        info->driver_data[1] = urb;
 
@@ -1187,6 +1173,10 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
                dev->max_signal = 65;
        }
 
+       /*
+        * XXX: Once this driver supports anything that requires
+        *      beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
+        */
        dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 
        if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
index 1deb787..8198447 100644 (file)
@@ -438,6 +438,8 @@ struct ieee80211_sub_if_data {
        struct ieee80211_key *keys[NUM_DEFAULT_KEYS];
        struct ieee80211_key *default_key;
 
+       u16 sequence_number;
+
        /* BSS configuration for this interface. */
        struct ieee80211_bss_conf bss_conf;
 
index 22494bc..8bcabef 100644 (file)
@@ -600,8 +600,18 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
        if (ieee80211_hdrlen(hdr->frame_control) < 24)
                return TX_CONTINUE;
 
+       /*
+        * Anything but QoS data that has a sequence number field
+        * (is long enough) gets a sequence number from the global
+        * counter.
+        */
        if (!ieee80211_is_data_qos(hdr->frame_control)) {
+               /* driver should assign sequence number */
                info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
+               /* for pure STA mode without beacons, we can do it */
+               hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number);
+               tx->sdata->sequence_number += 0x10;
+               tx->sdata->sequence_number &= IEEE80211_SCTL_SEQ;
                return TX_CONTINUE;
        }