Search Linux Wireless

putting ieee80211_tx_control into skb->cb?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



With my patch to shrink ieee80211_tx_control, I can now put that into
skb->cb.

Do we want to use that as the interface to drivers as well? Many drivers
could benefit from that a lot since we could save all the extra copies
done here.

I've grepped all drivers, currently those using skb->cb are:
 * p54:     only needs 8 bytes
 * rt2x00:  needs almost all the space (40 bytes)
 * adm8211: puts the 802.11 header there
 * rtl8180: needs a single pointer to control
 * rtl8187: usb urb, control and hw pointers
 * zd1211:  control, hw and context pointers

Notice how four drivers here put the control information in there, which
needs to be copied by drivers. However, mac80211 only needs the control
flags later!

Additionally, mac80211 needs to copy the TX status information around a
lot when the irqsafe functions are used. That's also bad.

What we could do is this:

First, we put ieee80211_tx_control into skb->cb. The first member of
that is a 'u32 flags' which is the only thing we need later for TX
status reporting, so we require that drivers leave that in there.

Then, we merge the TX status flags into the TX flags so that now the
driver only needs to set a few flags in skb->cb. Also, we overlay this.

Hence, we have something like the following structure:

struct ieee80211_tx_information {
    u32 flags;

    union {
        struct {
            s8 tx_rate_idx, rts_cts_rate_idx,
               alt_retry_rate_idx, retry_limit;
            struct ieee80211_vif *vif;
            struct ieee80211_key_conf *hw_key;
            enum ieee80211_band band;
            u16 aid;
            u8 antenna_sel_tx;
            u8 icv_len, iv_len;
        } txctl;

        struct {
            u64 amdpu_ack_map;
            int ack_signal;
            u8 ampdu_ack_len;
            bool excessive_retries; /* should be a flag / removed */
            u8 retry_count;
        } status;

        /* can be used freely by driver after its ops->tx() accepts
         * the frame and before tx status reporting */
        u8 drv_data[40] __attribute__((__aligned__(sizeof(void *)));
    };
};

This means that the drivers are free to use everything in skb->cb for
their own use but should leave the 'u32 flags' intact, and need to make
sure to copy out all the information they need before putting in new
information. This fits with all the drivers, rt2x00 needs at most 32
bytes (40 now, but one is the txcontrol pointer) while we have 44 free.
Also, if the driver rejects the skb in ops->tx(), it must not have
modified skb->cb.

The only thing I'm not sure yet is how to handle alignment here. skb->cb
itself is 8-byte aligned so we probably need to reserve another four
bytes to get things to 8-byte alignment and then we go down to 40
available bytes, this is what I did above.

Thoughts?

johannes

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux