1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
From 3d1d6d96f14881c421860973b4eb4b2fff7cb812 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <Jes.Sorensen@redhat.com>
Date: Wed, 5 Oct 2016 16:04:54 -0400
Subject: [PATCH] rtl8xxxu: Obtain RTS rates from mac80211
Use the mac80211 provided rate for RTS rather than the hard coded
24Mbps as suggested by the vendor drivers.
Reported-by: Andrea Merello <andrea.merello@gmail.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
---
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 6 +--
.../net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 46 ++++++++++++++--------
2 files changed, 32 insertions(+), 20 deletions(-)
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -1340,7 +1340,7 @@ struct rtl8xxxu_fileops {
void (*fill_txdesc) (struct ieee80211_hdr *hdr,
struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
u16 rate_flag, bool sgi, bool short_preamble,
- bool ampdu_enable);
+ bool ampdu_enable, u32 rts_rate);
int writeN_block_size;
int rx_agg_buf_size;
char tx_desc_size;
@@ -1437,11 +1437,11 @@ bool rtl8xxxu_gen2_simularity_compare(st
void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr,
struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
u16 rate_flag, bool sgi, bool short_preamble,
- bool ampdu_enable);
+ bool ampdu_enable, u32 rts_rate);
void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr,
struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate,
u16 rate_flag, bool sgi, bool short_preamble,
- bool ampdu_enable);
+ bool ampdu_enable, u32 rts_rate);
extern struct rtl8xxxu_fileops rtl8192cu_fops;
extern struct rtl8xxxu_fileops rtl8192eu_fops;
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -4762,7 +4762,7 @@ void
rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr,
struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
u16 rate_flag, bool sgi, bool short_preamble,
- bool ampdu_enable)
+ bool ampdu_enable, u32 rts_rate)
{
u16 seq_number;
@@ -4796,15 +4796,16 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211
if (sgi)
tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI);
+ /*
+ * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
+ */
+ tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT);
if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
- /*
- * Use RTS rate 24M - does the mac80211 tell
- * us which to use?
- */
- tx_desc->txdw4 |= cpu_to_le32(DESC_RATE_24M <<
- TXDESC32_RTS_RATE_SHIFT);
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE);
tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE);
+ } else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC32_CTS_SELF_ENABLE);
+ tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE);
}
}
@@ -4816,7 +4817,7 @@ void
rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr,
struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate,
u16 rate_flag, bool sgi, bool short_preamble,
- bool ampdu_enable)
+ bool ampdu_enable, u32 rts_rate)
{
struct rtl8xxxu_txdesc40 *tx_desc40;
u16 seq_number;
@@ -4849,15 +4850,19 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211
if (short_preamble)
tx_desc40->txdw5 |= cpu_to_le32(TXDESC40_SHORT_PREAMBLE);
+ tx_desc40->txdw4 |= cpu_to_le32(rts_rate << TXDESC40_RTS_RATE_SHIFT);
+ /*
+ * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
+ */
if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
- /*
- * Use RTS rate 24M - does the mac80211 tell
- * us which to use?
- */
- tx_desc40->txdw4 |= cpu_to_le32(DESC_RATE_24M <<
- TXDESC40_RTS_RATE_SHIFT);
tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_RTS_CTS_ENABLE);
tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_HW_RTS_ENABLE);
+ } else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ /*
+ * For some reason the vendor driver doesn't set
+ * TXDESC40_HW_RTS_ENABLE for CTS to SELF
+ */
+ tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_CTS_SELF_ENABLE);
}
}
@@ -4874,7 +4879,7 @@ static void rtl8xxxu_tx(struct ieee80211
struct ieee80211_sta *sta = NULL;
struct ieee80211_vif *vif = tx_info->control.vif;
struct device *dev = &priv->udev->dev;
- u32 queue, rate;
+ u32 queue, rate, rts_rate;
u16 pktlen = skb->len;
u16 seq_number;
u16 rate_flag = tx_info->control.rates[0].flags;
@@ -4974,10 +4979,17 @@ static void rtl8xxxu_tx(struct ieee80211
(sta && vif && vif->bss_conf.use_short_preamble))
short_preamble = true;
+ if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS)
+ rts_rate = ieee80211_get_rts_cts_rate(hw, tx_info)->hw_value;
+ else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT)
+ rts_rate = ieee80211_get_rts_cts_rate(hw, tx_info)->hw_value;
+ else
+ rts_rate = 0;
+
seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
- priv->fops->fill_txdesc(hdr, tx_desc, rate, rate_flag,
- sgi, short_preamble, ampdu_enable);
+ priv->fops->fill_txdesc(hdr, tx_desc, rate, rate_flag, sgi,
+ short_preamble, ampdu_enable, rts_rate);
rtl8xxxu_calc_tx_desc_csum(tx_desc);
|