rtl8180: add TX queue mapping and support for rtl8187se

This patch adds tx queue mapping for rtl8187se and a long comment
block about their usages.
It adapts the TX function to use that map and it sets properly
the TX descriptor rtl8187se-only fields

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Andrea Merello 2014-03-26 21:00:57 +01:00 committed by John W. Linville
parent f18f112bde
commit 3ee44d6011
2 changed files with 88 additions and 6 deletions

View File

@ -85,6 +85,52 @@ static const struct ieee80211_channel rtl818x_channels[] = {
{ .center_freq = 2484 },
};
/* Queues for rtl8187se card
*
* name | reg | queue
* BC | 7 | 6
* MG | 1 | 0
* HI | 6 | 1
* VO | 5 | 2
* VI | 4 | 3
* BE | 3 | 4
* BK | 2 | 5
*
* The complete map for DMA kick reg using use all queue is:
* static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] =
* {1, 6, 5, 4, 3, 2, 7};
*
* .. but.. Because for mac80211 4 queues are enough for QoS we use this
*
* name | reg | queue
* BC | 7 | 4 <- currently not used yet
* MG | 1 | x <- Not used
* HI | 6 | x <- Not used
* VO | 5 | 0 <- used
* VI | 4 | 1 <- used
* BE | 3 | 2 <- used
* BK | 2 | 3 <- used
*
* Beacon queue could be used, but this is not finished yet.
*
* I thougth about using the other two queues but I decided not to do this:
*
* - I'm unsure whether the mac80211 will ever try to use more than 4 queues
* by itself.
*
* - I could route MGMT frames (currently sent over VO queue) to the MGMT
* queue but since mac80211 will do not know about it, I will probably gain
* some HW priority whenever the VO queue is not empty, but this gain is
* limited by the fact that I had to stop the mac80211 queue whenever one of
* the VO or MGMT queues is full, stopping also submitting of MGMT frame
* to the driver.
*
* - I don't know how to set in the HW the contention window params for MGMT
* and HI-prio queues.
*/
static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] = {5, 4, 3, 2, 7};
/* Queues for rtl8180/rtl8185 cards
*
* name | reg | prio
@ -358,6 +404,8 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
u8 rc_flags;
u16 plcp_len = 0;
__le16 rts_duration = 0;
/* do arithmetic and then convert to le16 */
u16 frame_duration = 0;
prio = skb_get_queue_mapping(skb);
ring = &priv->tx_ring[prio];
@ -369,7 +417,6 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
kfree_skb(skb);
dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
return;
}
tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS |
@ -405,6 +452,18 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
plcp_len |= 1 << 15;
}
if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
__le16 duration;
/* SIFS time (required by HW) is already included by
* ieee80211_generic_frame_duration
*/
duration = ieee80211_generic_frame_duration(dev, priv->vif,
IEEE80211_BAND_2GHZ, skb->len,
ieee80211_get_tx_rate(dev, info));
frame_duration = priv->ack_time + le16_to_cpu(duration);
}
spin_lock_irqsave(&priv->lock, flags);
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@ -417,10 +476,19 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
entry = &ring->desc[idx];
if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
entry->frame_duration = cpu_to_le16(frame_duration);
entry->frame_len_se = cpu_to_le16(skb->len);
/* tpc polarity */
entry->flags3 = cpu_to_le16(1<<4);
} else
entry->frame_len = cpu_to_le32(skb->len);
entry->rts_duration = rts_duration;
entry->plcp_len = cpu_to_le16(plcp_len);
entry->tx_buf = cpu_to_le32(mapping);
entry->frame_len = cpu_to_le32(skb->len);
entry->flags2 = info->control.rates[1].idx >= 0 ?
ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
entry->retry_limit = info->control.rates[0].count;
@ -442,12 +510,18 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
spin_unlock_irqrestore(&priv->lock, flags);
if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
/* just poll: rings are stopped with TPPollStop reg */
hw_prio = rtl8187se_queues_map[prio];
rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING,
(1 << hw_prio));
} else {
hw_prio = rtl8180_queues_map[prio];
rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING,
(1 << hw_prio) | /* ring to poll */
(1<<1) | (1<<2));/* stopped rings */
}
}
void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam)
{

View File

@ -29,6 +29,14 @@
*/
#define RTL8180_NR_TX_QUEUES 2
/* rtl8187SE have 6 queues + beacon queues
* mac80211 can use 4 QoS data queue, + beacon = 5 tot
*/
#define RTL8187SE_NR_TX_QUEUES 5
/* for array static allocation, it is the max of above */
#define RTL818X_NR_TX_QUEUES 5
struct rtl8180_tx_desc {
__le32 flags;
__le16 rts_duration;
@ -105,7 +113,7 @@ struct rtl8180_priv {
dma_addr_t rx_ring_dma;
unsigned int rx_idx;
struct sk_buff *rx_buf[32];
struct rtl8180_tx_ring tx_ring[RTL8180_NR_TX_QUEUES];
struct rtl8180_tx_ring tx_ring[RTL818X_NR_TX_QUEUES];
struct ieee80211_channel channels[14];
struct ieee80211_rate rates[12];
struct ieee80211_supported_band band;