@@ -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 ; /* ADDED: Store user-specified MCS */
92+ bool manual_mcs_set ; /* ADDED: Flag to indicate manual MCS override */
9193
9294 size_t ssid_len ;
9395 /* Currently connected BSS id */
@@ -1345,7 +1347,6 @@ static int vwifi_get_station(struct wiphy *wiphy,
13451347 struct station_info * sinfo )
13461348{
13471349 struct vwifi_vif * vif = ndev_get_vwifi_vif (dev );
1348-
13491350 bool found_sta = false;
13501351 switch (dev -> ieee80211_ptr -> iftype ) {
13511352 case NL80211_IFTYPE_AP :;
@@ -1439,38 +1440,52 @@ static int vwifi_get_station(struct wiphy *wiphy,
14391440
14401441
14411442
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+ */
14471447 int mcs_index ;
14481448 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 );
14621470 } 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 );
14661487 }
14671488
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-
14741489 /* Configure RX and TX rates */
14751490 sinfo -> rxrate .flags = RATE_INFO_FLAGS_MCS ;
14761491 sinfo -> rxrate .mcs = mcs_index ;
@@ -1728,13 +1743,8 @@ static int vwifi_start_ap(struct wiphy *wiphy,
17281743
17291744 /* Initialize hrtimer of beacon */
17301745 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
17351746 hrtimer_init (& vif -> beacon_timer , CLOCK_MONOTONIC , HRTIMER_MODE_ABS_SOFT );
17361747 vif -> beacon_timer .function = vwifi_beacon ;
1737- #endif
17381748
17391749 if (!hrtimer_is_queued (& vif -> beacon_timer )) {
17401750 u64 tsf , until_tbtt ;
@@ -2201,6 +2211,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
22012211
22022212 return 0 ;
22032213}
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+ }
22042274
22052275/* Structure of functions for FullMAC 80211 drivers. Functions implemented
22062276 * along with fields/flags in the wiphy structure represent driver features.
@@ -2226,6 +2296,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
22262296 .get_tx_power = vwifi_get_tx_power ,
22272297 .join_ibss = vwifi_join_ibss ,
22282298 .leave_ibss = vwifi_leave_ibss ,
2299+ .set_bitrate_mask = vwifi_set_bitrate_mask ,
22292300};
22302301
22312302/* Macro for defining 2GHZ channel array */
@@ -2250,7 +2321,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
22502321 }
22512322
22522323/* Array of "supported" channels in 2GHz band. It is required for wiphy. */
2253- static const struct ieee80211_channel vwifi_supported_channels_2ghz [] = {
2324+ static struct ieee80211_channel vwifi_supported_channels_2ghz [] = {
22542325 CHAN_2GHZ (1 , 2412 ), CHAN_2GHZ (2 , 2417 ), CHAN_2GHZ (3 , 2422 ),
22552326 CHAN_2GHZ (4 , 2427 ), CHAN_2GHZ (5 , 2432 ), CHAN_2GHZ (6 , 2437 ),
22562327 CHAN_2GHZ (7 , 2442 ), CHAN_2GHZ (8 , 2447 ), CHAN_2GHZ (9 , 2452 ),
@@ -2273,16 +2344,35 @@ static const struct ieee80211_channel vwifi_supported_channels_5ghz[] = {
22732344/* Array of supported rates, required to support those next rates
22742345 * for 2GHz and 5GHz band.
22752346 */
2276- static const struct ieee80211_rate vwifi_supported_rates [] = {
2347+ static struct ieee80211_rate vwifi_supported_rates [] = {
22772348 RATE_ENT (10 , 0x1 ), RATE_ENT (20 , 0x2 ), RATE_ENT (55 , 0x4 ),
22782349 RATE_ENT (110 , 0x8 ), RATE_ENT (60 , 0x10 ), RATE_ENT (90 , 0x20 ),
22792350 RATE_ENT (120 , 0x40 ), RATE_ENT (180 , 0x80 ), RATE_ENT (240 , 0x100 ),
22802351 RATE_ENT (360 , 0x200 ), RATE_ENT (480 , 0x400 ), RATE_ENT (540 , 0x800 ),
22812352};
22822353
2283- /* Describes supported band of 2GHz. */
2284- static struct ieee80211_supported_band nf_band_2ghz ;
2285-
2354+ static struct ieee80211_supported_band nf_band_2ghz = {
2355+ .band = NL80211_BAND_2GHZ ,
2356+ .channels = vwifi_supported_channels_2ghz ,
2357+ .n_channels = ARRAY_SIZE (vwifi_supported_channels_2ghz ),
2358+ .bitrates = vwifi_supported_rates ,
2359+ .n_bitrates = ARRAY_SIZE (vwifi_supported_rates ),
2360+ .ht_cap =
2361+ {
2362+ .ht_supported = true,
2363+ .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_GRN_FLD |
2364+ IEEE80211_HT_CAP_MAX_AMSDU |
2365+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 ,
2366+ .mcs =
2367+ {
2368+ .rx_mask = {0xff , 0xff , 0xff , 0xff }, /* MCS 0-31 */
2369+ .rx_highest = cpu_to_le16 (300 ),
2370+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED ,
2371+ },
2372+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K ,
2373+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16 ,
2374+ },
2375+ };
22862376/* Describes supported band of 5GHz. */
22872377static struct ieee80211_supported_band nf_band_5ghz ;
22882378
0 commit comments