Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51cb6db0 authored by David S. Miller's avatar David S. Miller
Browse files

mac80211: Reimplement WME using ->select_queue().



The only behavior change is that we do not drop packets under any
circumstances.  If that is absolutely needed, we could easily add it
back.

With cleanups and help from Johannes Berg.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eae792b7
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -847,20 +847,12 @@ static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr)

static inline int ieee80211_num_regular_queues(struct ieee80211_hw *hw)
{
#ifdef CONFIG_MAC80211_QOS
	return hw->queues;
#else
	return 1;
#endif
}

static inline int ieee80211_num_queues(struct ieee80211_hw *hw)
{
#ifdef CONFIG_MAC80211_QOS
	return hw->queues + hw->ampdu_queues;
#else
	return 1;
#endif
}

static inline struct ieee80211_rate *
+0 −11
Original line number Diff line number Diff line
@@ -11,17 +11,6 @@ config MAC80211
	  This option enables the hardware independent IEEE 802.11
	  networking stack.

config MAC80211_QOS
	def_bool y
	depends on MAC80211
	depends on NET_SCHED
	depends on BROKEN

comment "QoS/HT support disabled"
	depends on MAC80211 && !MAC80211_QOS
comment "QoS/HT support needs CONFIG_NET_SCHED"
	depends on MAC80211 && !NET_SCHED

menu "Rate control algorithm selection"
	depends on MAC80211 != n

+1 −1
Original line number Diff line number Diff line
@@ -18,10 +18,10 @@ mac80211-y := \
	tx.o \
	key.o \
	util.o \
	wme.o \
	event.o

mac80211-$(CONFIG_MAC80211_LEDS) += led.o
mac80211-$(CONFIG_MAC80211_QOS) += wme.o
mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
	debugfs.o \
	debugfs_sta.o \
+6 −9
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/etherdevice.h>
#include <net/wireless.h>
#include <net/iw_handler.h>
#include <net/mac80211.h>
#include "key.h"
#include "sta_info.h"

@@ -537,6 +538,9 @@ enum {
	IEEE80211_ADDBA_MSG	= 4,
};

/* maximum number of hardware queues we support. */
#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)

struct ieee80211_local {
	/* embed the driver visible part.
	 * don't cast (use the static inlines below), but we keep
@@ -545,6 +549,8 @@ struct ieee80211_local {

	const struct ieee80211_ops *ops;

	unsigned long queue_pool[BITS_TO_LONGS(QD_MAX_QUEUES)];

	struct net_device *mdev; /* wmaster# - "master" 802.11 device */
	int open_count;
	int monitors, cooked_mntrs;
@@ -740,15 +746,6 @@ struct ieee80211_local {
#endif
};

static inline int ieee80211_is_multiqueue(struct ieee80211_local *local)
{
#ifdef CONFIG_MAC80211_QOS
	return netif_is_multiqueue(local->mdev);
#else
	return 0;
#endif
}

static inline struct ieee80211_sub_if_data *
IEEE80211_DEV_TO_SUB_IF(struct net_device *dev)
{
+15 −46
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ static int ieee80211_master_open(struct net_device *dev)
	if (res)
		return res;

	netif_start_queue(local->mdev);
	netif_tx_start_all_queues(local->mdev);

	return 0;
}
@@ -375,7 +375,7 @@ static int ieee80211_open(struct net_device *dev)
		queue_work(local->hw.workqueue, &ifsta->work);
	}

	netif_start_queue(dev);
	netif_tx_start_all_queues(dev);

	return 0;
 err_del_interface:
@@ -400,7 +400,7 @@ static int ieee80211_stop(struct net_device *dev)
	/*
	 * Stop TX on this interface first.
	 */
	netif_stop_queue(dev);
	netif_tx_stop_all_queues(dev);

	/*
	 * Now delete all active aggregation sessions.
@@ -554,7 +554,6 @@ static int ieee80211_stop(struct net_device *dev)
int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct netdev_queue *txq;
	struct sta_info *sta;
	struct ieee80211_sub_if_data *sdata;
	u16 start_seq_num = 0;
@@ -619,11 +618,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
			(unsigned long)&sta->timer_to_tid[tid];
	init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);

	/* ensure that TX flow won't interrupt us
	 * until the end of the call to requeue function */
	txq = netdev_get_tx_queue(local->mdev, 0);
	spin_lock_bh(&txq->lock);

	/* create a new queue for this aggregation */
	ret = ieee80211_ht_agg_queue_add(local, sta, tid);

