@@ -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 ; /* ADDED: Store user-specified MCS */
92
+ bool manual_mcs_set ; /* ADDED: Flag to indicate manual MCS override */
91
93
92
94
size_t ssid_len ;
93
95
/* Currently connected BSS id */
@@ -1345,7 +1347,6 @@ static int vwifi_get_station(struct wiphy *wiphy,
1345
1347
struct station_info * sinfo )
1346
1348
{
1347
1349
struct vwifi_vif * vif = ndev_get_vwifi_vif (dev );
1348
-
1349
1350
bool found_sta = false;
1350
1351
switch (dev -> ieee80211_ptr -> iftype ) {
1351
1352
case NL80211_IFTYPE_AP :;
@@ -1439,38 +1440,52 @@ static int vwifi_get_station(struct wiphy *wiphy,
1439
1440
1440
1441
1441
1442
1442
- /* Log byte counters for debugging */
1443
- pr_info ("vwifi: Station %pM tx_bytes %llu, rx_bytes %llu\n" , mac ,
1444
- sinfo -> tx_bytes , sinfo -> rx_bytes );
1445
-
1446
- /* Dynamic modulation based on signal strength */
1443
+ /* Checks vif->manual_mcs_set to use vif->manual_mcs if set;
1444
+ * Assigns modulation string for manual MCS ; else auto change based
1445
+ * on signal strength
1446
+ */
1447
1447
int mcs_index ;
1448
1448
const char * modulation ;
1449
- unsigned int data_rate_mbps ;
1450
- if (sinfo -> signal > -50 ) {
1451
- /* Strong signal: 64-QAM, MCS 31 */
1452
- mcs_index = 31 ;
1453
- modulation = "64-QAM" ;
1454
- } else if (sinfo -> signal > -70 && sinfo -> signal <= -50 ) {
1455
- /* Medium signal: 16-QAM, MCS 23 */
1456
- mcs_index = 23 ;
1457
- modulation = "16-QAM" ;
1458
- } else if (sinfo -> signal > -90 && sinfo -> signal <= -70 ) {
1459
- /* Weak signal: QPSK, MCS 15 */
1460
- mcs_index = 15 ;
1461
- modulation = "QPSK" ;
1449
+ if (vif -> manual_mcs_set ) {
1450
+ mcs_index = vif -> manual_mcs ;
1451
+ switch (mcs_index ) {
1452
+ case 7 :
1453
+ modulation = "BPSK" ;
1454
+ break ;
1455
+ case 15 :
1456
+ modulation = "QPSK" ;
1457
+ break ;
1458
+ case 23 :
1459
+ modulation = "16-QAM" ;
1460
+ break ;
1461
+ case 31 :
1462
+ modulation = "64-QAM" ;
1463
+ break ;
1464
+ default :
1465
+ modulation = "Unknown" ;
1466
+ break ;
1467
+ }
1468
+ pr_info ("vwifi: Station %pM using manual MCS %d (%s)\n" , mac , mcs_index ,
1469
+ modulation );
1462
1470
} else {
1463
- /* Very weak signal: BPSK, MCS 7 */
1464
- mcs_index = 7 ;
1465
- modulation = "BPSK" ;
1471
+ if (sinfo -> signal > -50 ) {
1472
+ mcs_index = 31 ;
1473
+ modulation = "64-QAM" ;
1474
+ } else if (sinfo -> signal > -70 && sinfo -> signal <= -50 ) {
1475
+ mcs_index = 23 ;
1476
+ modulation = "16-QAM" ;
1477
+ } else if (sinfo -> signal > -90 && sinfo -> signal <= -70 ) {
1478
+ mcs_index = 15 ;
1479
+ modulation = "QPSK" ;
1480
+ } else {
1481
+ mcs_index = 7 ;
1482
+ modulation = "BPSK" ;
1483
+ }
1484
+ pr_info (
1485
+ "vwifi: Station %pM signal %d dBm, using modulation %s (MCS %d)\n" ,
1486
+ mac , sinfo -> signal , modulation , mcs_index );
1466
1487
}
1467
1488
1468
- /* Log signal, modulation, and data rate for debugging */
1469
- pr_info (
1470
- "vwifi: Station %pM signal %d dBm, using modulation %s (MCS %d, %u "
1471
- "Mbps)\n" ,
1472
- mac , sinfo -> signal , modulation , mcs_index , data_rate_mbps );
1473
-
1474
1489
/* Configure RX and TX rates */
1475
1490
sinfo -> rxrate .flags = RATE_INFO_FLAGS_MCS ;
1476
1491
sinfo -> rxrate .mcs = mcs_index ;
@@ -1728,13 +1743,8 @@ static int vwifi_start_ap(struct wiphy *wiphy,
1728
1743
1729
1744
/* Initialize hrtimer of beacon */
1730
1745
pr_info ("vwifi: init beacon_timer.\n" );
1731
- #if LINUX_VERSION_CODE >= KERNEL_VERSION (6 , 15 , 0 )
1732
- hrtimer_setup (& vif -> beacon_timer , vwifi_beacon , CLOCK_MONOTONIC ,
1733
- HRTIMER_MODE_ABS_SOFT );
1734
- #else
1735
1746
hrtimer_init (& vif -> beacon_timer , CLOCK_MONOTONIC , HRTIMER_MODE_ABS_SOFT );
1736
1747
vif -> beacon_timer .function = vwifi_beacon ;
1737
- #endif
1738
1748
1739
1749
if (!hrtimer_is_queued (& vif -> beacon_timer )) {
1740
1750
u64 tsf , until_tbtt ;
@@ -2201,6 +2211,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2201
2211
2202
2212
return 0 ;
2203
2213
}
2214
+ /* Callback to handle manual bitrate configuration via iw */
2215
+ static int vwifi_set_bitrate_mask (struct wiphy * wiphy ,
2216
+ struct net_device * dev ,
2217
+ unsigned int link_id ,
2218
+ const u8 * peer ,
2219
+ const struct cfg80211_bitrate_mask * mask )
2220
+ {
2221
+ struct vwifi_vif * vif = netdev_priv (dev );
2222
+ int mcs_index = -1 ;
2223
+
2224
+ if (!vif ) {
2225
+ pr_err ("vwifi: Failed to get vwifi_vif for dev %s\n" , dev -> name );
2226
+ return - EINVAL ;
2227
+ }
2228
+
2229
+ if (vif -> sme_state != SME_CONNECTED ) {
2230
+ pr_err ("vwifi: Dev %s not connected, cannot set bitrate\n" , dev -> name );
2231
+ return - EINVAL ;
2232
+ }
2233
+
2234
+ pr_info ("vwifi: set_bitrate_mask called for dev %s, link_id %u, peer %pM\n" ,
2235
+ dev -> name , link_id , peer ? peer : vif -> bssid );
2236
+ pr_info ("vwifi: 2.4GHz MCS mask: %02x %02x %02x %02x\n" ,
2237
+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [0 ],
2238
+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [1 ],
2239
+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [2 ],
2240
+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [3 ]);
2241
+
2242
+ /* Find the requested MCS index */
2243
+ for (int i = 0 ; i < 4 ; i ++ ) {
2244
+ if (mask -> control [NL80211_BAND_2GHZ ].ht_mcs [i ]) {
2245
+ for (int j = 0 ; j < 8 ; j ++ ) {
2246
+ if (mask -> control [NL80211_BAND_2GHZ ].ht_mcs [i ] & (1 << j )) {
2247
+ mcs_index = i * 8 + j ;
2248
+ pr_info ("vwifi: Requested MCS index %d\n" , mcs_index );
2249
+ break ;
2250
+ }
2251
+ }
2252
+ if (mcs_index != -1 )
2253
+ break ;
2254
+ }
2255
+ }
2256
+
2257
+ if (mcs_index == -1 ) {
2258
+ pr_err ("vwifi: No valid MCS index found\n" );
2259
+ return - EINVAL ;
2260
+ }
2261
+
2262
+ if (mcs_index != 7 && mcs_index != 15 && mcs_index != 23 &&
2263
+ mcs_index != 31 ) {
2264
+ pr_err ("vwifi: Unsupported MCS index %d\n" , mcs_index );
2265
+ return - EINVAL ;
2266
+ }
2267
+
2268
+ vif -> manual_mcs = mcs_index ;
2269
+ vif -> manual_mcs_set = true;
2270
+ pr_info ("vwifi: Set manual MCS %d for dev %s\n" , mcs_index , dev -> name );
2271
+
2272
+ return 0 ;
2273
+ }
2204
2274
2205
2275
/* Structure of functions for FullMAC 80211 drivers. Functions implemented
2206
2276
* along with fields/flags in the wiphy structure represent driver features.
@@ -2226,31 +2296,35 @@ static struct cfg80211_ops vwifi_cfg_ops = {
2226
2296
.get_tx_power = vwifi_get_tx_power ,
2227
2297
.join_ibss = vwifi_join_ibss ,
2228
2298
.leave_ibss = vwifi_leave_ibss ,
2299
+ .set_bitrate_mask = vwifi_set_bitrate_mask ,
2229
2300
};
2230
2301
2231
2302
/* Macro for defining 2GHZ channel array */
2232
- #define CHAN_2GHZ (channel , freq ) \
2233
- { \
2234
- .band = NL80211_BAND_2GHZ, .hw_value = (channel), \
2235
- .center_freq = (freq), \
2303
+ #define CHAN_2GHZ (channel , freq ) \
2304
+ { \
2305
+ .band = NL80211_BAND_2GHZ, \
2306
+ .hw_value = (channel), \
2307
+ .center_freq = (freq), \
2236
2308
}
2237
2309
2238
2310
/* Macro for defining 5GHZ channel array */
2239
- #define CHAN_5GHZ (channel ) \
2240
- { \
2241
- .band = NL80211_BAND_5GHZ, .hw_value = (channel), \
2242
- .center_freq = 5000 + (5 * (channel)), \
2311
+ #define CHAN_5GHZ (channel ) \
2312
+ { \
2313
+ .band = NL80211_BAND_5GHZ, \
2314
+ .hw_value = (channel), \
2315
+ .center_freq = 5000 + (5 * (channel)), \
2243
2316
}
2244
2317
2245
2318
2246
2319
/* Macro for defining rate table */
2247
- #define RATE_ENT (_rate , _hw_value ) \
2248
- { \
2249
- .bitrate = (_rate), .hw_value = (_hw_value), \
2320
+ #define RATE_ENT (_rate , _hw_value ) \
2321
+ { \
2322
+ .bitrate = (_rate), \
2323
+ .hw_value = (_hw_value), \
2250
2324
}
2251
2325
2252
2326
/* Array of "supported" channels in 2GHz band. It is required for wiphy. */
2253
- static const struct ieee80211_channel vwifi_supported_channels_2ghz [] = {
2327
+ static struct ieee80211_channel vwifi_supported_channels_2ghz [] = {
2254
2328
CHAN_2GHZ (1 , 2412 ), CHAN_2GHZ (2 , 2417 ), CHAN_2GHZ (3 , 2422 ),
2255
2329
CHAN_2GHZ (4 , 2427 ), CHAN_2GHZ (5 , 2432 ), CHAN_2GHZ (6 , 2437 ),
2256
2330
CHAN_2GHZ (7 , 2442 ), CHAN_2GHZ (8 , 2447 ), CHAN_2GHZ (9 , 2452 ),
@@ -2273,16 +2347,35 @@ static const struct ieee80211_channel vwifi_supported_channels_5ghz[] = {
2273
2347
/* Array of supported rates, required to support those next rates
2274
2348
* for 2GHz and 5GHz band.
2275
2349
*/
2276
- static const struct ieee80211_rate vwifi_supported_rates [] = {
2350
+ static struct ieee80211_rate vwifi_supported_rates [] = {
2277
2351
RATE_ENT (10 , 0x1 ), RATE_ENT (20 , 0x2 ), RATE_ENT (55 , 0x4 ),
2278
2352
RATE_ENT (110 , 0x8 ), RATE_ENT (60 , 0x10 ), RATE_ENT (90 , 0x20 ),
2279
2353
RATE_ENT (120 , 0x40 ), RATE_ENT (180 , 0x80 ), RATE_ENT (240 , 0x100 ),
2280
2354
RATE_ENT (360 , 0x200 ), RATE_ENT (480 , 0x400 ), RATE_ENT (540 , 0x800 ),
2281
2355
};
2282
2356
2283
- /* Describes supported band of 2GHz. */
2284
- static struct ieee80211_supported_band nf_band_2ghz ;
2285
-
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
+ };
2286
2379
/* Describes supported band of 5GHz. */
2287
2380
static struct ieee80211_supported_band nf_band_5ghz ;
2288
2381
0 commit comments