sta_info_set_tim_bit(sta);
info->control.jiffies = jiffies;
+ info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
skb_queue_tail(&sta->ps_tx_buf, tx->skb);
return TX_QUEUED;
}
* frame filtering and keeps a station blacklist on its own
* (e.g: p54), so that frames can be delivered unimpeded.
*
- * Note: It should be save to disable the filter now.
+ * Note: It should be safe to disable the filter now.
* As, it is really unlikely that we still have any pending
* frame for this station in the hw's buffers/fifos left,
* that is not rejected with a unsuccessful tx_status yet.
if (unlikely(!info->control.rates[0].count))
info->control.rates[0].count = 1;
+ if (WARN_ON_ONCE((info->control.rates[0].count > 1) &&
+ (info->flags & IEEE80211_TX_CTL_NO_ACK)))
+ info->control.rates[0].count = 1;
+
if (is_multicast_ether_addr(hdr->addr1)) {
/*
* XXX: verify the rate is in the basic rateset
hdrlen = ieee80211_hdrlen(hdr->frame_control);
/* internal error, why is TX_FRAGMENTED set? */
- if (WARN_ON(skb->len <= frag_threshold))
+ if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
return TX_DROP;
/*
do {
hdr = (void *) skb->data;
+ if (unlikely(ieee80211_is_pspoll(hdr->frame_control)))
+ break; /* must not overwrite AID */
next_len = skb->next ? skb->next->len : 0;
group_addr = is_multicast_ether_addr(hdr->addr1);
* deal with packet injection down monitor interface
* with Radiotap Header -- only called for monitor mode interface
*/
-static ieee80211_tx_result
-__ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
- struct sk_buff *skb)
+static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
+ struct sk_buff *skb)
{
/*
* this is the moment to interpret and discard the radiotap header that
* on transmission
*/
if (skb->len < (iterator.max_length + FCS_LEN))
- return TX_DROP;
+ return false;
skb_trim(skb, skb->len - FCS_LEN);
}
}
if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
- return TX_DROP;
+ return false;
/*
* remove the radiotap header
*/
skb_pull(skb, iterator.max_length);
- return TX_CONTINUE;
+ return true;
}
/*
/* process and remove the injection radiotap header */
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
- if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP)
+ if (!__ieee80211_parse_tx_radiotap(tx, skb))
return TX_DROP;
/*
info->flags |= IEEE80211_TX_CTL_NO_ACK;
} else {
tx->flags |= IEEE80211_TX_UNICAST;
- info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
+ if (unlikely(local->wifi_wme_noack_test))
+ info->flags |= IEEE80211_TX_CTL_NO_ACK;
+ else
+ info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
}
if (tx->flags & IEEE80211_TX_FRAGMENTED) {
bool txpending)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- struct sta_info *sta;
struct ieee80211_tx_data tx;
ieee80211_tx_result res_prepare;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
return;
}
- sta = tx.sta;
tx.channel = local->hw.conf.channel;
info->band = tx.channel->band;
}
if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
- local->hw.conf.dynamic_ps_timeout > 0) {
+ local->hw.conf.dynamic_ps_timeout > 0 &&
+ !local->sw_scanning && !local->hw_scanning && local->ps_sdata) {
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
ieee80211_stop_queues_by_reason(&local->hw,
IEEE80211_QUEUE_STOP_REASON_PS);
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
- int ret = 1, head_need;
+ int ret = NETDEV_TX_BUSY, head_need;
u16 ethertype, hdrlen, meshhdrlen = 0;
__le16 fc;
struct ieee80211_hdr hdr;
u32 sta_flags = 0;
if (unlikely(skb->len < ETH_HLEN)) {
- ret = 0;
+ ret = NETDEV_TX_OK;
goto fail;
}
if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
/* Do not send frames with mesh_ttl == 0 */
sdata->u.mesh.mshstats.dropped_frames_ttl++;
- ret = 0;
+ ret = NETDEV_TX_OK;
goto fail;
}
memset(&mesh_hdr, 0, sizeof(mesh_hdr));
hdrlen = 24;
break;
default:
- ret = 0;
+ ret = NETDEV_TX_OK;
goto fail;
}
I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
- ret = 0;
+ ret = NETDEV_TX_OK;
goto fail;
}
dev->trans_start = jiffies;
dev_queue_xmit(skb);
- return 0;
+ return NETDEV_TX_OK;
fail:
- if (!ret)
+ if (ret == NETDEV_TX_OK)
dev_kfree_skb(skb);
return ret;