static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) { IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n"); goto drop; } if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE && !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) goto drop; if (control->sta) { if (iwl_mvm_tx_skb(mvm, skb, control->sta)) goto drop; return; } if (iwl_mvm_tx_skb_non_sta(mvm, skb)) goto drop; return; drop: ieee80211_free_txskb(hw, skb); }
static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) { struct wcn36xx_dxe_ctl *ctl = ch->tail_blk_ctl; struct ieee80211_tx_info *info; unsigned long flags; /* * Make at least one loop of do-while because in case ring is * completely full head and tail are pointing to the same element * and while-do will not make any cycles. */ do { if (ctl->skb) { dma_unmap_single(NULL, ctl->desc->src_addr_l, ctl->skb->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(ctl->skb); if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { /* Keep frame until TX status comes */ ieee80211_free_txskb(wcn->hw, ctl->skb); } spin_lock_irqsave(&ctl->skb_lock, flags); if (wcn->queues_stopped) { wcn->queues_stopped = false; ieee80211_wake_queues(wcn->hw); } spin_unlock_irqrestore(&ctl->skb_lock, flags); ctl->skb = NULL; } ctl = ctl->next; } while (ctl != ch->head_blk_ctl && !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)); ch->tail_blk_ctl = ctl; }
static void vnt_tx_context_complete(struct urb *urb) { struct vnt_usb_send_context *context = urb->context; struct vnt_private *priv = context->priv; switch (urb->status) { case 0: dev_dbg(&priv->usb->dev, "Write %d bytes\n", context->buf_len); break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: context->in_use = false; return; case -ETIMEDOUT: default: dev_dbg(&priv->usb->dev, "BULK Out failed %d\n", urb->status); break; } if (context->type == CONTEXT_DATA_PACKET) ieee80211_wake_queues(priv->hw); if (urb->status || context->type == CONTEXT_BEACON_PACKET) { if (context->skb) ieee80211_free_txskb(priv->hw, context->skb); context->in_use = false; } }
static void rtl_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_tcb_desc tcb_desc; memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) goto err_free; if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) goto err_free; rtl_tx_accounting(hw, skb); if (!rtlpriv->intf_ops->waitq_insert(hw, control->sta, skb)) rtlpriv->intf_ops->adapter_tx(hw, control->sta, skb, &tcb_desc); return; err_free: ieee80211_free_txskb(hw, skb); }
static void ar5523_data_tx_cb(struct urb *urb) { struct sk_buff *skb = urb->context; struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); struct ar5523_tx_data *data = (struct ar5523_tx_data *) txi->driver_data; struct ar5523 *ar = data->ar; unsigned long flags; ar5523_dbg(ar, "data tx urb completed: %d\n", urb->status); spin_lock_irqsave(&ar->tx_data_list_lock, flags); list_del(&data->list); spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); if (urb->status) { ar5523_dbg(ar, "%s: urb status: %d\n", __func__, urb->status); ar5523_data_tx_pkt_put(ar); ieee80211_free_txskb(ar->hw, skb); } else { skb_pull(skb, sizeof(struct ar5523_tx_desc) + sizeof(__be32)); ieee80211_tx_status_irqsafe(ar->hw, skb); } usb_free_urb(urb); }
static void vnt_tx_80211(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) { struct vnt_private *priv = hw->priv; if (vnt_tx_packet(priv, skb)) ieee80211_free_txskb(hw, skb); }
static inline void free_descriptor_buffer(struct b43_dmaring *ring, struct b43_dmadesc_meta *meta) { if (meta->skb) { if (ring->tx) ieee80211_free_txskb(ring->dev->wl->hw, meta->skb); else dev_kfree_skb_any(meta->skb); meta->skb = NULL; } }
int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) { struct sk_buff *beacon; beacon = ieee80211_beacon_get(priv->hw, vif); if (!beacon) return -ENOMEM; if (vnt_beacon_xmit(priv, beacon)) { ieee80211_free_txskb(priv->hw, beacon); return -ENODEV; } return 0; }
static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_tx_control txctl; memset(&txctl, 0, sizeof(struct ath_tx_control)); txctl.txq = sc->beacon.cabq; ath_dbg(common, XMIT, "transmitting CABQ packet, skb: %p\n", skb); if (ath_tx_start(hw, skb, &txctl) != 0) { ath_dbg(common, XMIT, "CABQ TX failed\n"); ieee80211_free_txskb(hw, skb); } }
static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) { struct wcn36xx_dxe_ctl *ctl = ch->tail_blk_ctl; struct ieee80211_tx_info *info; while (ctl != ch->head_blk_ctl && !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) { if (ctl->skb) { dma_unmap_single(NULL, ctl->desc->src_addr_l, ctl->skb->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(ctl->skb); if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { /* Keep frame until TX status comes */ ieee80211_free_txskb(wcn->hw, ctl->skb); } ctl->skb = NULL; } ctl = ctl->next; } ch->tail_blk_ctl = ctl; }
int mt7601u_dma_enqueue_tx(struct mt7601u_dev *dev, struct sk_buff *skb, struct mt76_wcid *wcid, int hw_q) { u8 ep = q2ep(hw_q); u32 dma_flags; int ret; dma_flags = MT_TXD_PKT_INFO_80211; if (wcid->hw_key_idx == 0xff) dma_flags |= MT_TXD_PKT_INFO_WIV; ret = mt7601u_dma_skb_wrap_pkt(skb, ep2dmaq(ep), dma_flags); if (ret) return ret; ret = mt7601u_dma_submit_tx(dev, skb, ep); if (ret) { ieee80211_free_txskb(dev->hw, skb); return ret; } return 0; }
int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) { struct b43_dmaring *ring; struct ieee80211_hdr *hdr; int err = 0; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); hdr = (struct ieee80211_hdr *)skb->data; if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { /* The multicast ring will be sent after the DTIM */ ring = dev->dma.tx_ring_mcast; /* Set the more-data bit. Ucode will clear it on * the last frame for us. */ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); } else { /* Decide by priority where to put this frame. */ ring = select_ring_by_priority( dev, skb_get_queue_mapping(skb)); } B43_WARN_ON(!ring->tx); if (unlikely(ring->stopped)) { /* We get here only because of a bug in mac80211. * Because of a race, one packet may be queued after * the queue is stopped, thus we got called when we shouldn't. * For now, just refuse the transmit. */ if (b43_debug(dev, B43_DBG_DMAVERBOSE)) b43err(dev->wl, "Packet after queue stopped\n"); err = -ENOSPC; goto out; } if (unlikely(WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME))) { /* If we get here, we have a real error with the queue * full, but queues not stopped. */ b43err(dev->wl, "DMA queue overflow\n"); err = -ENOSPC; goto out; } /* Assign the queue number to the ring (if not already done before) * so TX status handling can use it. The queue to ring mapping is * static, so we don't need to store it per frame. */ ring->queue_prio = skb_get_queue_mapping(skb); err = dma_tx_fragment(ring, skb); if (unlikely(err == -ENOKEY)) { /* Drop this packet, as we don't have the encryption key * anymore and must not transmit it unencrypted. */ ieee80211_free_txskb(dev->wl->hw, skb); err = 0; goto out; } if (unlikely(err)) { b43err(dev->wl, "DMA tx mapping failure\n"); goto out; } if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || should_inject_overflow(ring)) { /* This TX ring is full. */ unsigned int skb_mapping = skb_get_queue_mapping(skb); ieee80211_stop_queue(dev->wl->hw, skb_mapping); dev->wl->tx_queue_stopped[skb_mapping] = 1; ring->stopped = true; if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); } } out: return err; }
/** * rsi_core_xmit() - This function transmits the packets received from mac80211 * @common: Pointer to the driver private structure. * @skb: Pointer to the socket buffer structure. * * Return: None. */ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) { struct rsi_hw *adapter = common->priv; struct ieee80211_tx_info *info; struct skb_info *tx_params; struct ieee80211_hdr *wh = NULL; struct ieee80211_vif *vif; u8 q_num, tid = 0; struct rsi_sta *rsta = NULL; if ((!skb) || (!skb->len)) { rsi_dbg(ERR_ZONE, "%s: Null skb/zero Length packet\n", __func__); goto xmit_fail; } if (common->fsm_state != FSM_MAC_INIT_DONE) { rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__); goto xmit_fail; } if (common->wow_flags & RSI_WOW_ENABLED) { rsi_dbg(ERR_ZONE, "%s: Blocking Tx_packets when WOWLAN is enabled\n", __func__); goto xmit_fail; } info = IEEE80211_SKB_CB(skb); tx_params = (struct skb_info *)info->driver_data; wh = (struct ieee80211_hdr *)&skb->data[0]; tx_params->sta_id = 0; vif = rsi_get_vif(adapter, wh->addr2); if (!vif) goto xmit_fail; tx_params->vif = vif; tx_params->vap_id = ((struct vif_priv *)vif->drv_priv)->vap_id; if ((ieee80211_is_mgmt(wh->frame_control)) || (ieee80211_is_ctl(wh->frame_control)) || (ieee80211_is_qos_nullfunc(wh->frame_control))) { if (ieee80211_is_assoc_req(wh->frame_control) || ieee80211_is_reassoc_req(wh->frame_control)) { struct ieee80211_bss_conf *bss = &vif->bss_conf; common->eapol4_confirm = false; rsi_hal_send_sta_notify_frame(common, RSI_IFTYPE_STATION, STA_CONNECTED, bss->bssid, bss->qos, bss->aid, 0, vif); } q_num = MGMT_SOFT_Q; skb->priority = q_num; if (rsi_prepare_mgmt_desc(common, skb)) { rsi_dbg(ERR_ZONE, "Failed to prepare desc\n"); goto xmit_fail; } } else { if (ieee80211_is_data_qos(wh->frame_control)) { u8 *qos = ieee80211_get_qos_ctl(wh); tid = *qos & IEEE80211_QOS_CTL_TID_MASK; skb->priority = TID_TO_WME_AC(tid); } else { tid = IEEE80211_NONQOS_TID; skb->priority = BE_Q; } q_num = skb->priority; tx_params->tid = tid; if (((vif->type == NL80211_IFTYPE_AP) || (vif->type == NL80211_IFTYPE_P2P_GO)) && (!is_broadcast_ether_addr(wh->addr1)) && (!is_multicast_ether_addr(wh->addr1))) { rsta = rsi_find_sta(common, wh->addr1); if (!rsta) goto xmit_fail; tx_params->sta_id = rsta->sta_id; } else { tx_params->sta_id = 0; } if (rsta) { /* Start aggregation if not done for this tid */ if (!rsta->start_tx_aggr[tid]) { rsta->start_tx_aggr[tid] = true; ieee80211_start_tx_ba_session(rsta->sta, tid, 0); } } if (skb->protocol == cpu_to_be16(ETH_P_PAE)) { q_num = MGMT_SOFT_Q; skb->priority = q_num; } if (rsi_prepare_data_desc(common, skb)) { rsi_dbg(ERR_ZONE, "Failed to prepare data desc\n"); goto xmit_fail; } } if ((q_num < MGMT_SOFT_Q) && ((skb_queue_len(&common->tx_queue[q_num]) + 1) >= DATA_QUEUE_WATER_MARK)) { rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__); if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num))) ieee80211_stop_queue(adapter->hw, WME_AC(q_num)); rsi_set_event(&common->tx_thread.event); goto xmit_fail; } rsi_core_queue_pkt(common, skb); rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thread <===\n", __func__); rsi_set_event(&common->tx_thread.event); return; xmit_fail: rsi_dbg(ERR_ZONE, "%s: Failed to queue packet\n", __func__); /* Dropping pkt here */ ieee80211_free_txskb(common->priv->hw, skb); }
static void ar5523_tx_work_locked(struct ar5523 *ar) { struct ar5523_tx_data *data; struct ar5523_tx_desc *desc; struct ar5523_chunk *chunk; struct ieee80211_tx_info *txi; struct urb *urb; struct sk_buff *skb; int error = 0, paylen; u32 txqid; unsigned long flags; BUILD_BUG_ON(sizeof(struct ar5523_tx_data) > IEEE80211_TX_INFO_DRIVER_DATA_SIZE); ar5523_dbg(ar, "%s\n", __func__); do { spin_lock_irqsave(&ar->tx_data_list_lock, flags); if (!list_empty(&ar->tx_queue_pending)) { data = (struct ar5523_tx_data *) ar->tx_queue_pending.next; list_del(&data->list); } else data = NULL; spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); if (!data) break; txi = container_of((void *)data, struct ieee80211_tx_info, driver_data); txqid = 0; skb = container_of((void *)txi, struct sk_buff, cb); paylen = skb->len; urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { ar5523_err(ar, "Failed to allocate TX urb\n"); ieee80211_free_txskb(ar->hw, skb); continue; } data->ar = ar; data->urb = urb; desc = (struct ar5523_tx_desc *)skb_push(skb, sizeof(*desc)); chunk = (struct ar5523_chunk *)skb_push(skb, sizeof(*chunk)); chunk->seqnum = 0; chunk->flags = UATH_CFLAGS_FINAL; chunk->length = cpu_to_be16(skb->len); desc->msglen = cpu_to_be32(skb->len); desc->msgid = AR5523_DATA_ID; desc->buflen = cpu_to_be32(paylen); desc->type = cpu_to_be32(WDCMSG_SEND); desc->flags = cpu_to_be32(UATH_TX_NOTIFY); if (test_bit(AR5523_CONNECTED, &ar->flags)) desc->connid = cpu_to_be32(AR5523_ID_BSS); else desc->connid = cpu_to_be32(AR5523_ID_BROADCAST); if (txi->flags & IEEE80211_TX_CTL_USE_MINRATE) txqid |= UATH_TXQID_MINRATE; desc->txqid = cpu_to_be32(txqid); urb->transfer_flags = URB_ZERO_PACKET; usb_fill_bulk_urb(urb, ar->dev, ar5523_data_tx_pipe(ar->dev), skb->data, skb->len, ar5523_data_tx_cb, skb); spin_lock_irqsave(&ar->tx_data_list_lock, flags); list_add_tail(&data->list, &ar->tx_queue_submitted); spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); mod_timer(&ar->tx_wd_timer, jiffies + AR5523_TX_WD_TIMEOUT); atomic_inc(&ar->tx_nr_pending); ar5523_dbg(ar, "TX Frame (%d pending)\n", atomic_read(&ar->tx_nr_pending)); error = usb_submit_urb(urb, GFP_KERNEL); if (error) { ar5523_err(ar, "error %d when submitting tx urb\n", error); spin_lock_irqsave(&ar->tx_data_list_lock, flags); list_del(&data->list); spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); atomic_dec(&ar->tx_nr_pending); ar5523_data_tx_pkt_put(ar); usb_free_urb(urb); ieee80211_free_txskb(ar->hw, skb); } } while (true); }
int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) { struct b43_dmaring *ring; struct ieee80211_hdr *hdr; int err = 0; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); hdr = (struct ieee80211_hdr *)skb->data; if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { ring = dev->dma.tx_ring_mcast; hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); } else { ring = select_ring_by_priority( dev, skb_get_queue_mapping(skb)); } B43_WARN_ON(!ring->tx); if (unlikely(ring->stopped)) { if (b43_debug(dev, B43_DBG_DMAVERBOSE)) b43err(dev->wl, "Packet after queue stopped\n"); err = -ENOSPC; goto out; } if (unlikely(WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME))) { b43err(dev->wl, "DMA queue overflow\n"); err = -ENOSPC; goto out; } ring->queue_prio = skb_get_queue_mapping(skb); err = dma_tx_fragment(ring, skb); if (unlikely(err == -ENOKEY)) { /* Drop this packet, as we don't have the encryption key * anymore and must not transmit it unencrypted. */ ieee80211_free_txskb(dev->wl->hw, skb); err = 0; goto out; } if (unlikely(err)) { b43err(dev->wl, "DMA tx mapping failure\n"); goto out; } if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || should_inject_overflow(ring)) { unsigned int skb_mapping = skb_get_queue_mapping(skb); ieee80211_stop_queue(dev->wl->hw, skb_mapping); dev->wl->tx_queue_stopped[skb_mapping] = 1; ring->stopped = true; if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); } } out: return err; }
void rt2x00mac_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) { struct rt2x00_dev *rt2x00dev = hw->priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); enum data_queue_qid qid = skb_get_queue_mapping(skb); struct data_queue *queue = NULL; /* * Mac80211 might be calling this function while we are trying * to remove the device or perhaps suspending it. * Note that we can only stop the TX queues inside the TX path * due to possible race conditions in mac80211. */ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) goto exit_free_skb; /* * Use the ATIM queue if appropriate and present. */ if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) qid = QID_ATIM; queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); if (unlikely(!queue)) { rt2x00_err(rt2x00dev, "Attempt to send packet over invalid queue %d\n" "Please file bug report to %s\n", qid, DRV_PROJECT); goto exit_free_skb; } /* * If CTS/RTS is required. create and queue that frame first. * Make sure we have at least enough entries available to send * this CTS/RTS frame as well as the data frame. * Note that when the driver has set the set_rts_threshold() * callback function it doesn't need software generation of * either RTS or CTS-to-self frame and handles everything * inside the hardware. */ if (!rt2x00dev->ops->hw->set_rts_threshold && (tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS | IEEE80211_TX_RC_USE_CTS_PROTECT))) { if (rt2x00queue_available(queue) <= 1) goto exit_fail; if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb)) goto exit_fail; } if (unlikely(rt2x00queue_write_tx_frame(queue, skb, control->sta, false))) goto exit_fail; /* * Pausing queue has to be serialized with rt2x00lib_txdone(). Note * we should not use spin_lock_bh variant as bottom halve was already * disabled before ieee80211_xmit() call. */ spin_lock(&queue->tx_lock); if (rt2x00queue_threshold(queue)) rt2x00queue_pause_queue(queue); spin_unlock(&queue->tx_lock); return; exit_fail: spin_lock(&queue->tx_lock); rt2x00queue_pause_queue(queue); spin_unlock(&queue->tx_lock); exit_free_skb: ieee80211_free_txskb(hw, skb); }
/** * rsi_core_xmit() - This function transmits the packets received from mac80211 * @common: Pointer to the driver private structure. * @skb: Pointer to the socket buffer structure. * * Return: None. */ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) { struct rsi_hw *adapter = common->priv; struct ieee80211_tx_info *info; struct skb_info *tx_params; struct ieee80211_hdr *tmp_hdr = NULL; u8 q_num, tid = 0; if ((!skb) || (!skb->len)) { rsi_dbg(ERR_ZONE, "%s: Null skb/zero Length packet\n", __func__); goto xmit_fail; } info = IEEE80211_SKB_CB(skb); tx_params = (struct skb_info *)info->driver_data; tmp_hdr = (struct ieee80211_hdr *)&skb->data[0]; if (common->fsm_state != FSM_MAC_INIT_DONE) { rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__); goto xmit_fail; } if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) || (ieee80211_is_ctl(tmp_hdr->frame_control)) || (ieee80211_is_qos_nullfunc(tmp_hdr->frame_control))) { q_num = MGMT_SOFT_Q; skb->priority = q_num; } else { if (ieee80211_is_data_qos(tmp_hdr->frame_control)) { tid = (skb->data[24] & IEEE80211_QOS_TID); skb->priority = TID_TO_WME_AC(tid); } else { tid = IEEE80211_NONQOS_TID; skb->priority = BE_Q; } q_num = skb->priority; tx_params->tid = tid; tx_params->sta_id = 0; } if ((q_num != MGMT_SOFT_Q) && ((skb_queue_len(&common->tx_queue[q_num]) + 1) >= DATA_QUEUE_WATER_MARK)) { rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__); if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num))) ieee80211_stop_queue(adapter->hw, WME_AC(q_num)); rsi_set_event(&common->tx_thread.event); goto xmit_fail; } rsi_core_queue_pkt(common, skb); rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thead <===\n", __func__); rsi_set_event(&common->tx_thread.event); return; xmit_fail: rsi_dbg(ERR_ZONE, "%s: Failed to queue packet\n", __func__); /* Dropping pkt here */ ieee80211_free_txskb(common->priv->hw, skb); }