#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/bitmap.h>
+#include <linux/rcupdate.h>
+#include <net/net_namespace.h>
#include <net/ieee80211_radiotap.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
u16 fc;
int hdrlen;
+ DECLARE_MAC_BUF(mac);
printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len);
if (skb->len < 4) {
printk(" FC=0x%04x DUR=0x%04x",
fc, le16_to_cpu(hdr->duration_id));
if (hdrlen >= 10)
- printk(" A1=" MAC_FMT, MAC_ARG(hdr->addr1));
+ printk(" A1=%s", print_mac(mac, hdr->addr1));
if (hdrlen >= 16)
- printk(" A2=" MAC_FMT, MAC_ARG(hdr->addr2));
+ printk(" A2=%s", print_mac(mac, hdr->addr2));
if (hdrlen >= 24)
- printk(" A3=" MAC_FMT, MAC_ARG(hdr->addr3));
+ printk(" A3=%s", print_mac(mac, hdr->addr3));
if (hdrlen >= 30)
- printk(" A4=" MAC_FMT, MAC_ARG(hdr->addr4));
+ printk(" A4=%s", print_mac(mac, hdr->addr4));
printk("\n");
}
#else /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */
* to closest integer */
dur = ieee80211_frame_duration(local, 10, rate, erp,
- tx->sdata->short_preamble);
+ tx->sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE);
if (next_frag_len) {
/* Frame is fragmented: duration increases with time needed to
dur *= 2; /* ACK + SIFS */
/* next fragment */
dur += ieee80211_frame_duration(local, next_frag_len,
- txrate->rate, erp,
- tx->sdata->short_preamble);
+ txrate->rate, erp,
+ tx->sdata->flags &
+ IEEE80211_SDATA_SHORT_PREAMBLE);
}
return dur;
(tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))
return TXRX_DROP;
- if (tx->u.tx.ps_buffered)
+ if (tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED)
return TXRX_CONTINUE;
sta_flags = tx->sta ? tx->sta->flags : 0;
- if (likely(tx->u.tx.unicast)) {
+ if (likely(tx->flags & IEEE80211_TXRXD_TXUNICAST)) {
if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
tx->sdata->type != IEEE80211_IF_TYPE_IBSS &&
(tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ DECLARE_MAC_BUF(mac);
printk(KERN_DEBUG "%s: dropped data frame to not "
- "associated station " MAC_FMT "\n",
- tx->dev->name, MAC_ARG(hdr->addr1));
+ "associated station %s\n",
+ tx->dev->name, print_mac(mac, hdr->addr1));
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc);
return TXRX_DROP;
} else {
if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
tx->local->num_sta == 0 &&
- !tx->local->allow_broadcast_always &&
tx->sdata->type != IEEE80211_IF_TYPE_IBSS)) {
/*
* No associated STAs - no need to send multicast
if (unlikely(!tx->u.tx.mgmt_interface && tx->sdata->ieee802_1x &&
!(sta_flags & WLAN_STA_AUTHORIZED))) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: dropped frame to " MAC_FMT
+ DECLARE_MAC_BUF(mac);
+ printk(KERN_DEBUG "%s: dropped frame to %s"
" (unauthorized port)\n", tx->dev->name,
- MAC_ARG(hdr->addr1));
+ print_mac(mac, hdr->addr1));
#endif
I802_DEBUG_INC(tx->local->tx_handlers_drop_unauth_port);
return TXRX_DROP;
ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
{
struct sta_info *sta = tx->sta;
+ DECLARE_MAC_BUF(mac);
if (unlikely(!sta ||
((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT &&
if (unlikely((sta->flags & WLAN_STA_PS) && !sta->pspoll)) {
struct ieee80211_tx_packet_data *pkt_data;
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
- printk(KERN_DEBUG "STA " MAC_FMT " aid %d: PS buffer (entries "
+ printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries "
"before %d)\n",
- MAC_ARG(sta->addr), sta->aid,
+ print_mac(mac, sta->addr), sta->aid,
skb_queue_len(&sta->ps_tx_buf));
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
sta->flags |= WLAN_STA_TIM;
if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) {
struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf);
if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: STA " MAC_FMT " TX "
+ printk(KERN_DEBUG "%s: STA %s TX "
"buffer full - dropping oldest frame\n",
- tx->dev->name, MAC_ARG(sta->addr));
+ tx->dev->name, print_mac(mac, sta->addr));
}
dev_kfree_skb(old);
} else
}
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
else if (unlikely(sta->flags & WLAN_STA_PS)) {
- printk(KERN_DEBUG "%s: STA " MAC_FMT " in PS mode, but pspoll "
+ printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll "
"set -> send frame\n", tx->dev->name,
- MAC_ARG(sta->addr));
+ print_mac(mac, sta->addr));
}
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
sta->pspoll = 0;
static ieee80211_txrx_result
ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
{
- if (unlikely(tx->u.tx.ps_buffered))
+ if (unlikely(tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED))
return TXRX_CONTINUE;
- if (tx->u.tx.unicast)
+ if (tx->flags & IEEE80211_TXRXD_TXUNICAST)
return ieee80211_tx_h_unicast_ps_buf(tx);
else
return ieee80211_tx_h_multicast_ps_buf(tx);
static ieee80211_txrx_result
ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
{
- if (tx->sta)
- tx->u.tx.control->key_idx = tx->sta->key_idx_compression;
- else
- tx->u.tx.control->key_idx = HW_KEY_IDX_INVALID;
+ struct ieee80211_key *key;
if (unlikely(tx->u.tx.control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
tx->key = NULL;
- else if (tx->sta && tx->sta->key)
- tx->key = tx->sta->key;
- else if (tx->sdata->default_key)
- tx->key = tx->sdata->default_key;
+ else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
+ tx->key = key;
+ else if ((key = rcu_dereference(tx->sdata->default_key)))
+ tx->key = key;
else if (tx->sdata->drop_unencrypted &&
!(tx->sdata->eapol && ieee80211_is_eapol(tx->skb))) {
I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
return TXRX_DROP;
- } else
+ } else {
tx->key = NULL;
+ tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
+ }
if (tx->key) {
tx->key->tx_rx_count++;
u8 *pos;
int frag_threshold = tx->local->fragmentation_threshold;
- if (!tx->fragmented)
+ if (!(tx->flags & IEEE80211_TXRXD_FRAGMENTED))
return TXRX_CONTINUE;
first = tx->skb;
hdrlen = ieee80211_get_hdrlen(tx->fc);
payload_len = first->len - hdrlen;
per_fragm = frag_threshold - hdrlen - FCS_LEN;
- num_fragm = (payload_len + per_fragm - 1) / per_fragm;
+ num_fragm = DIV_ROUND_UP(payload_len, per_fragm);
frags = kzalloc(num_fragm * sizeof(struct sk_buff *), GFP_ATOMIC);
if (!frags)
static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
{
- if (tx->key->force_sw_encrypt) {
+ if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
return -1;
} else {
- tx->u.tx.control->key_idx = tx->key->hw_key_idx;
- if (tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
- if (ieee80211_wep_add_iv(tx->local, skb, tx->key) ==
- NULL)
+ tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
+ if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
+ if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
return -1;
}
}
fc = le16_to_cpu(hdr->frame_control);
- if (!tx->key || tx->key->alg != ALG_WEP ||
+ if (!tx->key || tx->key->conf.alg != ALG_WEP ||
((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
(fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
&extra);
if (unlikely(extra.probe != NULL)) {
tx->u.tx.control->flags |= IEEE80211_TXCTL_RATE_CTRL_PROBE;
- tx->u.tx.probe_last_frag = 1;
+ tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val;
tx->u.tx.rate = extra.probe;
} else {
if (!tx->u.tx.rate)
return TXRX_DROP;
if (tx->u.tx.mode->mode == MODE_IEEE80211G &&
- tx->sdata->use_protection && tx->fragmented &&
- extra.nonerp) {
+ (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) &&
+ (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && extra.nonerp) {
tx->u.tx.last_frag_rate = tx->u.tx.rate;
- tx->u.tx.probe_last_frag = extra.probe ? 1 : 0;
-
+ if (extra.probe)
+ tx->flags &= ~IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
+ else
+ tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
tx->u.tx.rate = extra.nonerp;
tx->u.tx.control->rate = extra.nonerp;
tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
control->retry_limit = 1;
}
- if (tx->fragmented) {
+ if (tx->flags & IEEE80211_TXRXD_FRAGMENTED) {
/* Do not use multiple retry rates when sending fragmented
* frames.
* TODO: The last fragment could still use multiple retry
* for the frame. */
if (mode->mode == MODE_IEEE80211G &&
(tx->u.tx.rate->flags & IEEE80211_RATE_ERP) &&
- tx->u.tx.unicast && tx->sdata->use_protection &&
+ (tx->flags & IEEE80211_TXRXD_TXUNICAST) &&
+ (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) &&
!(control->flags & IEEE80211_TXCTL_USE_RTS_CTS))
control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT;
* available on the network at the current point in time. */
if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
(tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) &&
- tx->sdata->short_preamble &&
+ (tx->sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
(!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) {
tx->u.tx.control->tx_rate = tx->u.tx.rate->val2;
}
* for remaining fragments will be updated when they are being sent
* to low-level driver in ieee80211_tx(). */
dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1),
- tx->fragmented ? tx->u.tx.extra_frag[0]->len :
- 0);
+ (tx->flags & IEEE80211_TXRXD_FRAGMENTED) ?
+ tx->u.tx.extra_frag[0]->len : 0);
hdr->duration_id = cpu_to_le16(dur);
if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
}
}
+ /*
+ * Tell hardware to not encrypt when we had sw crypto.
+ * Because we use the same flag to internally indicate that
+ * no (software) encryption should be done, we have to set it
+ * after all crypto handlers.
+ */
+ if (tx->key && !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
+ tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
+
return TXRX_CONTINUE;
}
* 1 usec = 1/8 * (1080 / 10) = 13.5 */
if (mode->mode == MODE_IEEE80211A ||
- mode->mode == MODE_ATHEROS_TURBO ||
- mode->mode == MODE_ATHEROS_TURBOG ||
(mode->mode == MODE_IEEE80211G &&
tx->u.tx.rate->flags & IEEE80211_RATE_ERP))
hdrtime = CHAN_UTIL_HDR_SHORT;
*/
control->retry_limit = 1; /* no retry */
- control->key_idx = -1; /* no encryption key */
control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
IEEE80211_TXCTL_USE_CTS_PROTECT);
control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT |
tx->dev = dev; /* use original interface */
tx->local = local;
tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- tx->sta = sta_info_get(local, hdr->addr1);
- tx->fc = le16_to_cpu(hdr->frame_control);
/*
* set defaults for things that can be set by
*/
control->power_level = local->hw.conf.power_level;
control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
- if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta)
- control->antenna_sel_tx = tx->sta->antenna_sel_tx;
/* process and remove the injection radiotap header */
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
res = TXRX_QUEUED; /* indication it was monitor packet */
}
+ tx->sta = sta_info_get(local, hdr->addr1);
+ tx->fc = le16_to_cpu(hdr->frame_control);
tx->u.tx.control = control;
- tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1);
- if (is_multicast_ether_addr(hdr->addr1))
+ if (is_multicast_ether_addr(hdr->addr1)) {
+ tx->flags &= ~IEEE80211_TXRXD_TXUNICAST;
control->flags |= IEEE80211_TXCTL_NO_ACK;
- else
+ } else {
+ tx->flags |= IEEE80211_TXRXD_TXUNICAST;
control->flags &= ~IEEE80211_TXCTL_NO_ACK;
- tx->fragmented = local->fragmentation_threshold <
- IEEE80211_MAX_FRAG_THRESHOLD && tx->u.tx.unicast &&
- skb->len + FCS_LEN > local->fragmentation_threshold &&
- (!local->ops->set_frag_threshold);
+ }
+ if (local->fragmentation_threshold < IEEE80211_MAX_FRAG_THRESHOLD &&
+ (tx->flags & IEEE80211_TXRXD_TXUNICAST) &&
+ skb->len + FCS_LEN > local->fragmentation_threshold &&
+ !local->ops->set_frag_threshold)
+ tx->flags |= IEEE80211_TXRXD_FRAGMENTED;
+ else
+ tx->flags &= ~IEEE80211_TXRXD_FRAGMENTED;
if (!tx->sta)
control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK;
else if (tx->sta->clear_dst_mask) {
struct net_device *dev;
pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
- dev = dev_get_by_index(pkt_data->ifindex);
+ dev = dev_get_by_index(&init_net, pkt_data->ifindex);
if (unlikely(dev && !is_ieee80211_device(dev, mdev))) {
dev_put(dev);
dev = NULL;
if (i == tx->u.tx.num_extra_frag) {
control->tx_rate = tx->u.tx.last_frag_hwrate;
control->rate = tx->u.tx.last_frag_rate;
- if (tx->u.tx.probe_last_frag)
+ if (tx->flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG)
control->flags |=
IEEE80211_TXCTL_RATE_CTRL_PROBE;
else
return 0;
}
+ /*
+ * key references are protected using RCU and this requires that
+ * we are in a read-site RCU section during receive processing
+ */
+ rcu_read_lock();
+
sta = tx.sta;
tx.u.tx.mgmt_interface = mgmt;
tx.u.tx.mode = local->hw.conf.mode;
if (unlikely(res == TXRX_QUEUED)) {
I802_DEBUG_INC(local->tx_handlers_queued);
+ rcu_read_unlock();
return 0;
}
store->num_extra_frag = tx.u.tx.num_extra_frag;
store->last_frag_hwrate = tx.u.tx.last_frag_hwrate;
store->last_frag_rate = tx.u.tx.last_frag_rate;
- store->last_frag_rate_ctrl_probe = tx.u.tx.probe_last_frag;
+ store->last_frag_rate_ctrl_probe =
+ !!(tx.flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG);
}
+ rcu_read_unlock();
return 0;
drop:
if (tx.u.tx.extra_frag[i])
dev_kfree_skb(tx.u.tx.extra_frag[i]);
kfree(tx.u.tx.extra_frag);
+ rcu_read_unlock();
return 0;
}
memset(&control, 0, sizeof(struct ieee80211_tx_control));
if (pkt_data->ifindex)
- odev = dev_get_by_index(pkt_data->ifindex);
+ odev = dev_get_by_index(&init_net, pkt_data->ifindex);
if (unlikely(odev && !is_ieee80211_device(odev, dev))) {
dev_put(odev);
odev = NULL;
control.ifindex = odev->ifindex;
control.type = osdata->type;
- if (pkt_data->req_tx_status)
+ if (pkt_data->flags & IEEE80211_TXPD_REQ_TX_STATUS)
control.flags |= IEEE80211_TXCTL_REQ_TX_STATUS;
- if (pkt_data->do_not_encrypt)
+ if (pkt_data->flags & IEEE80211_TXPD_DO_NOT_ENCRYPT)
control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
- if (pkt_data->requeue)
+ if (pkt_data->flags & IEEE80211_TXPD_REQUEUE)
control.flags |= IEEE80211_TXCTL_REQUEUE;
control.queue = pkt_data->queue;
/* needed because we set skb device to master */
pkt_data->ifindex = dev->ifindex;
- pkt_data->mgmt_iface = 0;
- pkt_data->do_not_encrypt = 1;
+ pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
/*
* fix up the pointers accounting for the radiotap
struct ieee80211_hdr hdr;
const u8 *encaps_data;
int encaps_len, skip_header_bytes;
- int nh_pos, h_pos, no_encrypt = 0;
+ int nh_pos, h_pos;
struct sta_info *sta;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
/* TODO: handling for 802.1x authorized/unauthorized port */
fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
- if (likely(sdata->type == IEEE80211_IF_TYPE_AP ||
- sdata->type == IEEE80211_IF_TYPE_VLAN)) {
+ switch (sdata->type) {
+ case IEEE80211_IF_TYPE_AP:
+ case IEEE80211_IF_TYPE_VLAN:
fc |= IEEE80211_FCTL_FROMDS;
/* DA BSSID SA */
memcpy(hdr.addr1, skb->data, ETH_ALEN);
memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
hdrlen = 24;
- } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
+ break;
+ case IEEE80211_IF_TYPE_WDS:
fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS;
/* RA TA DA SA */
memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN);
memcpy(hdr.addr3, skb->data, ETH_ALEN);
memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
hdrlen = 30;
- } else if (sdata->type == IEEE80211_IF_TYPE_STA) {
+ break;
+ case IEEE80211_IF_TYPE_STA:
fc |= IEEE80211_FCTL_TODS;
/* BSSID SA DA */
memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN);
memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
memcpy(hdr.addr3, skb->data, ETH_ALEN);
hdrlen = 24;
- } else if (sdata->type == IEEE80211_IF_TYPE_IBSS) {
+ break;
+ case IEEE80211_IF_TYPE_IBSS:
/* DA SA BSSID */
memcpy(hdr.addr1, skb->data, ETH_ALEN);
memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
memcpy(hdr.addr3, sdata->u.sta.bssid, ETH_ALEN);
hdrlen = 24;
- } else {
+ break;
+ default:
ret = 0;
goto fail;
}
nh_pos += encaps_len;
h_pos += encaps_len;
}
- memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
+
+ if (fc & IEEE80211_STYPE_QOS_DATA) {
+ __le16 *qos_control;
+
+ qos_control = (__le16*) skb_push(skb, 2);
+ memcpy(skb_push(skb, hdrlen - 2), &hdr, hdrlen - 2);
+ /*
+ * Maybe we could actually set some fields here, for now just
+ * initialise to zero to indicate no special operation.
+ */
+ *qos_control = 0;
+ } else
+ memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
+
nh_pos += hdrlen;
h_pos += hdrlen;
pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
pkt_data->ifindex = dev->ifindex;
- pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
- pkt_data->do_not_encrypt = no_encrypt;
+ if (sdata->type == IEEE80211_IF_TYPE_MGMT)
+ pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
skb->dev = local->mdev;
- sdata->stats.tx_packets++;
- sdata->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
/* Update skb pointers to various headers since this modified frame
* is going to go through Linux networking code that may potentially
pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
pkt_data->ifindex = sdata->dev->ifindex;
- pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
+ if (sdata->type == IEEE80211_IF_TYPE_MGMT)
+ pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
skb->priority = 20; /* use hardcoded priority for mgmt TX queue */
skb->dev = sdata->local->mdev;
* to request TX callback for hostapd. BIT(1) is checked.
*/
if ((fc & BIT(1)) == BIT(1)) {
- pkt_data->req_tx_status = 1;
+ pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
fc &= ~BIT(1);
hdr->frame_control = cpu_to_le16(fc);
}
- pkt_data->do_not_encrypt = !(fc & IEEE80211_FCTL_PROTECTED);
+ if (!(fc & IEEE80211_FCTL_PROTECTED))
+ pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
- sdata->stats.tx_packets++;
- sdata->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev_queue_xmit(skb);
tx.u.tx.num_extra_frag = store->num_extra_frag;
tx.u.tx.last_frag_hwrate = store->last_frag_hwrate;
tx.u.tx.last_frag_rate = store->last_frag_rate;
- tx.u.tx.probe_last_frag = store->last_frag_rate_ctrl_probe;
+ tx.flags = 0;
+ if (store->last_frag_rate_ctrl_probe)
+ tx.flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
ret = __ieee80211_tx(local, store->skb, &tx);
if (ret) {
if (ret == IEEE80211_TX_FRAG_AGAIN)
u8 *b_head, *b_tail;
int bh_len, bt_len;
- bdev = dev_get_by_index(if_id);
+ bdev = dev_get_by_index(&init_net, if_id);
if (bdev) {
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
ap = &sdata->u.ap;
return NULL;
}
- control->tx_rate = (sdata->short_preamble &&
- (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
+ control->tx_rate =
+ ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
+ (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
rate->val2 : rate->val;
control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
control->power_level = local->hw.conf.power_level;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_ap *bss = NULL;
- bdev = dev_get_by_index(if_id);
+ bdev = dev_get_by_index(&init_net, if_id);
if (bdev) {
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
bss = &sdata->u.ap;
dev_kfree_skb_any(skb);
}
sta = tx.sta;
- tx.u.tx.ps_buffered = 1;
+ tx.flags |= IEEE80211_TXRXD_TXPS_BUFFERED;
+ tx.u.tx.mode = local->hw.conf.mode;
for (handler = local->tx_handlers; *handler != NULL; handler++) {
res = (*handler)(&tx);