[rt2x00-users] [RFC] rt2800usb: remove usb pad after transmission

Helmut Schaa helmut.schaa at googlemail.com
Mon Dec 19 19:33:59 EST 2011


Hi Jakub,

On Sat, Dec 17, 2011 at 11:47 PM, Jakub Kicinski <kubakici at wp.pl> wrote:
> rt2800usb appends certain pad to frames before they are transferred
> to HW. This pad should be removed once the frame is transmitted
> and before skb is handed back to mac80211.
>
> I send this as RFC because I'm not sure whether you agree with my
> approach. IMHO saving pad length in queue entry will be a cleaner
> solution than calculating actual length of frame from descriptor
> fields.

I agree that this should be fixed since mac80211 might retransmit the
frame for example. And that will then contain the padding in the
payload ...

However, see my inline comments.

> Signed-off-by: Jakub Kicinski <kubakici at wp.pl>
> ---
>  drivers/net/wireless/rt2x00/rt2800usb.c |   17 +++++++++++++++--
>  drivers/net/wireless/rt2x00/rt2800usb.h |   11 +++++++++++
>  2 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
> index 3778763..e8bd429 100644
> --- a/drivers/net/wireless/rt2x00/rt2800usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2800usb.c
> @@ -424,6 +424,7 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
>  static void rt2800usb_write_tx_data(struct queue_entry *entry,
>                                        struct txentry_desc *txdesc)
>  {
> +       struct rt2800usb_tx_queue_entry_priv *entry_priv = entry->priv_data;
>        unsigned int len;
>        int err;
>
> @@ -437,6 +438,7 @@ static void rt2800usb_write_tx_data(struct queue_entry *entry,
>         *                 |<------------- tx_pkt_len ------------->|
>         */
>        len = roundup(entry->skb->len, 4) + 4;
> +       entry_priv->usb_pad = len - entry->skb->len;
>        err = skb_padto(entry->skb, len);
>        if (unlikely(err)) {
>                WARNING(entry->queue->rt2x00dev, "TX SKB padding error, out of memory\n");
> @@ -509,6 +511,13 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
>        return true;
>  }
>
> +static void rt2800usb_remove_usb_pad(struct queue_entry *entry)
> +{
> +       struct rt2800usb_tx_queue_entry_priv *entry_priv = entry->priv_data;
> +
> +       skb_trim(entry->skb, entry->skb->len - entry_priv->usb_pad);

Might make sense to add a check for (entry_priv->usb_pad <
entry->skb->len) here.

> +}
> +
>  static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
>  {
>        struct data_queue *queue;
> @@ -541,9 +550,13 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
>                        entry = NULL;
>                }
>
> -               if (entry)
> +               if (entry) {
> +                       if (qid != QID_BEACON)
> +                               rt2800usb_remove_usb_pad(entry);
> +
>                        rt2800_txdone_entry(entry, reg,
>                                            rt2800usb_get_txwi(entry));
> +               }
>        }
>  }
>
> @@ -834,7 +847,7 @@ static const struct data_queue_desc rt2800usb_queue_tx = {
>        .entry_num              = 64,
>        .data_size              = AGGREGATION_SIZE,
>        .desc_size              = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
> -       .priv_size              = sizeof(struct queue_entry_priv_usb),
> +       .priv_size              = sizeof(struct rt2800usb_tx_queue_entry_priv),
>  };
>
>  static const struct data_queue_desc rt2800usb_queue_bcn = {
> diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
> index 671ea35..75eb5fb 100644
> --- a/drivers/net/wireless/rt2x00/rt2800usb.h
> +++ b/drivers/net/wireless/rt2x00/rt2800usb.h
> @@ -37,6 +37,17 @@
>  #define FIRMWARE_RT2870                        "rt2870.bin"
>  #define FIRMWARE_IMAGE_BASE            0x3000
>
> +/*
> + * rt2800usb TX queue specific entry
> + *
> + * usb_priv: Per entry USB specific information
> + * usb_pad: Length of pad appended to frame
> + */
> +struct rt2800usb_tx_queue_entry_priv {
> +       struct queue_entry_priv_usb usb_priv;
> +       u8 usb_pad;

Any special reason for using an u8?

Isnt't entry->priv_data also used in the generic rt2x00 USB parts (rt2x00usb.c)
but casted to queue_entry_priv_usb. So this needs a comment why it doesn't
break the generic USB routines ...

Helmut



More information about the users mailing list