Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 266757
b: refs/heads/master
c: a2fe816
h: refs/heads/master
i:
  266755: 0da3282
v: v3
  • Loading branch information
Helmut Schaa authored and John W. Linville committed Oct 14, 2011
1 parent 0ef6bd2 commit 28a1372
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7bd9897e1a07d97e6297f38f741e2d1851e243b8
refs/heads/master: a2fe81667410723d941a688e1958a49d67ca3346
12 changes: 0 additions & 12 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -1177,18 +1177,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev);

/*
* radiotap header for status frames
*/
struct ieee80211_tx_status_rtap_hdr {
struct ieee80211_radiotap_header hdr;
u8 rate;
u8 padding_for_rate;
__le16 tx_flags;
u8 data_retries;
} __packed;


/* HT */
void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
struct ieee80211_ht_cap *ht_cap_ie,
Expand Down
6 changes: 1 addition & 5 deletions trunk/net/mac80211/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,12 +904,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
* and we need some headroom for passing the frame to monitor
* interfaces, but never both at the same time.
*/
#ifndef __CHECKER__
BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM !=
sizeof(struct ieee80211_tx_status_rtap_hdr));
#endif
local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
sizeof(struct ieee80211_tx_status_rtap_hdr));
IEEE80211_TX_STATUS_HEADROOM);

debugfs_hw_add(local);

Expand Down
112 changes: 77 additions & 35 deletions trunk/net/mac80211/status.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,79 @@ static void ieee80211_set_bar_pending(struct sta_info *sta, u8 tid, u16 ssn)
tid_tx->bar_pending = true;
}

static int ieee80211_tx_radiotap_len(struct ieee80211_tx_info *info)
{
int len = sizeof(struct ieee80211_radiotap_header);

/* IEEE80211_RADIOTAP_RATE rate */
if (info->status.rates[0].idx >= 0 &&
!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS))
len += 2;

/* IEEE80211_RADIOTAP_TX_FLAGS */
len += 2;

/* IEEE80211_RADIOTAP_DATA_RETRIES */
len += 1;

return len;
}

static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
*sband, struct sk_buff *skb,
int retry_count, int rtap_len)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_radiotap_header *rthdr;
unsigned char *pos;
__le16 txflags;

rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len);

memset(rthdr, 0, rtap_len);
rthdr->it_len = cpu_to_le16(rtap_len);
rthdr->it_present =
cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
(1 << IEEE80211_RADIOTAP_DATA_RETRIES));
pos = (unsigned char *)(rthdr + 1);

/*
* XXX: Once radiotap gets the bitmap reset thing the vendor
* extensions proposal contains, we can actually report
* the whole set of tries we did.
*/

/* IEEE80211_RADIOTAP_RATE */
if (info->status.rates[0].idx >= 0 &&
!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) {
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
*pos = sband->bitrates[info->status.rates[0].idx].bitrate / 5;
/* padding for tx flags */
pos += 2;
}

/* IEEE80211_RADIOTAP_TX_FLAGS */
txflags = 0;
if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
!is_multicast_ether_addr(hdr->addr1))
txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);

if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
(info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);

put_unaligned_le16(txflags, pos);
pos += 2;

/* IEEE80211_RADIOTAP_DATA_RETRIES */
/* for now report the total retry_count */
*pos = retry_count;
pos++;
}

/*
* Use a static threshold for now, best value to be determined
* by testing ...
Expand All @@ -246,7 +319,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
u16 frag, type;
__le16 fc;
struct ieee80211_supported_band *sband;
struct ieee80211_tx_status_rtap_hdr *rthdr;
struct ieee80211_sub_if_data *sdata;
struct net_device *prev_dev = NULL;
struct sta_info *sta, *tmp;
Expand All @@ -256,6 +328,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
bool acked;
struct ieee80211_bar *bar;
u16 tid;
int rtap_len;

for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
if (info->status.rates[i].idx < 0) {
Expand Down Expand Up @@ -460,44 +533,13 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
}

/* send frame to monitor interfaces now */

if (skb_headroom(skb) < sizeof(*rthdr)) {
rtap_len = ieee80211_tx_radiotap_len(info);
if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
printk(KERN_ERR "ieee80211_tx_status: headroom too small\n");
dev_kfree_skb(skb);
return;
}

rthdr = (struct ieee80211_tx_status_rtap_hdr *)
skb_push(skb, sizeof(*rthdr));

memset(rthdr, 0, sizeof(*rthdr));
rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
rthdr->hdr.it_present =
cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
(1 << IEEE80211_RADIOTAP_DATA_RETRIES) |
(1 << IEEE80211_RADIOTAP_RATE));

if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
!is_multicast_ether_addr(hdr->addr1))
rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);

/*
* XXX: Once radiotap gets the bitmap reset thing the vendor
* extensions proposal contains, we can actually report
* the whole set of tries we did.
*/
if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
(info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
if (info->status.rates[0].idx >= 0 &&
!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS))
rthdr->rate = sband->bitrates[
info->status.rates[0].idx].bitrate / 5;

/* for now report the total retry_count */
rthdr->data_retries = retry_count;
ieee80211_add_tx_radiotap_header(sband, skb, retry_count, rtap_len);

/* XXX: is this sufficient for BPF? */
skb_set_mac_header(skb, 0);
Expand Down

0 comments on commit 28a1372

Please sign in to comment.