Skip to content

Commit 9176810

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 54e0b80 commit 9176810

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;
@@ -2209,6 +2225,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
22092225

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

22132289
/* Structure of functions for FullMAC 80211 drivers. Functions implemented
22142290
* along with fields/flags in the wiphy structure represent driver features.
@@ -2234,6 +2310,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
22342310
.get_tx_power = vwifi_get_tx_power,
22352311
.join_ibss = vwifi_join_ibss,
22362312
.leave_ibss = vwifi_leave_ibss,
2313+
.set_bitrate_mask = vwifi_set_bitrate_mask,
22372314
};
22382315

22392316
/* Macro for defining 2GHZ channel array */
@@ -2288,8 +2365,28 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
22882365
};
22892366

22902367
/* Describes supported band of 2GHz. */
2291-
static struct ieee80211_supported_band nf_band_2ghz;
2292-
2368+
static struct ieee80211_supported_band nf_band_2ghz = {
2369+
.band = NL80211_BAND_2GHZ,
2370+
.channels = vwifi_supported_channels_2ghz,
2371+
.n_channels = ARRAY_SIZE(vwifi_supported_channels_2ghz),
2372+
.bitrates = vwifi_supported_rates,
2373+
.n_bitrates = ARRAY_SIZE(vwifi_supported_rates),
2374+
.ht_cap =
2375+
{
2376+
.ht_supported = true,
2377+
.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_GRN_FLD |
2378+
IEEE80211_HT_CAP_MAX_AMSDU |
2379+
IEEE80211_HT_CAP_SUP_WIDTH_20_40,
2380+
.mcs =
2381+
{
2382+
.rx_mask = {0xff, 0xff, 0xff, 0xff}, /* MCS 0-31 */
2383+
.rx_highest = cpu_to_le16(300),
2384+
.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
2385+
},
2386+
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
2387+
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
2388+
},
2389+
};
22932390
/* Describes supported band of 5GHz. */
22942391
static struct ieee80211_supported_band nf_band_5ghz;
22952392

0 commit comments

Comments
 (0)