@@ -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 ;
@@ -2198,6 +2214,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2198
2214
2199
2215
return 0 ;
2200
2216
}
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
+ }
2201
2277
2202
2278
/* Structure of functions for FullMAC 80211 drivers. Functions implemented
2203
2279
* along with fields/flags in the wiphy structure represent driver features.
@@ -2223,6 +2299,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
2223
2299
.get_tx_power = vwifi_get_tx_power ,
2224
2300
.join_ibss = vwifi_join_ibss ,
2225
2301
.leave_ibss = vwifi_leave_ibss ,
2302
+ .set_bitrate_mask = vwifi_set_bitrate_mask ,
2226
2303
};
2227
2304
2228
2305
/* Macro for defining 2GHZ channel array */
@@ -2277,8 +2354,28 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
2277
2354
};
2278
2355
2279
2356
/* 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
+ };
2282
2379
/* Describes supported band of 5GHz. */
2283
2380
static struct ieee80211_supported_band nf_band_5ghz ;
2284
2381
0 commit comments