@@ -88,6 +88,8 @@ struct vwifi_vif {
88
88
struct wireless_dev wdev ;
89
89
struct net_device * ndev ;
90
90
struct net_device_stats stats ;
91
+ int manual_mcs ;
92
+ bool manual_mcs_set ;
91
93
92
94
size_t ssid_len ;
93
95
/* Currently connected BSS id */
@@ -1435,38 +1437,52 @@ static int vwifi_get_station(struct wiphy *wiphy,
1435
1437
* https://semfionetworks.com/blog/mcs-table-updated-with-80211ax-data-rates/
1436
1438
* IEEE 802.11n : https://zh.wikipedia.org/zh-tw/IEEE_802.11n
1437
1439
*/
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
+ */
1443
1444
int mcs_index ;
1444
1445
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 );
1458
1467
} 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 );
1462
1484
}
1463
1485
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
-
1470
1486
/* Configure RX and TX rates */
1471
1487
sinfo -> rxrate .flags = RATE_INFO_FLAGS_MCS ;
1472
1488
sinfo -> rxrate .mcs = mcs_index ;
@@ -2209,6 +2225,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2209
2225
2210
2226
return 0 ;
2211
2227
}
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
+ }
2212
2288
2213
2289
/* Structure of functions for FullMAC 80211 drivers. Functions implemented
2214
2290
* along with fields/flags in the wiphy structure represent driver features.
@@ -2234,6 +2310,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
2234
2310
.get_tx_power = vwifi_get_tx_power ,
2235
2311
.join_ibss = vwifi_join_ibss ,
2236
2312
.leave_ibss = vwifi_leave_ibss ,
2313
+ .set_bitrate_mask = vwifi_set_bitrate_mask ,
2237
2314
};
2238
2315
2239
2316
/* Macro for defining 2GHZ channel array */
@@ -2288,8 +2365,28 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
2288
2365
};
2289
2366
2290
2367
/* 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
+ };
2293
2390
/* Describes supported band of 5GHz. */
2294
2391
static struct ieee80211_supported_band nf_band_5ghz ;
2295
2392
0 commit comments