@@ -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 */
@@ -1436,38 +1438,52 @@ static int vwifi_get_station(struct wiphy *wiphy,
1436
1438
* https://semfionetworks.com/blog/mcs-table-updated-with-80211ax-data-rates/
1437
1439
* IEEE 802.11n : https://zh.wikipedia.org/zh-tw/IEEE_802.11n
1438
1440
*/
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
+ */
1444
1445
int mcs_index ;
1445
1446
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 );
1459
1468
} 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 );
1463
1485
}
1464
1486
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
-
1471
1487
/* Configure RX and TX rates */
1472
1488
sinfo -> rxrate .flags = RATE_INFO_FLAGS_MCS ;
1473
1489
sinfo -> rxrate .mcs = mcs_index ;
@@ -2199,6 +2215,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2199
2215
2200
2216
return 0 ;
2201
2217
}
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
+ }
2202
2278
2203
2279
/* Structure of functions for FullMAC 80211 drivers. Functions implemented
2204
2280
* along with fields/flags in the wiphy structure represent driver features.
@@ -2224,6 +2300,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
2224
2300
.get_tx_power = vwifi_get_tx_power ,
2225
2301
.join_ibss = vwifi_join_ibss ,
2226
2302
.leave_ibss = vwifi_leave_ibss ,
2303
+ .set_bitrate_mask = vwifi_set_bitrate_mask ,
2227
2304
};
2228
2305
2229
2306
/* Macro for defining 2GHZ channel array */
@@ -2276,10 +2353,29 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
2276
2353
RATE_ENT (120 , 0x40 ), RATE_ENT (180 , 0x80 ), RATE_ENT (240 , 0x100 ),
2277
2354
RATE_ENT (360 , 0x200 ), RATE_ENT (480 , 0x400 ), RATE_ENT (540 , 0x800 ),
2278
2355
};
2279
-
2280
2356
/* 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
+ };
2283
2379
/* Describes supported band of 5GHz. */
2284
2380
static struct ieee80211_supported_band nf_band_5ghz ;
2285
2381
0 commit comments