Skip to content

Commit 8559519

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. 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 d52092f commit 8559519

File tree

1 file changed

+126
-29
lines changed

1 file changed

+126
-29
lines changed

vwifi.c

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

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

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

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

22282305
/* Macro for defining 2GHZ channel array */
@@ -2277,8 +2354,28 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
22772354
};
22782355

22792356
/* Describes supported band of 2GHz. */
2280-
static struct ieee80211_supported_band nf_band_2ghz;
2281-
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+
};
22822379
/* Describes supported band of 5GHz. */
22832380
static struct ieee80211_supported_band nf_band_5ghz;
22842381

0 commit comments

Comments
 (0)