mac80211: QoS related cleanups
This * makes the queue number passed to drivers a u16 (as it will be with skb_get_queue_mapping) * removes the useless queue number defines * splits hw->queues into hw->queues/ampdu_queues * removes the debugfs files for per-queue counters * removes some dead QoS code * removes the beacon queue configuration for IBSS so that the drivers now never get a queue number bigger than (hw->queues + hw->ampdu_queues - 1) for tx and only in the range 0..hw->queues-1 for conf_tx. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
36fc6757fe
commit
e100bb64bf
|
@ -2996,8 +2996,7 @@ static void b43_qos_update_work(struct work_struct *work)
|
|||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
static int b43_op_conf_tx(struct ieee80211_hw *hw,
|
||||
int _queue,
|
||||
static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct b43_wl *wl = hw_to_b43_wl(hw);
|
||||
|
|
|
@ -2383,8 +2383,7 @@ out:
|
|||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static int b43legacy_op_conf_tx(struct ieee80211_hw *hw,
|
||||
int queue,
|
||||
static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -568,7 +568,7 @@ static void iwlcore_init_hw(struct iwl_priv *priv)
|
|||
hw->queues = 4;
|
||||
#ifdef CONFIG_IWL4965_HT
|
||||
/* Enhanced value; more queues, to support 11n aggregation */
|
||||
hw->queues = 16;
|
||||
hw->ampdu_queues = 12;
|
||||
#endif /* CONFIG_IWL4965_HT */
|
||||
}
|
||||
|
||||
|
|
|
@ -7143,7 +7143,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,
|
||||
static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct iwl3945_priv *priv = hw->priv;
|
||||
|
|
|
@ -6339,7 +6339,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
|
||||
static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
|
|
|
@ -935,7 +935,7 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
|
|||
}
|
||||
}
|
||||
|
||||
static int p54_conf_tx(struct ieee80211_hw *dev, int queue,
|
||||
static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct p54_common *priv = dev->priv;
|
||||
|
|
|
@ -1442,8 +1442,7 @@ static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
|
||||
int queue,
|
||||
static int rt2400pci_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
|
@ -1453,7 +1452,7 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
|
|||
* per queue. So by default we only configure the TX queue,
|
||||
* and ignore all other configurations.
|
||||
*/
|
||||
if (queue != IEEE80211_TX_QUEUE_DATA0)
|
||||
if (queue != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (rt2x00mac_conf_tx(hw, queue, params))
|
||||
|
|
|
@ -997,7 +997,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
|
|||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
u32 changes);
|
||||
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
|
||||
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params);
|
||||
|
||||
/*
|
||||
|
|
|
@ -517,7 +517,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
|
||||
|
||||
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx,
|
||||
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
|
|
|
@ -86,12 +86,9 @@ enum data_queue_qid {
|
|||
static inline enum data_queue_qid mac80211_queue_to_qid(unsigned int queue)
|
||||
{
|
||||
/* Regular TX queues are mapped directly */
|
||||
if (queue < NUM_TX_DATA_QUEUES)
|
||||
if (queue < 4)
|
||||
return queue;
|
||||
else if (queue == IEEE80211_TX_QUEUE_BEACON)
|
||||
return QID_BEACON;
|
||||
else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)
|
||||
return QID_ATIM;
|
||||
WARN_ON(1);
|
||||
return QID_OTHER;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,18 @@ struct ieee80211_ht_bss_info {
|
|||
u8 bss_op_mode; /* use IEEE80211_HT_IE_ */
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ieee80211_max_queues - maximum number of queues
|
||||
*
|
||||
* @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
|
||||
* @IEEE80211_MAX_AMPDU_QUEUES: Maximum number of queues usable
|
||||
* for A-MPDU operation.
|
||||
*/
|
||||
enum ieee80211_max_queues {
|
||||
IEEE80211_MAX_QUEUES = 16,
|
||||
IEEE80211_MAX_AMPDU_QUEUES = 16,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_tx_queue_params - transmit queue configuration
|
||||
*
|
||||
|
@ -129,42 +141,6 @@ struct ieee80211_tx_queue_stats {
|
|||
unsigned int count;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ieee80211_tx_queue - transmit queue number
|
||||
*
|
||||
* These constants are used with some callbacks that take a
|
||||
* queue number to set parameters for a queue.
|
||||
*
|
||||
* @IEEE80211_TX_QUEUE_DATA0: data queue 0
|
||||
* @IEEE80211_TX_QUEUE_DATA1: data queue 1
|
||||
* @IEEE80211_TX_QUEUE_DATA2: data queue 2
|
||||
* @IEEE80211_TX_QUEUE_DATA3: data queue 3
|
||||
* @IEEE80211_TX_QUEUE_DATA4: data queue 4
|
||||
* @IEEE80211_TX_QUEUE_SVP: ??
|
||||
* @NUM_TX_DATA_QUEUES: number of data queues
|
||||
* @IEEE80211_TX_QUEUE_AFTER_BEACON: transmit queue for frames to be
|
||||
* sent after a beacon
|
||||
* @IEEE80211_TX_QUEUE_BEACON: transmit queue for beacon frames
|
||||
* @NUM_TX_DATA_QUEUES_AMPDU: adding more queues for A-MPDU
|
||||
*/
|
||||
enum ieee80211_tx_queue {
|
||||
IEEE80211_TX_QUEUE_DATA0,
|
||||
IEEE80211_TX_QUEUE_DATA1,
|
||||
IEEE80211_TX_QUEUE_DATA2,
|
||||
IEEE80211_TX_QUEUE_DATA3,
|
||||
IEEE80211_TX_QUEUE_DATA4,
|
||||
IEEE80211_TX_QUEUE_SVP,
|
||||
|
||||
NUM_TX_DATA_QUEUES,
|
||||
|
||||
/* due to stupidity in the sub-ioctl userspace interface, the items in
|
||||
* this struct need to have fixed values. As soon as it is removed, we can
|
||||
* fix these entries. */
|
||||
IEEE80211_TX_QUEUE_AFTER_BEACON = 6,
|
||||
IEEE80211_TX_QUEUE_BEACON = 7,
|
||||
NUM_TX_DATA_QUEUES_AMPDU = 16
|
||||
};
|
||||
|
||||
struct ieee80211_low_level_stats {
|
||||
unsigned int dot11ACKFailureCount;
|
||||
unsigned int dot11RTSFailureCount;
|
||||
|
@ -315,7 +291,7 @@ struct ieee80211_tx_control {
|
|||
* position represents antenna number used */
|
||||
u8 icv_len; /* length of the ICV/MIC field in octets */
|
||||
u8 iv_len; /* length of the IV field in octets */
|
||||
u8 queue; /* hardware queue to use for this frame;
|
||||
u16 queue; /* hardware queue to use for this frame;
|
||||
* 0 = highest, hw->queues-1 = lowest */
|
||||
u16 aid; /* Station AID */
|
||||
int type; /* internal */
|
||||
|
@ -772,7 +748,14 @@ enum ieee80211_hw_flags {
|
|||
* @max_noise: like @max_rssi, but for the noise value.
|
||||
*
|
||||
* @queues: number of available hardware transmit queues for
|
||||
* data packets. WMM/QoS requires at least four.
|
||||
* data packets. WMM/QoS requires at least four, these
|
||||
* queues need to have configurable access parameters.
|
||||
*
|
||||
* @ampdu_queues: number of available hardware transmit queues
|
||||
* for A-MPDU packets, these have no access parameters
|
||||
* because they're used only for A-MPDU frames. Note that
|
||||
* mac80211 will not currently use any of the regular queues
|
||||
* for aggregation.
|
||||
*
|
||||
* @rate_control_algorithm: rate control algorithm for this hardware.
|
||||
* If unset (NULL), the default algorithm will be used. Must be
|
||||
|
@ -791,7 +774,7 @@ struct ieee80211_hw {
|
|||
unsigned int extra_tx_headroom;
|
||||
int channel_change_time;
|
||||
int vif_data_size;
|
||||
u8 queues;
|
||||
u16 queues, ampdu_queues;
|
||||
s8 max_rssi;
|
||||
s8 max_signal;
|
||||
s8 max_noise;
|
||||
|
@ -1069,8 +1052,7 @@ enum ieee80211_ampdu_mlme_action {
|
|||
* of assocaited station or AP.
|
||||
*
|
||||
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
|
||||
* bursting) for a hardware TX queue. The @queue parameter uses the
|
||||
* %IEEE80211_TX_QUEUE_* constants. Must be atomic.
|
||||
* bursting) for a hardware TX queue. Must be atomic.
|
||||
*
|
||||
* @get_tx_stats: Get statistics of the current TX queue status. This is used
|
||||
* to get number of currently queued packets (queue length), maximum queue
|
||||
|
@ -1150,7 +1132,7 @@ struct ieee80211_ops {
|
|||
u32 short_retry, u32 long_retr);
|
||||
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum sta_notify_cmd, const u8 *addr);
|
||||
int (*conf_tx)(struct ieee80211_hw *hw, int queue,
|
||||
int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params);
|
||||
int (*get_tx_stats)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_queue_stats *stats);
|
||||
|
|
|
@ -197,45 +197,6 @@ DEBUGFS_STATS_FILE(rx_handlers_fragments, 20, "%u",
|
|||
DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u",
|
||||
local->tx_status_drop);
|
||||
|
||||
static ssize_t stats_wme_rx_queue_read(struct file *file,
|
||||
char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_local *local = file->private_data;
|
||||
char buf[NUM_RX_DATA_QUEUES*15], *p = buf;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
|
||||
p += scnprintf(p, sizeof(buf)+buf-p,
|
||||
"%u\n", local->wme_rx_queue[i]);
|
||||
|
||||
return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
|
||||
}
|
||||
|
||||
static const struct file_operations stats_wme_rx_queue_ops = {
|
||||
.read = stats_wme_rx_queue_read,
|
||||
.open = mac80211_open_file_generic,
|
||||
};
|
||||
|
||||
static ssize_t stats_wme_tx_queue_read(struct file *file,
|
||||
char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ieee80211_local *local = file->private_data;
|
||||
char buf[NUM_TX_DATA_QUEUES*15], *p = buf;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
|
||||
p += scnprintf(p, sizeof(buf)+buf-p,
|
||||
"%u\n", local->wme_tx_queue[i]);
|
||||
|
||||
return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
|
||||
}
|
||||
|
||||
static const struct file_operations stats_wme_tx_queue_ops = {
|
||||
.read = stats_wme_tx_queue_read,
|
||||
.open = mac80211_open_file_generic,
|
||||
};
|
||||
#endif
|
||||
|
||||
DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
|
||||
|
@ -303,8 +264,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
|
|||
DEBUGFS_STATS_ADD(rx_expand_skb_head2);
|
||||
DEBUGFS_STATS_ADD(rx_handlers_fragments);
|
||||
DEBUGFS_STATS_ADD(tx_status_drop);
|
||||
DEBUGFS_STATS_ADD(wme_tx_queue);
|
||||
DEBUGFS_STATS_ADD(wme_rx_queue);
|
||||
#endif
|
||||
DEBUGFS_STATS_ADD(dot11ACKFailureCount);
|
||||
DEBUGFS_STATS_ADD(dot11RTSFailureCount);
|
||||
|
@ -356,8 +315,6 @@ void debugfs_hw_del(struct ieee80211_local *local)
|
|||
DEBUGFS_STATS_DEL(rx_expand_skb_head2);
|
||||
DEBUGFS_STATS_DEL(rx_handlers_fragments);
|
||||
DEBUGFS_STATS_DEL(tx_status_drop);
|
||||
DEBUGFS_STATS_DEL(wme_tx_queue);
|
||||
DEBUGFS_STATS_DEL(wme_rx_queue);
|
||||
#endif
|
||||
DEBUGFS_STATS_DEL(dot11ACKFailureCount);
|
||||
DEBUGFS_STATS_DEL(dot11RTSFailureCount);
|
||||
|
|
|
@ -123,36 +123,6 @@ static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
|
|||
}
|
||||
STA_OPS(last_seq_ctrl);
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
|
||||
static ssize_t sta_wme_rx_queue_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
|
||||
int i;
|
||||
struct sta_info *sta = file->private_data;
|
||||
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
|
||||
sta->wme_rx_queue[i]);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
|
||||
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
|
||||
}
|
||||
STA_OPS(wme_rx_queue);
|
||||
|
||||
static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char buf[15*NUM_TX_DATA_QUEUES], *p = buf;
|
||||
int i;
|
||||
struct sta_info *sta = file->private_data;
|
||||
for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
|
||||
sta->wme_tx_queue[i]);
|
||||
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
|
||||
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
|
||||
}
|
||||
STA_OPS(wme_tx_queue);
|
||||
#endif
|
||||
|
||||
static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
@ -293,10 +263,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
|
|||
DEBUGFS_ADD(num_ps_buf_frames);
|
||||
DEBUGFS_ADD(inactive_ms);
|
||||
DEBUGFS_ADD(last_seq_ctrl);
|
||||
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
|
||||
DEBUGFS_ADD(wme_rx_queue);
|
||||
DEBUGFS_ADD(wme_tx_queue);
|
||||
#endif
|
||||
DEBUGFS_ADD(agg_status);
|
||||
}
|
||||
|
||||
|
@ -306,10 +272,6 @@ void ieee80211_sta_debugfs_remove(struct sta_info *sta)
|
|||
DEBUGFS_DEL(num_ps_buf_frames);
|
||||
DEBUGFS_DEL(inactive_ms);
|
||||
DEBUGFS_DEL(last_seq_ctrl);
|
||||
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
|
||||
DEBUGFS_DEL(wme_rx_queue);
|
||||
DEBUGFS_DEL(wme_tx_queue);
|
||||
#endif
|
||||
DEBUGFS_DEL(agg_status);
|
||||
|
||||
debugfs_remove(sta->debugfs.dir);
|
||||
|
|
|
@ -610,8 +610,8 @@ struct ieee80211_local {
|
|||
struct sta_info *sta_hash[STA_HASH_SIZE];
|
||||
struct timer_list sta_cleanup;
|
||||
|
||||
unsigned long state[NUM_TX_DATA_QUEUES_AMPDU];
|
||||
struct ieee80211_tx_stored_packet pending_packet[NUM_TX_DATA_QUEUES_AMPDU];
|
||||
unsigned long state[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES];
|
||||
struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_AMPDU_QUEUES];
|
||||
struct tasklet_struct tx_pending_tasklet;
|
||||
|
||||
/* number of interfaces with corresponding IFF_ flags */
|
||||
|
@ -705,8 +705,6 @@ struct ieee80211_local {
|
|||
unsigned int rx_expand_skb_head2;
|
||||
unsigned int rx_handlers_fragments;
|
||||
unsigned int tx_status_drop;
|
||||
unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES];
|
||||
unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES];
|
||||
#define I802_DEBUG_INC(c) (c)++
|
||||
#else /* CONFIG_MAC80211_DEBUG_COUNTERS */
|
||||
#define I802_DEBUG_INC(c) do { } while (0)
|
||||
|
@ -764,8 +762,6 @@ struct ieee80211_local {
|
|||
struct dentry *rx_expand_skb_head2;
|
||||
struct dentry *rx_handlers_fragments;
|
||||
struct dentry *tx_status_drop;
|
||||
struct dentry *wme_tx_queue;
|
||||
struct dentry *wme_rx_queue;
|
||||
#endif
|
||||
struct dentry *dot11ACKFailureCount;
|
||||
struct dentry *dot11RTSFailureCount;
|
||||
|
|
|
@ -1745,6 +1745,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
|||
goto fail_wep;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ieee80211_install_qdisc(local->mdev);
|
||||
|
||||
/* add one default STA interface */
|
||||
|
|
|
@ -257,19 +257,8 @@ static void ieee80211_sta_def_wmm_params(struct net_device *dev,
|
|||
qparam.cw_max = 1023;
|
||||
qparam.txop = 0;
|
||||
|
||||
for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++)
|
||||
local->ops->conf_tx(local_to_hw(local),
|
||||
i + IEEE80211_TX_QUEUE_DATA0,
|
||||
&qparam);
|
||||
|
||||
if (ibss) {
|
||||
/* IBSS uses different parameters for Beacon sending */
|
||||
qparam.cw_min++;
|
||||
qparam.cw_min *= 2;
|
||||
qparam.cw_min--;
|
||||
local->ops->conf_tx(local_to_hw(local),
|
||||
IEEE80211_TX_QUEUE_BEACON, &qparam);
|
||||
}
|
||||
for (i = 0; i < local_to_hw(local)->queues; i++)
|
||||
local->ops->conf_tx(local_to_hw(local), i, &qparam);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,23 +295,23 @@ static void ieee80211_sta_wmm_params(struct net_device *dev,
|
|||
|
||||
switch (aci) {
|
||||
case 1:
|
||||
queue = IEEE80211_TX_QUEUE_DATA3;
|
||||
queue = 3;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(0) | BIT(3);
|
||||
break;
|
||||
case 2:
|
||||
queue = IEEE80211_TX_QUEUE_DATA1;
|
||||
queue = 1;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(4) | BIT(5);
|
||||
break;
|
||||
case 3:
|
||||
queue = IEEE80211_TX_QUEUE_DATA0;
|
||||
queue = 0;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(6) | BIT(7);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
queue = IEEE80211_TX_QUEUE_DATA2;
|
||||
queue = 2;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(1) | BIT(2);
|
||||
break;
|
||||
|
|
|
@ -275,11 +275,6 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
|
|||
}
|
||||
}
|
||||
|
||||
I802_DEBUG_INC(rx->local->wme_rx_queue[tid]);
|
||||
/* only a debug counter, sta might not be assigned properly yet */
|
||||
if (rx->sta)
|
||||
I802_DEBUG_INC(rx->sta->wme_rx_queue[tid]);
|
||||
|
||||
rx->queue = tid;
|
||||
/* Set skb->priority to 1d tag if highest order bit of TID is not set.
|
||||
* For now, set skb->priority to 0 for other cases. */
|
||||
|
|
|
@ -257,7 +257,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|||
* sta_rx_agg_session_timer_expired for useage */
|
||||
sta->timer_to_tid[i] = i;
|
||||
/* tid to tx queue: initialize according to HW (0 is valid) */
|
||||
sta->tid_to_tx_q[i] = local->hw.queues;
|
||||
sta->tid_to_tx_q[i] = local->hw.queues + local->hw.ampdu_queues;
|
||||
/* rx */
|
||||
sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
|
||||
sta->ampdu_mlme.tid_rx[i] = NULL;
|
||||
|
|
|
@ -19,16 +19,22 @@
|
|||
#include "wme.h"
|
||||
|
||||
/* maximum number of hardware queues we support. */
|
||||
#define TC_80211_MAX_QUEUES 16
|
||||
#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
|
||||
/* current number of hardware queues we support. */
|
||||
#define QD_NUM(hw) ((hw)->queues + (hw)->ampdu_queues)
|
||||
|
||||
/*
|
||||
* Default mapping in classifier to work with default
|
||||
* queue setup.
|
||||
*/
|
||||
const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 };
|
||||
|
||||
struct ieee80211_sched_data
|
||||
{
|
||||
unsigned long qdisc_pool[BITS_TO_LONGS(TC_80211_MAX_QUEUES)];
|
||||
unsigned long qdisc_pool[BITS_TO_LONGS(QD_MAX_QUEUES)];
|
||||
struct tcf_proto *filter_list;
|
||||
struct Qdisc *queues[TC_80211_MAX_QUEUES];
|
||||
struct sk_buff_head requeued[TC_80211_MAX_QUEUES];
|
||||
struct Qdisc *queues[QD_MAX_QUEUES];
|
||||
struct sk_buff_head requeued[QD_MAX_QUEUES];
|
||||
};
|
||||
|
||||
static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0};
|
||||
|
@ -95,7 +101,7 @@ static inline int wme_downgrade_ac(struct sk_buff *skb)
|
|||
|
||||
/* positive return value indicates which queue to use
|
||||
* negative return value indicates to drop the frame */
|
||||
static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
|
||||
static int classify80211(struct sk_buff *skb, struct Qdisc *qd)
|
||||
{
|
||||
struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
|
@ -106,7 +112,7 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
|
|||
if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) {
|
||||
/* management frames go on AC_VO queue, but are sent
|
||||
* without QoS control fields */
|
||||
return IEEE80211_TX_QUEUE_DATA0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 /* injected */) {
|
||||
|
@ -141,14 +147,16 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
|
|||
static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
|
||||
{
|
||||
struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
|
||||
struct ieee80211_hw *hw = &local->hw;
|
||||
struct ieee80211_sched_data *q = qdisc_priv(qd);
|
||||
struct ieee80211_tx_packet_data *pkt_data =
|
||||
(struct ieee80211_tx_packet_data *) skb->cb;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
unsigned short fc = le16_to_cpu(hdr->frame_control);
|
||||
struct Qdisc *qdisc;
|
||||
int err, queue;
|
||||
struct sta_info *sta;
|
||||
int err;
|
||||
u16 queue;
|
||||
u8 tid;
|
||||
|
||||
if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) {
|
||||
|
@ -158,7 +166,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
|
|||
tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
|
||||
if (sta) {
|
||||
int ampdu_queue = sta->tid_to_tx_q[tid];
|
||||
if ((ampdu_queue < local->hw.queues) &&
|
||||
if ((ampdu_queue < QD_NUM(hw)) &&
|
||||
test_bit(ampdu_queue, q->qdisc_pool)) {
|
||||
queue = ampdu_queue;
|
||||
pkt_data->flags |= IEEE80211_TXPD_AMPDU;
|
||||
|
@ -174,6 +182,9 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
|
|||
|
||||
queue = classify80211(skb, qd);
|
||||
|
||||
if (unlikely(queue >= local->hw.queues))
|
||||
queue = local->hw.queues - 1;
|
||||
|
||||
/* now we know the 1d priority, fill in the QoS header if there is one
|
||||
*/
|
||||
if (WLAN_FC_IS_QOS_DATA(fc)) {
|
||||
|
@ -193,8 +204,8 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
|
|||
sta = sta_info_get(local, hdr->addr1);
|
||||
if (sta) {
|
||||
int ampdu_queue = sta->tid_to_tx_q[tid];
|
||||
if ((ampdu_queue < local->hw.queues) &&
|
||||
test_bit(ampdu_queue, q->qdisc_pool)) {
|
||||
if ((ampdu_queue < QD_NUM(hw)) &&
|
||||
test_bit(ampdu_queue, q->qdisc_pool)) {
|
||||
queue = ampdu_queue;
|
||||
pkt_data->flags |= IEEE80211_TXPD_AMPDU;
|
||||
} else {
|
||||
|
@ -205,17 +216,6 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
|
|||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (unlikely(queue >= local->hw.queues)) {
|
||||
#if 0
|
||||
if (net_ratelimit()) {
|
||||
printk(KERN_DEBUG "%s - queue=%d (hw does not "
|
||||
"support) -> %d\n",
|
||||
__func__, queue, local->hw.queues - 1);
|
||||
}
|
||||
#endif
|
||||
queue = local->hw.queues - 1;
|
||||
}
|
||||
|
||||
if (unlikely(queue < 0)) {
|
||||
kfree_skb(skb);
|
||||
err = NET_XMIT_DROP;
|
||||
|
@ -270,7 +270,7 @@ static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd)
|
|||
int queue;
|
||||
|
||||
/* check all the h/w queues in numeric/priority order */
|
||||
for (queue = 0; queue < hw->queues; queue++) {
|
||||
for (queue = 0; queue < QD_NUM(hw); queue++) {
|
||||
/* see if there is room in this hardware queue */
|
||||
if ((test_bit(IEEE80211_LINK_STATE_XOFF,
|
||||
&local->state[queue])) ||
|
||||
|
@ -308,7 +308,7 @@ static void wme_qdiscop_reset(struct Qdisc* qd)
|
|||
|
||||
/* QUESTION: should we have some hardware flush functionality here? */
|
||||
|
||||
for (queue = 0; queue < hw->queues; queue++) {
|
||||
for (queue = 0; queue < QD_NUM(hw); queue++) {
|
||||
skb_queue_purge(&q->requeued[queue]);
|
||||
qdisc_reset(q->queues[queue]);
|
||||
}
|
||||
|
@ -326,7 +326,7 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
|
|||
tcf_destroy_chain(q->filter_list);
|
||||
q->filter_list = NULL;
|
||||
|
||||
for (queue=0; queue < hw->queues; queue++) {
|
||||
for (queue = 0; queue < QD_NUM(hw); queue++) {
|
||||
skb_queue_purge(&q->requeued[queue]);
|
||||
qdisc_destroy(q->queues[queue]);
|
||||
q->queues[queue] = &noop_qdisc;
|
||||
|
@ -337,17 +337,6 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
|
|||
/* called whenever parameters are updated on existing qdisc */
|
||||
static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt)
|
||||
{
|
||||
/* struct ieee80211_sched_data *q = qdisc_priv(qd);
|
||||
*/
|
||||
/* check our options block is the right size */
|
||||
/* copy any options to our local structure */
|
||||
/* Ignore options block for now - always use static mapping
|
||||
struct tc_ieee80211_qopt *qopt = nla_data(opt);
|
||||
|
||||
if (opt->nla_len < nla_attr_size(sizeof(*qopt)))
|
||||
return -EINVAL;
|
||||
memcpy(q->tag2queue, qopt->tag2queue, sizeof(qopt->tag2queue));
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -358,7 +347,7 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
|
|||
struct ieee80211_sched_data *q = qdisc_priv(qd);
|
||||
struct net_device *dev = qd->dev;
|
||||
struct ieee80211_local *local;
|
||||
int queues;
|
||||
struct ieee80211_hw *hw;
|
||||
int err = 0, i;
|
||||
|
||||
/* check that device is a mac80211 device */
|
||||
|
@ -366,29 +355,26 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
|
|||
dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
|
||||
return -EINVAL;
|
||||
|
||||
/* check this device is an ieee80211 master type device */
|
||||
if (dev->type != ARPHRD_IEEE80211)
|
||||
local = wdev_priv(dev->ieee80211_ptr);
|
||||
hw = &local->hw;
|
||||
|
||||
/* only allow on master dev */
|
||||
if (dev != local->mdev)
|
||||
return -EINVAL;
|
||||
|
||||
/* check that there is no qdisc currently attached to device
|
||||
* this ensures that we will be the root qdisc. (I can't find a better
|
||||
* way to test this explicitly) */
|
||||
if (dev->qdisc_sleeping != &noop_qdisc)
|
||||
/* ensure that we are root qdisc */
|
||||
if (qd->parent != TC_H_ROOT)
|
||||
return -EINVAL;
|
||||
|
||||
if (qd->flags & TCQ_F_INGRESS)
|
||||
return -EINVAL;
|
||||
|
||||
local = wdev_priv(dev->ieee80211_ptr);
|
||||
queues = local->hw.queues;
|
||||
|
||||
/* if options were passed in, set them */
|
||||
if (opt) {
|
||||
if (opt)
|
||||
err = wme_qdiscop_tune(qd, opt);
|
||||
}
|
||||
|
||||
/* create child queues */
|
||||
for (i = 0; i < queues; i++) {
|
||||
for (i = 0; i < QD_NUM(hw); i++) {
|
||||
skb_queue_head_init(&q->requeued[i]);
|
||||
q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops,
|
||||
qd->handle);
|
||||
|
@ -398,8 +384,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
|
|||
}
|
||||
}
|
||||
|
||||
/* reserve all legacy QoS queues */
|
||||
for (i = 0; i < min(IEEE80211_TX_QUEUE_DATA4, queues); i++)
|
||||
/* non-aggregation queues: reserve/mark as used */
|
||||
for (i = 0; i < local->hw.queues; i++)
|
||||
set_bit(i, q->qdisc_pool);
|
||||
|
||||
return err;
|
||||
|
@ -407,16 +393,6 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
|
|||
|
||||
static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb)
|
||||
{
|
||||
/* struct ieee80211_sched_data *q = qdisc_priv(qd);
|
||||
unsigned char *p = skb->tail;
|
||||
struct tc_ieee80211_qopt opt;
|
||||
|
||||
memcpy(&opt.tag2queue, q->tag2queue, TC_80211_MAX_TAG + 1);
|
||||
NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
|
||||
*/ return skb->len;
|
||||
/*
|
||||
nla_put_failure:
|
||||
skb_trim(skb, p - skb->data);*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -429,7 +405,7 @@ static int wme_classop_graft(struct Qdisc *qd, unsigned long arg,
|
|||
struct ieee80211_hw *hw = &local->hw;
|
||||
unsigned long queue = arg - 1;
|
||||
|
||||
if (queue >= hw->queues)
|
||||
if (queue >= QD_NUM(hw))
|
||||
return -EINVAL;
|
||||
|
||||
if (!new)
|
||||
|
@ -453,7 +429,7 @@ wme_classop_leaf(struct Qdisc *qd, unsigned long arg)
|
|||
struct ieee80211_hw *hw = &local->hw;
|
||||
unsigned long queue = arg - 1;
|
||||
|
||||
if (queue >= hw->queues)
|
||||
if (queue >= QD_NUM(hw))
|
||||
return NULL;
|
||||
|
||||
return q->queues[queue];
|
||||
|
@ -466,7 +442,7 @@ static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid)
|
|||
struct ieee80211_hw *hw = &local->hw;
|
||||
unsigned long queue = TC_H_MIN(classid);
|
||||
|
||||
if (queue - 1 >= hw->queues)
|
||||
if (queue - 1 >= QD_NUM(hw))
|
||||
return 0;
|
||||
|
||||
return queue;
|
||||
|
@ -492,7 +468,7 @@ static int wme_classop_change(struct Qdisc *qd, u32 handle, u32 parent,
|
|||
struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
|
||||
struct ieee80211_hw *hw = &local->hw;
|
||||
|
||||
if (cl - 1 > hw->queues)
|
||||
if (cl - 1 > QD_NUM(hw))
|
||||
return -ENOENT;
|
||||
|
||||
/* TODO: put code to program hardware queue parameters here,
|
||||
|
@ -509,7 +485,7 @@ static int wme_classop_delete(struct Qdisc *qd, unsigned long cl)
|
|||
struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
|
||||
struct ieee80211_hw *hw = &local->hw;
|
||||
|
||||
if (cl - 1 > hw->queues)
|
||||
if (cl - 1 > QD_NUM(hw))
|
||||
return -ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -522,7 +498,7 @@ static int wme_classop_dump_class(struct Qdisc *qd, unsigned long cl,
|
|||
struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
|
||||
struct ieee80211_hw *hw = &local->hw;
|
||||
|
||||
if (cl - 1 > hw->queues)
|
||||
if (cl - 1 > QD_NUM(hw))
|
||||
return -ENOENT;
|
||||
tcm->tcm_handle = TC_H_MIN(cl);
|
||||
tcm->tcm_parent = qd->handle;
|
||||
|
@ -540,7 +516,7 @@ static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg)
|
|||
if (arg->stop)
|
||||
return;
|
||||
|
||||
for (queue = 0; queue < hw->queues; queue++) {
|
||||
for (queue = 0; queue < QD_NUM(hw); queue++) {
|
||||
if (arg->count < arg->skip) {
|
||||
arg->count++;
|
||||
continue;
|
||||
|
@ -657,10 +633,13 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,
|
|||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
/* prepare the filter and save it for the SW queue
|
||||
* matching the recieved HW queue */
|
||||
* matching the received HW queue */
|
||||
|
||||
if (!local->hw.ampdu_queues)
|
||||
return -EPERM;
|
||||
|
||||
/* try to get a Qdisc from the pool */
|
||||
for (i = IEEE80211_TX_QUEUE_BEACON; i < local->hw.queues; i++)
|
||||
for (i = local->hw.queues; i < QD_NUM(&local->hw); i++)
|
||||
if (!test_and_set_bit(i, q->qdisc_pool)) {
|
||||
ieee80211_stop_queue(local_to_hw(local), i);
|
||||
sta->tid_to_tx_q[tid] = i;
|
||||
|
@ -689,13 +668,14 @@ void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local,
|
|||
struct sta_info *sta, u16 tid,
|
||||
u8 requeue)
|
||||
{
|
||||
struct ieee80211_hw *hw = &local->hw;
|
||||
struct ieee80211_sched_data *q =
|
||||
qdisc_priv(local->mdev->qdisc_sleeping);
|
||||
int agg_queue = sta->tid_to_tx_q[tid];
|
||||
|
||||
/* return the qdisc to the pool */
|
||||
clear_bit(agg_queue, q->qdisc_pool);
|
||||
sta->tid_to_tx_q[tid] = local->hw.queues;
|
||||
sta->tid_to_tx_q[tid] = QD_NUM(hw);
|
||||
|
||||
if (requeue)
|
||||
ieee80211_requeue(local, agg_queue);
|
||||
|
|
Loading…
Reference in New Issue