Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 111722
b: refs/heads/master
c: 25d834e
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Sep 15, 2008
1 parent 9acaec5 commit 1c1a2a4
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 26 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: 9c31fd635ddfae6eb61712491770befa2ce1fdde
refs/heads/master: 25d834e16294c8dfd923dae6bdb8a055391a99a5
3 changes: 2 additions & 1 deletion trunk/drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)

txi = IEEE80211_SKB_CB(skb);

hwsim_check_magic(txi->control.vif);
if (txi->control.vif)
hwsim_check_magic(txi->control.vif);
if (txi->control.sta)
hwsim_check_sta_magic(txi->control.sta);

Expand Down
21 changes: 13 additions & 8 deletions trunk/drivers/net/wireless/rt2x00/rt2x00queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
struct ieee80211_rate *rate =
ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
Expand Down Expand Up @@ -278,16 +277,22 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* sequence counter given by mac80211.
*/
if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
spin_lock_irqsave(&intf->seqlock, irqflags);
if (likely(tx_info->control.vif)) {
struct rt2x00_intf *intf;

if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
intf->seqno += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
intf = vif_to_intf(tx_info->control.vif);

spin_unlock_irqrestore(&intf->seqlock, irqflags);
spin_lock_irqsave(&intf->seqlock, irqflags);

__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
intf->seqno += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(intf->seqno);

spin_unlock_irqrestore(&intf->seqlock, irqflags);

__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
}
}

/*
Expand Down
1 change: 1 addition & 0 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ struct ieee80211_tx_info {

union {
struct {
/* NB: vif can be NULL for injected frames */
struct ieee80211_vif *vif;
struct ieee80211_key_conf *hw_key;
struct ieee80211_sta *sta;
Expand Down
64 changes: 60 additions & 4 deletions trunk/net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,14 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
u8 *qc;
int tid;

/* only for injected frames */
/*
* Packet injection may want to control the sequence
* number, if we have no matching interface then we
* neither assign one ourselves nor ask the driver to.
*/
if (unlikely(!info->control.vif))
return TX_CONTINUE;

if (unlikely(ieee80211_is_ctl(hdr->frame_control)))
return TX_CONTINUE;

Expand Down Expand Up @@ -849,7 +856,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
sband = tx->local->hw.wiphy->bands[tx->channel->band];

skb->do_not_encrypt = 1;
info->flags |= IEEE80211_TX_CTL_INJECTED;
tx->flags &= ~IEEE80211_TX_FRAGMENTED;

/*
Expand Down Expand Up @@ -981,7 +987,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,

/* process and remove the injection radiotap header */
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP)
return TX_DROP;

Expand Down Expand Up @@ -1300,6 +1306,11 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
struct ieee80211_sub_if_data *osdata;
int headroom;
bool may_encrypt;
enum {
NOT_MONITOR,
FOUND_SDATA,
UNKNOWN_ADDRESS,
} monitor_iface = NOT_MONITOR;
int ret;

if (skb->iif)
Expand Down Expand Up @@ -1335,6 +1346,50 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
fwded_frames);
}
} else if (unlikely(osdata->vif.type == NL80211_IFTYPE_MONITOR)) {
struct ieee80211_sub_if_data *sdata;
struct ieee80211_local *local = osdata->local;
struct ieee80211_hdr *hdr;
int hdrlen;
u16 len_rthdr;

info->flags |= IEEE80211_TX_CTL_INJECTED;
monitor_iface = UNKNOWN_ADDRESS;

len_rthdr = ieee80211_get_radiotap_len(skb->data);
hdr = (struct ieee80211_hdr *)skb->data + len_rthdr;
hdrlen = ieee80211_hdrlen(hdr->frame_control);

/* check the header is complete in the frame */
if (likely(skb->len >= len_rthdr + hdrlen)) {
/*
* We process outgoing injected frames that have a
* local address we handle as though they are our
* own frames.
* This code here isn't entirely correct, the local
* MAC address is not necessarily enough to find
* the interface to use; for that proper VLAN/WDS
* support we will need a different mechanism.
*/

rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces,
list) {
if (!netif_running(sdata->dev))
continue;
if (compare_ether_addr(sdata->dev->dev_addr,
hdr->addr2)) {
dev_hold(sdata->dev);
dev_put(odev);
osdata = sdata;
odev = osdata->dev;
skb->iif = sdata->dev->ifindex;
monitor_iface = FOUND_SDATA;
break;
}
}
rcu_read_unlock();
}
}

may_encrypt = !skb->do_not_encrypt;
Expand All @@ -1355,7 +1410,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
osdata = container_of(osdata->bss,
struct ieee80211_sub_if_data,
u.ap);
info->control.vif = &osdata->vif;
if (likely(monitor_iface != UNKNOWN_ADDRESS))
info->control.vif = &osdata->vif;
ret = ieee80211_tx(odev, skb);
dev_put(odev);

Expand Down
37 changes: 25 additions & 12 deletions trunk/net/mac80211/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,16 +231,21 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
struct ieee80211_rate *rate)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_sub_if_data *sdata;
u16 dur;
int erp;
bool short_preamble = false;

erp = 0;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
if (vif) {
sdata = vif_to_sdata(vif);
short_preamble = sdata->bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
}

dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp,
sdata->bss_conf.use_short_preamble);
short_preamble);

return cpu_to_le16(dur);
}
Expand All @@ -252,21 +257,25 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_rate *rate;
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_sub_if_data *sdata;
bool short_preamble;
int erp;
u16 dur;
struct ieee80211_supported_band *sband;

sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

short_preamble = sdata->bss_conf.use_short_preamble;
short_preamble = false;

rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];

erp = 0;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
if (vif) {
sdata = vif_to_sdata(vif);
short_preamble = sdata->bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
}

/* CTS duration */
dur = ieee80211_frame_duration(local, 10, rate->bitrate,
Expand All @@ -289,20 +298,24 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_rate *rate;
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_sub_if_data *sdata;
bool short_preamble;
int erp;
u16 dur;
struct ieee80211_supported_band *sband;

sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

short_preamble = sdata->bss_conf.use_short_preamble;
short_preamble = false;

rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
erp = 0;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
if (vif) {
sdata = vif_to_sdata(vif);
short_preamble = sdata->bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
}

/* Data frame duration */
dur = ieee80211_frame_duration(local, frame_len, rate->bitrate,
Expand Down

0 comments on commit 1c1a2a4

Please sign in to comment.