Skip to content

Commit 687bcf3

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 687bcf3

File tree

1 file changed

+128
-29
lines changed

1 file changed

+128
-29
lines changed

vwifi.c

Lines changed: 128 additions & 29 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,55 @@ 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);
14421441

1443-
/* Dynamic modulation based on signal strength */
1442+
1443+
1444+
/* Checks vif->manual_mcs_set to use vif->manual_mcs if set;
1445+
* Assigns modulation string for manual MCS ; else auto change based
1446+
* on signal strength
1447+
*/
14441448
int mcs_index;
14451449
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";
1450+
if (vif->manual_mcs_set) {
1451+
mcs_index = vif->manual_mcs;
1452+
switch (mcs_index) {
1453+
case 7:
1454+
modulation = "BPSK";
1455+
break;
1456+
case 15:
1457+
modulation = "QPSK";
1458+
break;
1459+
case 23:
1460+
modulation = "16-QAM";
1461+
break;
1462+
case 31:
1463+
modulation = "64-QAM";
1464+
break;
1465+
default:
1466+
modulation = "Unknown";
1467+
break;
1468+
}
1469+
pr_info("vwifi: Station %pM using manual MCS %d (%s)\n", mac, mcs_index,
1470+
modulation);
14591471
} else {
1460-
/* Very weak signal: BPSK, MCS 7 */
1461-
mcs_index = 7;
1462-
modulation = "BPSK";
1472+
if (sinfo->signal > -50) {
1473+
mcs_index = 31;
1474+
modulation = "64-QAM";
1475+
} else if (sinfo->signal > -70 && sinfo->signal <= -50) {
1476+
mcs_index = 23;
1477+
modulation = "16-QAM";
1478+
} else if (sinfo->signal > -90 && sinfo->signal <= -70) {
1479+
mcs_index = 15;
1480+
modulation = "QPSK";
1481+
} else {
1482+
mcs_index = 7;
1483+
modulation = "BPSK";
1484+
}
1485+
pr_info(
1486+
"vwifi: Station %pM signal %d dBm, using modulation %s (MCS %d)\n",
1487+
mac, sinfo->signal, modulation, mcs_index);
14631488
}
14641489

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-
14711490
/* Configure RX and TX rates */
14721491
sinfo->rxrate.flags = RATE_INFO_FLAGS_MCS;
14731492
sinfo->rxrate.mcs = mcs_index;
@@ -2199,6 +2218,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
21992218

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

22032282
/* Structure of functions for FullMAC 80211 drivers. Functions implemented
22042283
* along with fields/flags in the wiphy structure represent driver features.
@@ -2224,6 +2303,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
22242303
.get_tx_power = vwifi_get_tx_power,
22252304
.join_ibss = vwifi_join_ibss,
22262305
.leave_ibss = vwifi_leave_ibss,
2306+
.set_bitrate_mask = vwifi_set_bitrate_mask,
22272307
};
22282308

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

0 commit comments

Comments
 (0)