@@ -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,31 +2296,35 @@ 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 */
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), \
22362308 }
22372309
22382310/* 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)), \
22432316 }
22442317
22452318
22462319/* 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), \
22502324 }
22512325
22522326/* 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 [] = {
22542328 CHAN_2GHZ (1 , 2412 ), CHAN_2GHZ (2 , 2417 ), CHAN_2GHZ (3 , 2422 ),
22552329 CHAN_2GHZ (4 , 2427 ), CHAN_2GHZ (5 , 2432 ), CHAN_2GHZ (6 , 2437 ),
22562330 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[] = {
22732347/* Array of supported rates, required to support those next rates
22742348 * for 2GHz and 5GHz band.
22752349 */
2276- static const struct ieee80211_rate vwifi_supported_rates [] = {
2350+ static struct ieee80211_rate vwifi_supported_rates [] = {
22772351 RATE_ENT (10 , 0x1 ), RATE_ENT (20 , 0x2 ), RATE_ENT (55 , 0x4 ),
22782352 RATE_ENT (110 , 0x8 ), RATE_ENT (60 , 0x10 ), RATE_ENT (90 , 0x20 ),
22792353 RATE_ENT (120 , 0x40 ), RATE_ENT (180 , 0x80 ), RATE_ENT (240 , 0x100 ),
22802354 RATE_ENT (360 , 0x200 ), RATE_ENT (480 , 0x400 ), RATE_ENT (540 , 0x800 ),
22812355};
22822356
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+ };
22862379/* Describes supported band of 5GHz. */
22872380static struct ieee80211_supported_band nf_band_5ghz ;
22882381
0 commit comments