@@ -661,7 +655,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)

	/* Will put all the packets in the new SW queue */
	ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
	spin_unlock_bh(&txq->lock);
	spin_unlock_bh(&sta->lock);

	/* send an addBA request */
@@ -687,7 +680,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
err_unlock_queue:
	kfree(sta->ampdu_mlme.tid_tx[tid]);
	sta->ampdu_mlme.tid_tx[tid] = NULL;
	spin_unlock_bh(&txq->lock);
	ret = -EBUSY;
err_unlock_sta:
	spin_unlock_bh(&sta->lock);
@@ -812,7 +804,6 @@ EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct netdev_queue *txq;
	struct sta_info *sta;
	u8 *state;
	int agg_queue;
@@ -844,8 +835,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
	state = &sta->ampdu_mlme.tid_state_tx[tid];

	/* NOTE: no need to use sta->lock in this state check, as
	 * ieee80211_stop_tx_ba_session will let only
	 * one stop call to pass through per sta/tid */
	 * ieee80211_stop_tx_ba_session will let only one stop call to
	 * pass through per sta/tid
	 */
	if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
#ifdef CONFIG_MAC80211_HT_DEBUG
		printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
@@ -860,19 +852,14 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)

	agg_queue = sta->tid_to_tx_q[tid];

	/* avoid ordering issues: we are the only one that can modify
	 * the content of the qdiscs */
	txq = netdev_get_tx_queue(local->mdev, 0);
	spin_lock_bh(&txq->lock);
	/* remove the queue for this aggregation */
	ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
	spin_unlock_bh(&txq->lock);

	/* we just requeued the all the frames that were in the removed
	 * queue, and since we might miss a softirq we do netif_schedule_queue.
	 * ieee80211_wake_queue is not used here as this queue is not
	 * necessarily stopped */
	netif_schedule_queue(txq);
	/* We just requeued the all the frames that were in the
	 * removed queue, and since we might miss a softirq we do
	 * netif_schedule_queue.  ieee80211_wake_queue is not used
	 * here as this queue is not necessarily stopped
	 */
	netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue));
	spin_lock_bh(&sta->lock);
	*state = HT_AGG_STATE_IDLE;
	sta->ampdu_mlme.addba_req_num[tid] = 0;
@@ -1660,17 +1647,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
	 * We use the number of queues for feature tests (QoS, HT) internally
	 * so restrict them appropriately.
	 */
#ifdef CONFIG_MAC80211_QOS
	if (hw->queues > IEEE80211_MAX_QUEUES)
		hw->queues = IEEE80211_MAX_QUEUES;
	if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES)
		hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES;
	if (hw->queues < 4)
		hw->ampdu_queues = 0;
#else
	hw->queues = 1;
	hw->ampdu_queues = 0;
#endif

	mdev = alloc_netdev_mq(sizeof(struct wireless_dev),
			       "wmaster%d", ether_setup,
@@ -1754,7 +1736,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
		goto fail_wep;
	}

	ieee80211_install_qdisc(local->mdev);
	local->mdev->select_queue = ieee80211_select_queue;

	/* add one default STA interface */
	result = ieee80211_if_add(local, "wlan%d", NULL,
@@ -1852,23 +1834,11 @@ static int __init ieee80211_init(void)

	ret = rc80211_pid_init();
	if (ret)
		goto out;

	ret = ieee80211_wme_register();
	if (ret) {
		printk(KERN_DEBUG "ieee80211_init: failed to "
		       "initialize WME (err=%d)\n", ret);
		goto out_cleanup_pid;
	}
		return ret;

	ieee80211_debugfs_netdev_init();

	return 0;

 out_cleanup_pid:
	rc80211_pid_exit();
 out:
	return ret;
}

static void __exit ieee80211_exit(void)
@@ -1884,7 +1854,6 @@ static void __exit ieee80211_exit(void)
	if (mesh_allocated)
		ieee80211s_stop();

	ieee80211_wme_unregister();
	ieee80211_debugfs_netdev_exit();
}

Loading