aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-04-03 10:28:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-11 16:23:50 -0400
commit3a25a8c8b75b430c4f4022918e26fa51d557ecde (patch)
treed4863b7f17c2ea44fb523e29951b6bd202ddb1ad /include
parent4b6f1dd6a6faf4ed8d209bbd548e78b15e55aee8 (diff)
mac80211: add improved HW queue control
mac80211 currently only supports one hardware queue per AC. This is already problematic for off-channel uses since if we go off channel while the BE queue is full and then try to send an off-channel frame the frame will never go out. This will become worse when we support multi-channel since then a queue on one channel might be full, but we have to stop the software queue for all channels. That is obviously not desirable. To address this problem allow drivers to register more hardware queues, and allow them to map them to virtual interfaces. When they stop a hardware queue the corresponding AC software queues on the correct interfaces will be stopped as well. Additionally, there's an off-channel queue to solve that problem and a per-interface after-DTIM beacon queue. This allows drivers to manage software queues closer to how the hardware works. Currently, there's a limit of 16 hardware queues. This may or may not be sufficient, we can adjust it as needed. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'include')
-rw-r--r--include/net/mac80211.h81
1 files changed, 77 insertions, 4 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 2956a206235f..ec4995d0c14d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -95,9 +95,11 @@ struct device;
95 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. 95 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
96 */ 96 */
97enum ieee80211_max_queues { 97enum ieee80211_max_queues {
98 IEEE80211_MAX_QUEUES = 4, 98 IEEE80211_MAX_QUEUES = 16,
99}; 99};
100 100
101#define IEEE80211_INVAL_HW_QUEUE 0xff
102
101/** 103/**
102 * enum ieee80211_ac_numbers - AC numbers as used in mac80211 104 * enum ieee80211_ac_numbers - AC numbers as used in mac80211
103 * @IEEE80211_AC_VO: voice 105 * @IEEE80211_AC_VO: voice
@@ -522,7 +524,7 @@ struct ieee80211_tx_rate {
522 * 524 *
523 * @flags: transmit info flags, defined above 525 * @flags: transmit info flags, defined above
524 * @band: the band to transmit on (use for checking for races) 526 * @band: the band to transmit on (use for checking for races)
525 * @reserved: reserved for future use 527 * @hw_queue: HW queue to put the frame on, skb_get_queue_mapping() gives the AC
526 * @ack_frame_id: internal frame ID for TX status, used internally 528 * @ack_frame_id: internal frame ID for TX status, used internally
527 * @control: union for control data 529 * @control: union for control data
528 * @status: union for status data 530 * @status: union for status data
@@ -538,7 +540,7 @@ struct ieee80211_tx_info {
538 u32 flags; 540 u32 flags;
539 u8 band; 541 u8 band;
540 542
541 u8 reserved; 543 u8 hw_queue;
542 544
543 u16 ack_frame_id; 545 u16 ack_frame_id;
544 546
@@ -889,6 +891,8 @@ enum ieee80211_vif_flags {
889 * these need to be set (or cleared) when the interface is added 891 * these need to be set (or cleared) when the interface is added
890 * or, if supported by the driver, the interface type is changed 892 * or, if supported by the driver, the interface type is changed
891 * at runtime, mac80211 will never touch this field 893 * at runtime, mac80211 will never touch this field
894 * @hw_queue: hardware queue for each AC
895 * @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only
892 * @drv_priv: data area for driver use, will always be aligned to 896 * @drv_priv: data area for driver use, will always be aligned to
893 * sizeof(void *). 897 * sizeof(void *).
894 */ 898 */
@@ -897,7 +901,12 @@ struct ieee80211_vif {
897 struct ieee80211_bss_conf bss_conf; 901 struct ieee80211_bss_conf bss_conf;
898 u8 addr[ETH_ALEN]; 902 u8 addr[ETH_ALEN];
899 bool p2p; 903 bool p2p;
904
905 u8 cab_queue;
906 u8 hw_queue[IEEE80211_NUM_ACS];
907
900 u32 driver_flags; 908 u32 driver_flags;
909
901 /* must be last */ 910 /* must be last */
902 u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); 911 u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
903}; 912};
@@ -1179,6 +1188,11 @@ enum sta_notify_cmd {
1179 * @IEEE80211_HW_WANT_MONITOR_VIF: The driver would like to be informed of 1188 * @IEEE80211_HW_WANT_MONITOR_VIF: The driver would like to be informed of
1180 * a virtual monitor interface when monitor interfaces are the only 1189 * a virtual monitor interface when monitor interfaces are the only
1181 * active interfaces. 1190 * active interfaces.
1191 *
1192 * @IEEE80211_HW_QUEUE_CONTROL: The driver wants to control per-interface
1193 * queue mapping in order to use different queues (not just one per AC)
1194 * for different virtual interfaces. See the doc section on HW queue
1195 * control for more details.
1182 */ 1196 */
1183enum ieee80211_hw_flags { 1197enum ieee80211_hw_flags {
1184 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, 1198 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -1201,7 +1215,7 @@ enum ieee80211_hw_flags {
1201 IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, 1215 IEEE80211_HW_SUPPORTS_UAPSD = 1<<17,
1202 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, 1216 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18,
1203 IEEE80211_HW_CONNECTION_MONITOR = 1<<19, 1217 IEEE80211_HW_CONNECTION_MONITOR = 1<<19,
1204 /* reuse bit 20 */ 1218 IEEE80211_HW_QUEUE_CONTROL = 1<<20,
1205 IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, 1219 IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21,
1206 IEEE80211_HW_AP_LINK_PS = 1<<22, 1220 IEEE80211_HW_AP_LINK_PS = 1<<22,
1207 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, 1221 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23,
@@ -1271,6 +1285,9 @@ enum ieee80211_hw_flags {
1271 * @max_tx_aggregation_subframes: maximum number of subframes in an 1285 * @max_tx_aggregation_subframes: maximum number of subframes in an
1272 * aggregate an HT driver will transmit, used by the peer as a 1286 * aggregate an HT driver will transmit, used by the peer as a
1273 * hint to size its reorder buffer. 1287 * hint to size its reorder buffer.
1288 *
1289 * @offchannel_tx_hw_queue: HW queue ID to use for offchannel TX
1290 * (if %IEEE80211_HW_QUEUE_CONTROL is set)
1274 */ 1291 */
1275struct ieee80211_hw { 1292struct ieee80211_hw {
1276 struct ieee80211_conf conf; 1293 struct ieee80211_conf conf;
@@ -1291,6 +1308,7 @@ struct ieee80211_hw {
1291 u8 max_rate_tries; 1308 u8 max_rate_tries;
1292 u8 max_rx_aggregation_subframes; 1309 u8 max_rx_aggregation_subframes;
1293 u8 max_tx_aggregation_subframes; 1310 u8 max_tx_aggregation_subframes;
1311 u8 offchannel_tx_hw_queue;
1294}; 1312};
1295 1313
1296/** 1314/**
@@ -1699,6 +1717,61 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
1699 */ 1717 */
1700 1718
1701/** 1719/**
1720 * DOC: HW queue control
1721 *
1722 * Before HW queue control was introduced, mac80211 only had a single static
1723 * assignment of per-interface AC software queues to hardware queues. This
1724 * was problematic for a few reasons:
1725 * 1) off-channel transmissions might get stuck behind other frames
1726 * 2) multiple virtual interfaces couldn't be handled correctly
1727 * 3) after-DTIM frames could get stuck behind other frames
1728 *
1729 * To solve this, hardware typically uses multiple different queues for all
1730 * the different usages, and this needs to be propagated into mac80211 so it
1731 * won't have the same problem with the software queues.
1732 *
1733 * Therefore, mac80211 now offers the %IEEE80211_HW_QUEUE_CONTROL capability
1734 * flag that tells it that the driver implements its own queue control. To do
1735 * so, the driver will set up the various queues in each &struct ieee80211_vif
1736 * and the offchannel queue in &struct ieee80211_hw. In response, mac80211 will
1737 * use those queue IDs in the hw_queue field of &struct ieee80211_tx_info and
1738 * if necessary will queue the frame on the right software queue that mirrors
1739 * the hardware queue.
1740 * Additionally, the driver has to then use these HW queue IDs for the queue
1741 * management functions (ieee80211_stop_queue() et al.)
1742 *
1743 * The driver is free to set up the queue mappings as needed, multiple virtual
1744 * interfaces may map to the same hardware queues if needed. The setup has to
1745 * happen during add_interface or change_interface callbacks. For example, a
1746 * driver supporting station+station and station+AP modes might decide to have
1747 * 10 hardware queues to handle different scenarios:
1748 *
1749 * 4 AC HW queues for 1st vif: 0, 1, 2, 3
1750 * 4 AC HW queues for 2nd vif: 4, 5, 6, 7
1751 * after-DTIM queue for AP: 8
1752 * off-channel queue: 9
1753 *
1754 * It would then set up the hardware like this:
1755 * hw.offchannel_tx_hw_queue = 9
1756 *
1757 * and the first virtual interface that is added as follows:
1758 * vif.hw_queue[IEEE80211_AC_VO] = 0
1759 * vif.hw_queue[IEEE80211_AC_VI] = 1
1760 * vif.hw_queue[IEEE80211_AC_BE] = 2
1761 * vif.hw_queue[IEEE80211_AC_BK] = 3
1762 * vif.cab_queue = 8 // if AP mode, otherwise %IEEE80211_INVAL_HW_QUEUE
1763 * and the second virtual interface with 4-7.
1764 *
1765 * If queue 6 gets full, for example, mac80211 would only stop the second
1766 * virtual interface's BE queue since virtual interface queues are per AC.
1767 *
1768 * Note that the vif.cab_queue value should be set to %IEEE80211_INVAL_HW_QUEUE
1769 * whenever the queue is not used (i.e. the interface is not in AP mode) if the
1770 * queue could potentially be shared since mac80211 will look at cab_queue when
1771 * a queue is stopped/woken even if the interface is not in AP mode.
1772 */
1773
1774/**
1702 * enum ieee80211_filter_flags - hardware filter flags 1775 * enum ieee80211_filter_flags - hardware filter flags
1703 * 1776 *
1704 * These flags determine what the filter in hardware should be 1777 * These flags determine what the filter in hardware should be