Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
	}
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
	}
}
Beispiel #8
0
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);
	}
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
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;
}
Beispiel #13
0
/**
 * 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);
}
Beispiel #14
0
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);
}
Beispiel #15
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) {
		
		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;
}
Beispiel #16
0
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);
}
Beispiel #17
0
/**
 * 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);
}