Commit 90218467 authored by Michael Wu's avatar Michael Wu Committed by Greg Kroah-Hartman

rtl8187: Fix more frag bit checking, rts duration calc

patch 98798f48 in mainline.

The wrong pointer is passed to ieee80211_get_morefrag. Fix this.

While we're at it, reorder things so they look better and the rts duration
calculation is done with the right length.

Thanks to Christoph Hellwig for finding the ieee80211_get_morefrag issue.
Signed-off-by: default avatarMichael Wu <flamingice@sourmilk.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent b6060c05
...@@ -78,7 +78,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -78,7 +78,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
struct rtl8187_tx_hdr *hdr; struct rtl8187_tx_hdr *hdr;
struct rtl8187_tx_info *info; struct rtl8187_tx_info *info;
struct urb *urb; struct urb *urb;
u32 tmp; __le16 rts_dur = 0;
u32 flags;
urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) { if (!urb) {
...@@ -86,24 +87,24 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -86,24 +87,24 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
return 0; return 0;
} }
hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); flags = skb->len;
tmp = skb->len - sizeof(*hdr); flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
tmp |= RTL8187_TX_FLAG_NO_ENCRYPT; flags |= control->rts_cts_rate << 19;
tmp |= control->rts_cts_rate << 19; flags |= control->tx_rate << 24;
tmp |= control->tx_rate << 24; if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb)) flags |= RTL8187_TX_FLAG_MORE_FRAG;
tmp |= RTL8187_TX_FLAG_MORE_FRAG;
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
tmp |= RTL8187_TX_FLAG_RTS; flags |= RTL8187_TX_FLAG_RTS;
hdr->rts_duration = rts_dur = ieee80211_rts_duration(dev, skb->len, control);
ieee80211_rts_duration(dev, skb->len, control);
} }
if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
tmp |= RTL8187_TX_FLAG_CTS; flags |= RTL8187_TX_FLAG_CTS;
hdr->flags = cpu_to_le32(tmp);
hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
hdr->flags = cpu_to_le32(flags);
hdr->len = 0; hdr->len = 0;
tmp = control->retry_limit << 8; hdr->rts_duration = rts_dur;
hdr->retry = cpu_to_le32(tmp); hdr->retry = cpu_to_le32(control->retry_limit << 8);
info = (struct rtl8187_tx_info *)skb->cb; info = (struct rtl8187_tx_info *)skb->cb;
info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC); info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment