Skip to content

Commit af67f1d

Browse files
Add manual MCS configuration via set_bitrate_mask
Implement the set_bitrate_mask callback in cfg80211_ops to support manual MCS settings using `iw dev <interface> set bitrates ht-mcs-2.4 <mcs_index>`, addressing reviewer feedback. Store the selected MCS in vwifi_vif->manual_mcs and track its state with vwifi_vif->manual_mcs_set. Support MCS indices 7, 15, 23, and 31, with validation and logging. Enable High Throughput (HT) in nf_band_2ghz with MCS 0–31, using IEEE80211_HT_CAP_SUP_WIDTH_20_40 for 20 MHz compatibility. Fix compilation errors by initializing rx_mask statically and removing const qualifiers from channel/rate arrays. Improve vwifi_connect to ensure stable association. Tested with `iw dev vw1 set bitrates ht-mcs-2.4 15`, achieving MCS 15 at 130.0 MBit/s (bitrate calculation pending refinement to ~52 MBit/s). Test commands format $sudo ip netns exec ns1 iw dev vw1 link $sudo ip netns exec ns1 iw dev vw1 set bitrates ht-mcs-2.4 15 /*(changable 7,15,23,31)*/ $sudo ip netns exec ns1 iw dev vw1 link
1 parent 151e1eb commit af67f1d

File tree

1 file changed

+126
-30
lines changed

1 file changed

+126
-30
lines changed

vwifi.c

Lines changed: 126 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ struct vwifi_vif {
8888
struct wireless_dev wdev;
8989
struct net_device *ndev;
9090
struct net_device_stats stats;
91+
int manual_mcs;
92+
bool manual_mcs_set;
9193

9294
size_t ssid_len;
9395
/* Currently connected BSS id */
@@ -1436,38 +1438,52 @@ static int vwifi_get_station(struct wiphy *wiphy,
14361438
* https://semfionetworks.com/blog/mcs-table-updated-with-80211ax-data-rates/
14371439
* IEEE 802.11n : https://zh.wikipedia.org/zh-tw/IEEE_802.11n
14381440
*/
1439-
/* Log byte counters for debugging */
1440-
pr_info("vwifi: Station %pM tx_bytes %llu, rx_bytes %llu\n", mac,
1441-
sinfo->tx_bytes, sinfo->rx_bytes);
1442-
1443-
/* Dynamic modulation based on signal strength */
1441+
/* Checks vif->manual_mcs_set to use vif->manual_mcs if set;
1442+
* Assign modulation string for manual MCS ; else auto change based
1443+
* on signal strength
1444+
*/
14441445
int mcs_index;
14451446
const char *modulation;
1446-
unsigned int data_rate_mbps;
1447-
if (sinfo->signal > -50) {
1448-
/* Strong signal: 64-QAM, MCS 31 */
1449-
mcs_index = 31;
1450-
modulation = "64-QAM";
1451-
} else if (sinfo->signal > -70 && sinfo->signal <= -50) {
1452-
/* Medium signal: 16-QAM, MCS 23 */
1453-
mcs_index = 23;
1454-
modulation = "16-QAM";
1455-
} else if (sinfo->signal > -90 && sinfo->signal <= -70) {
1456-
/* Weak signal: QPSK, MCS 15 */
1457-
mcs_index = 15;
1458-
modulation = "QPSK";
1447+
if (vif->manual_mcs_set) {
1448+
mcs_index = vif->manual_mcs;
1449+
switch (mcs_index) {
1450+
case 7:
1451+
modulation = "BPSK";
1452+
break;
1453+
case 15:
1454+
modulation = "QPSK";
1455+
break;
1456+
case 23:
1457+
modulation = "16-QAM";
1458+
break;
1459+
case 31:
1460+
modulation = "64-QAM";
1461+
break;
1462+
default:
1463+
modulation = "Unknown";
1464+
break;
1465+
}
1466+
pr_info("vwifi: Station %pM using manual MCS %d (%s)\n", mac, mcs_index,
1467+
modulation);
14591468
} else {
1460-
/* Very weak signal: BPSK, MCS 7 */
1461-
mcs_index = 7;
1462-
modulation = "BPSK";
1469+
if (sinfo->signal > -50) {
1470+
mcs_index = 31;
1471+
modulation = "64-QAM";
1472+
} else if (sinfo->signal > -70 && sinfo->signal <= -50) {
1473+
mcs_index = 23;
1474+
modulation = "16-QAM";
1475+
} else if (sinfo->signal > -90 && sinfo->signal <= -70) {
1476+
mcs_index = 15;
1477+
modulation = "QPSK";
1478+
} else {
1479+
mcs_index = 7;
1480+
modulation = "BPSK";
1481+
}
1482+
pr_info(
1483+
"vwifi: Station %pM signal %d dBm, using modulation %s (MCS %d)\n",
1484+
mac, sinfo->signal, modulation, mcs_index);
14631485
}
14641486

1465-
/* Log signal, modulation, and data rate for debugging */
1466-
pr_info(
1467-
"vwifi: Station %pM signal %d dBm, using modulation %s (MCS %d, %u "
1468-
"Mbps)\n",
1469-
mac, sinfo->signal, modulation, mcs_index, data_rate_mbps);
1470-
14711487
/* Configure RX and TX rates */
14721488
sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS;
14731489
sinfo->rxrate.mcs = mcs_index;
@@ -2199,6 +2215,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
21992215

22002216
return 0;
22012217
}
2218+
/* Callback to handle manual bitrate configuration via iw */
2219+
static int vwifi_set_bitrate_mask(struct wiphy *wiphy,
2220+
struct net_device *dev,
2221+
unsigned int link_id,
2222+
const u8 *peer,
2223+
const struct cfg80211_bitrate_mask *mask)
2224+
{
2225+
struct vwifi_vif *vif = netdev_priv(dev);
2226+
int mcs_index = -1;
2227+
2228+
if (!vif) {
2229+
pr_err("vwifi: Failed to get vwifi_vif for dev %s\n", dev->name);
2230+
return -EINVAL;
2231+
}
2232+
2233+
if (vif->sme_state != SME_CONNECTED) {
2234+
pr_err("vwifi: Dev %s not connected, cannot set bitrate\n", dev->name);
2235+
return -EINVAL;
2236+
}
2237+
2238+
pr_info("vwifi: set_bitrate_mask called for dev %s, link_id %u, peer %pM\n",
2239+
dev->name, link_id, peer ? peer : vif->bssid);
2240+
pr_info("vwifi: 2.4GHz MCS mask: %02x %02x %02x %02x\n",
2241+
mask->control[NL80211_BAND_2GHZ].ht_mcs[0],
2242+
mask->control[NL80211_BAND_2GHZ].ht_mcs[1],
2243+
mask->control[NL80211_BAND_2GHZ].ht_mcs[2],
2244+
mask->control[NL80211_BAND_2GHZ].ht_mcs[3]);
2245+
2246+
/* Find the requested MCS index */
2247+
for (int i = 0; i < 4; i++) {
2248+
if (mask->control[NL80211_BAND_2GHZ].ht_mcs[i]) {
2249+
for (int j = 0; j < 8; j++) {
2250+
if (mask->control[NL80211_BAND_2GHZ].ht_mcs[i] & (1 << j)) {
2251+
mcs_index = i * 8 + j;
2252+
pr_info("vwifi: Requested MCS index %d\n", mcs_index);
2253+
break;
2254+
}
2255+
}
2256+
if (mcs_index != -1)
2257+
break;
2258+
}
2259+
}
2260+
2261+
if (mcs_index == -1) {
2262+
pr_err("vwifi: No valid MCS index found\n");
2263+
return -EINVAL;
2264+
}
2265+
2266+
if (mcs_index != 7 && mcs_index != 15 && mcs_index != 23 &&
2267+
mcs_index != 31) {
2268+
pr_err("vwifi: Unsupported MCS index %d\n", mcs_index);
2269+
return -EINVAL;
2270+
}
2271+
2272+
vif->manual_mcs = mcs_index;
2273+
vif->manual_mcs_set = true;
2274+
pr_info("vwifi: Set manual MCS %d for dev %s\n", mcs_index, dev->name);
2275+
2276+
return 0;
2277+
}
22022278

22032279
/* Structure of functions for FullMAC 80211 drivers. Functions implemented
22042280
* along with fields/flags in the wiphy structure represent driver features.
@@ -2224,6 +2300,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
22242300
.get_tx_power = vwifi_get_tx_power,
22252301
.join_ibss = vwifi_join_ibss,
22262302
.leave_ibss = vwifi_leave_ibss,
2303+
.set_bitrate_mask = vwifi_set_bitrate_mask,
22272304
};
22282305

22292306
/* Macro for defining 2GHZ channel array */
@@ -2276,10 +2353,29 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
22762353
RATE_ENT(120, 0x40), RATE_ENT(180, 0x80), RATE_ENT(240, 0x100),
22772354
RATE_ENT(360, 0x200), RATE_ENT(480, 0x400), RATE_ENT(540, 0x800),
22782355
};
2279-
22802356
/* Describes supported band of 2GHz. */
2281-
static struct ieee80211_supported_band nf_band_2ghz;
2282-
2357+
static struct ieee80211_supported_band nf_band_2ghz = {
2358+
.band = NL80211_BAND_2GHZ,
2359+
.channels = vwifi_supported_channels_2ghz,
2360+
.n_channels = ARRAY_SIZE(vwifi_supported_channels_2ghz),
2361+
.bitrates = vwifi_supported_rates,
2362+
.n_bitrates = ARRAY_SIZE(vwifi_supported_rates),
2363+
.ht_cap =
2364+
{
2365+
.ht_supported = true,
2366+
.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_GRN_FLD |
2367+
IEEE80211_HT_CAP_MAX_AMSDU |
2368+
IEEE80211_HT_CAP_SUP_WIDTH_20_40,
2369+
.mcs =
2370+
{
2371+
.rx_mask = {0xff, 0xff, 0xff, 0xff}, /* MCS 0-31 */
2372+
.rx_highest = cpu_to_le16(300),
2373+
.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
2374+
},
2375+
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
2376+
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
2377+
},
2378+
};
22832379
/* Describes supported band of 5GHz. */
22842380
static struct ieee80211_supported_band nf_band_5ghz;
22852381

0 commit comments

Comments
 (0)