Skip to content

Commit a2a676e

Browse files
authored
Fix for TX in 40 MHz Bandwidth mode (#14)
1 parent 317961a commit a2a676e

File tree

2 files changed

+44
-70
lines changed

2 files changed

+44
-70
lines changed

src/RadioManagementModule.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ int get_40mhz_center_channel(int channel) {
3131
{132, 134}, {136, 134},
3232
{140, 142}, {144, 142},
3333
// 5GHz UNII-3
34-
{149, 151}, {153, 151},
35-
{157, 159}, {161, 159}
34+
{149, 151}, {153, 155},
35+
{157, 159}, {161, 163}
3636
};
3737

3838
auto it = channel_map.find(channel);

src/Rtl8812aDevice.cpp

Lines changed: 42 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,12 @@ bool Rtl8812aDevice::send_packet(const uint8_t *packet, size_t length) {
2020
struct tx_desc *ptxdesc;
2121
bool resp;
2222
uint8_t *usb_frame;
23-
// struct ieee80211_radiotap_header *rtap_hdr;
2423
int real_packet_length, usb_frame_length, radiotap_length;
2524

2625
bool vht = false;
2726
int ret = 0;
2827
int qos_len = 0;
29-
int dot11_hdr_len = 24;
30-
int snap_len = 6;
31-
unsigned char *pdata;
32-
u16 frame_ctl;
33-
unsigned char src_mac_addr[6];
34-
unsigned char dst_mac_addr[6];
35-
u8 fixed_rate = MGN_1M, sgi = 0,
36-
bwidth = 0,
37-
ldpc = 0, stbc = 0;
28+
u8 fixed_rate = MGN_1M, sgi = 0, bwidth = 0, ldpc = 0, stbc = 0;
3829
u16 txflags = 0;
3930
int rate_id = 0;
4031
radiotap_length = int(packet[2]);
@@ -63,40 +54,34 @@ bool Rtl8812aDevice::send_packet(const uint8_t *packet, size_t length) {
6354
/* see if this argument is something we can use */
6455
switch (iterator.this_arg_index) {
6556

66-
case IEEE80211_RADIOTAP_RATE: /* u8 */
57+
case IEEE80211_RADIOTAP_RATE:
6758
fixed_rate = *iterator.this_arg;
6859
break;
6960

7061
case IEEE80211_RADIOTAP_TX_FLAGS:
7162
txflags = get_unaligned_le16(iterator.this_arg);
7263
break;
7364

74-
case IEEE80211_RADIOTAP_MCS: { /* u8,u8,u8 */
75-
u8 mcs_have = iterator.this_arg[0];
76-
printf("MCS value:%d %d %d\n", iterator.this_arg[0], iterator.this_arg[1],
77-
iterator.this_arg[2]);
78-
printf("mcs parse:%d\n", mcs_have);
79-
if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
80-
fixed_rate = iterator.this_arg[2] & 0x7f;
81-
if (fixed_rate > 31)
82-
fixed_rate = 0;
83-
fixed_rate += MGN_MCS0;
65+
case IEEE80211_RADIOTAP_MCS: {
66+
u8 mcs_flags = iterator.this_arg[1];
67+
68+
uint8_t mcs_bw_field = mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK;
69+
if (mcs_bw_field == IEEE80211_RADIOTAP_MCS_BW_40) {
70+
bwidth = CHANNEL_WIDTH_40;
71+
} else if (mcs_bw_field == IEEE80211_RADIOTAP_MCS_BW_20 ||
72+
mcs_bw_field == IEEE80211_RADIOTAP_MCS_BW_20L ||
73+
mcs_bw_field == IEEE80211_RADIOTAP_MCS_BW_20U) {
74+
bwidth = CHANNEL_WIDTH_20;
8475
}
85-
printf("mcs_have & 4 = %d,%d \n", (mcs_have & 4),
86-
(iterator.this_arg[1] & 1));
87-
if ((mcs_have & 4) && (iterator.this_arg[1] & 4))
76+
77+
if (mcs_flags & 0x04) {
8878
sgi = 1;
89-
if ((mcs_have & 1) && (iterator.this_arg[1] & 1))
90-
bwidth = 1;
91-
if ((mcs_have & 0x10) && (iterator.this_arg[1] & 0x10))
92-
ldpc = 1;
93-
if ((mcs_have & 0x20))
94-
stbc = (iterator.this_arg[1] >> 5) & 3;
79+
} else {
80+
sgi = 0;
81+
}
9582
} break;
9683

9784
case IEEE80211_RADIOTAP_VHT: {
98-
/* u16 known, u8 flags, u8 bandwidth, u8 mcs_nss[4], u8 coding, u8
99-
* group_id, u16 partial_aid */
10085
u8 known = iterator.this_arg[0];
10186
u8 flags = iterator.this_arg[2];
10287
unsigned int mcs, nss;
@@ -107,11 +92,11 @@ bool Rtl8812aDevice::send_packet(const uint8_t *packet, size_t length) {
10792
if (known & 0x40) {
10893
auto bw = iterator.this_arg[3] & 0x1f;
10994
if (bw >= 1 && bw <= 3)
110-
bwidth = 40; // 40 MHz
95+
bwidth = 40;
11196
else if (bw >= 4 && bw <= 10)
112-
bwidth = 80; // 80 MHz
97+
bwidth = 80;
11398
else
114-
bwidth = 20; // 20 MHz
99+
bwidth = 20;
115100
}
116101

117102
if (iterator.this_arg[8] & 1)
@@ -132,13 +117,26 @@ bool Rtl8812aDevice::send_packet(const uint8_t *packet, size_t length) {
132117
}
133118
}
134119

135-
printf("fixed rate:%d\n", fixed_rate);
136-
printf("sgi =%d,bandwdith=%d,ldpc=%d,stbc=%d\n", sgi, bwidth, ldpc, stbc);
137-
138120
usb_frame = new uint8_t[usb_frame_length]();
139121

140122
ptxdesc = (struct tx_desc *)usb_frame;
141123

124+
_logger->info("fixed rate:{}, sgi:{}, radiotap_bwidth:{}, ldpc:{}, stbc:{}",
125+
(int)fixed_rate, (int)sgi, (int)bwidth, (int)ldpc, (int)stbc);
126+
127+
uint8_t BWSettingOfDesc;
128+
if (bwidth == CHANNEL_WIDTH_40) {
129+
BWSettingOfDesc = 1;
130+
} else if (bwidth == CHANNEL_WIDTH_80) {
131+
BWSettingOfDesc = 2;
132+
} else {
133+
BWSettingOfDesc = 0;
134+
}
135+
_logger->info("TX DESC BW decision: _channel.ChannelWidth(RX)={}, radiotap_bwidth(TX)={}, BWSettingOfDesc(TX_DESC)={}",
136+
(int)_channel.ChannelWidth, (int)bwidth, (int)BWSettingOfDesc);
137+
138+
SET_TX_DESC_DATA_BW_8812(usb_frame, BWSettingOfDesc);
139+
142140
SET_TX_DESC_FIRST_SEG_8812(usb_frame, 1);
143141
SET_TX_DESC_LAST_SEG_8812(usb_frame, 1);
144142
SET_TX_DESC_OWN_8812(usb_frame, 1);
@@ -160,15 +158,15 @@ bool Rtl8812aDevice::send_packet(const uint8_t *packet, size_t length) {
160158
SET_TX_DESC_BMC_8812(usb_frame, 1);
161159
SET_TX_DESC_RATE_ID_8812(
162160
usb_frame,
163-
static_cast<uint8_t>(rate_id)); // Originally set to 7, need to reconsider
161+
static_cast<uint8_t>(rate_id));
164162

165163
SET_TX_DESC_QUEUE_SEL_8812(usb_frame, 0x12);
166164
SET_TX_DESC_HWSEQ_EN_8812(
167-
usb_frame, static_cast<uint8_t>(0)); /* Hw do not set sequence number */
165+
usb_frame, static_cast<uint8_t>(0));
168166
SET_TX_DESC_SEQ_8812(
169167
usb_frame,
170168
GetSequence(packet +
171-
radiotap_length)); /* Copy inject sequence number to TxDesc */
169+
radiotap_length));
172170
SET_TX_DESC_RETRY_LIMIT_ENABLE_8812(usb_frame, static_cast<uint8_t>(1));
173171

174172
SET_TX_DESC_DATA_RETRY_LIMIT_8812(usb_frame, static_cast<uint8_t>(0));
@@ -180,64 +178,40 @@ bool Rtl8812aDevice::send_packet(const uint8_t *packet, size_t length) {
180178
SET_TX_DESC_USE_RATE_8812(usb_frame, 1);
181179
SET_TX_DESC_TX_RATE_8812(usb_frame,
182180
static_cast<uint8_t>(MRateToHwRate(
183-
fixed_rate))); // Originally set to 6, also need
184-
// to reconsider how to convert
181+
fixed_rate)));
185182

186183
if (ldpc) {
187184
SET_TX_DESC_DATA_LDPC_8812(usb_frame, ldpc);
188185
}
189186

190187
SET_TX_DESC_DATA_STBC_8812(usb_frame, stbc & 3);
191188

192-
uint8_t BWSettingOfDesc;
193-
if (_channel.ChannelWidth == CHANNEL_WIDTH_80) {
194-
if (bwidth == 80)
195-
BWSettingOfDesc = 2;
196-
else if (bwidth == 40)
197-
BWSettingOfDesc = 1;
198-
else
199-
BWSettingOfDesc = 0;
200-
} else if (_channel.ChannelWidth == CHANNEL_WIDTH_40) {
201-
if ((bwidth == 40) || (bwidth == 80))
202-
BWSettingOfDesc = 1;
203-
else
204-
BWSettingOfDesc = 0;
205-
} else
206-
BWSettingOfDesc = 0;
207-
208-
SET_TX_DESC_DATA_BW_8812(usb_frame, BWSettingOfDesc);
209-
210189
rtl8812a_cal_txdesc_chksum(usb_frame);
211190
_logger->info("tx desc formed");
212191
#ifdef DEBUG
213192
for (size_t i = 0; i < usb_frame_length; ++i) {
214-
// Print each byte as a two-digit hexadecimal number
215193
std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0')
216194
<< static_cast<int>(usb_frame[i]);
217195

218-
// Print a space between bytes, but not after the last byte
219196
if (i < usb_frame_length - 1) {
220197
std::cout << ",";
221198
}
222199
}
223-
std::cout << std::dec << std::endl; // Reset to decimal formatting
224-
// ----- end of fill tx desc -----
200+
std::cout << std::dec << std::endl;
225201
#endif
226202
uint8_t *addr = usb_frame + TXDESC_SIZE;
227203
memcpy(addr, packet + radiotap_length, real_packet_length);
228204
_logger->info("packet formed");
229205
#ifdef DEBUG
230206
for (size_t i = 0; i < usb_frame_length; ++i) {
231-
// Print each byte as a two-digit hexadecimal number
232207
std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0')
233208
<< static_cast<int>(usb_frame[i]);
234209

235-
// Print a space between bytes, but not after the last byte
236210
if (i < usb_frame_length - 1) {
237211
std::cout << ",";
238212
}
239213
}
240-
std::cout << std::dec << std::endl; // Reset to decimal formatting
214+
std::cout << std::dec << std::endl;
241215
#endif
242216
resp = _device.send_packet(usb_frame, usb_frame_length);
243217
delete[] usb_frame;

0 commit comments

Comments
 (0)