aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl818x/rtl8180/dev.c
diff options
context:
space:
mode:
authorAndrea Merello <andrea.merello@gmail.com>2014-03-26 16:00:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-03-27 14:20:08 -0400
commit3ee44d6011f5df36c9b062cbf25536c3691235e3 (patch)
treed8b278507f4407fd5aabb52b8e23bf3635b05174 /drivers/net/wireless/rtl818x/rtl8180/dev.c
parentf18f112bde931faa25b33f7fa97281be5ef5e2c4 (diff)
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>
Diffstat (limited to 'drivers/net/wireless/rtl818x/rtl8180/dev.c')
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c84
1 files changed, 79 insertions, 5 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index cce972d289ef..eb86ede246d2 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -85,6 +85,52 @@ static const struct ieee80211_channel rtl818x_channels[] = {
85 { .center_freq = 2484 }, 85 { .center_freq = 2484 },
86}; 86};
87 87
88/* Queues for rtl8187se card
89 *
90 * name | reg | queue
91 * BC | 7 | 6
92 * MG | 1 | 0
93 * HI | 6 | 1
94 * VO | 5 | 2
95 * VI | 4 | 3
96 * BE | 3 | 4
97 * BK | 2 | 5
98 *
99 * The complete map for DMA kick reg using use all queue is:
100 * static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] =
101 * {1, 6, 5, 4, 3, 2, 7};
102 *
103 * .. but.. Because for mac80211 4 queues are enough for QoS we use this
104 *
105 * name | reg | queue
106 * BC | 7 | 4 <- currently not used yet
107 * MG | 1 | x <- Not used
108 * HI | 6 | x <- Not used
109 * VO | 5 | 0 <- used
110 * VI | 4 | 1 <- used
111 * BE | 3 | 2 <- used
112 * BK | 2 | 3 <- used
113 *
114 * Beacon queue could be used, but this is not finished yet.
115 *
116 * I thougth about using the other two queues but I decided not to do this:
117 *
118 * - I'm unsure whether the mac80211 will ever try to use more than 4 queues
119 * by itself.
120 *
121 * - I could route MGMT frames (currently sent over VO queue) to the MGMT
122 * queue but since mac80211 will do not know about it, I will probably gain
123 * some HW priority whenever the VO queue is not empty, but this gain is
124 * limited by the fact that I had to stop the mac80211 queue whenever one of
125 * the VO or MGMT queues is full, stopping also submitting of MGMT frame
126 * to the driver.
127 *
128 * - I don't know how to set in the HW the contention window params for MGMT
129 * and HI-prio queues.
130 */
131
132static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] = {5, 4, 3, 2, 7};
133
88/* Queues for rtl8180/rtl8185 cards 134/* Queues for rtl8180/rtl8185 cards
89 * 135 *
90 * name | reg | prio 136 * name | reg | prio
@@ -358,6 +404,8 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
358 u8 rc_flags; 404 u8 rc_flags;
359 u16 plcp_len = 0; 405 u16 plcp_len = 0;
360 __le16 rts_duration = 0; 406 __le16 rts_duration = 0;
407 /* do arithmetic and then convert to le16 */
408 u16 frame_duration = 0;
361 409
362 prio = skb_get_queue_mapping(skb); 410 prio = skb_get_queue_mapping(skb);
363 ring = &priv->tx_ring[prio]; 411 ring = &priv->tx_ring[prio];
@@ -369,7 +417,6 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
369 kfree_skb(skb); 417 kfree_skb(skb);
370 dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); 418 dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
371 return; 419 return;
372
373 } 420 }
374 421
375 tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | 422 tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS |
@@ -405,6 +452,18 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
405 plcp_len |= 1 << 15; 452 plcp_len |= 1 << 15;
406 } 453 }
407 454
455 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
456 __le16 duration;
457 /* SIFS time (required by HW) is already included by
458 * ieee80211_generic_frame_duration
459 */
460 duration = ieee80211_generic_frame_duration(dev, priv->vif,
461 IEEE80211_BAND_2GHZ, skb->len,
462 ieee80211_get_tx_rate(dev, info));
463
464 frame_duration = priv->ack_time + le16_to_cpu(duration);
465 }
466
408 spin_lock_irqsave(&priv->lock, flags); 467 spin_lock_irqsave(&priv->lock, flags);
409 468
410 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 469 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -417,10 +476,19 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
417 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; 476 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
418 entry = &ring->desc[idx]; 477 entry = &ring->desc[idx];
419 478
479 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
480 entry->frame_duration = cpu_to_le16(frame_duration);
481 entry->frame_len_se = cpu_to_le16(skb->len);
482
483 /* tpc polarity */
484 entry->flags3 = cpu_to_le16(1<<4);
485 } else
486 entry->frame_len = cpu_to_le32(skb->len);
487
420 entry->rts_duration = rts_duration; 488 entry->rts_duration = rts_duration;
421 entry->plcp_len = cpu_to_le16(plcp_len); 489 entry->plcp_len = cpu_to_le16(plcp_len);
422 entry->tx_buf = cpu_to_le32(mapping); 490 entry->tx_buf = cpu_to_le32(mapping);
423 entry->frame_len = cpu_to_le32(skb->len); 491
424 entry->flags2 = info->control.rates[1].idx >= 0 ? 492 entry->flags2 = info->control.rates[1].idx >= 0 ?
425 ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; 493 ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
426 entry->retry_limit = info->control.rates[0].count; 494 entry->retry_limit = info->control.rates[0].count;
@@ -442,11 +510,17 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
442 510
443 spin_unlock_irqrestore(&priv->lock, flags); 511 spin_unlock_irqrestore(&priv->lock, flags);
444 512
445 hw_prio = rtl8180_queues_map[prio]; 513 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
446 514 /* just poll: rings are stopped with TPPollStop reg */
447 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, 515 hw_prio = rtl8187se_queues_map[prio];
516 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING,
517 (1 << hw_prio));
518 } else {
519 hw_prio = rtl8180_queues_map[prio];
520 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING,
448 (1 << hw_prio) | /* ring to poll */ 521 (1 << hw_prio) | /* ring to poll */
449 (1<<1) | (1<<2));/* stopped rings */ 522 (1<<1) | (1<<2));/* stopped rings */
523 }
450} 524}
451 525
452void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) 526void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam)