@@ -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 ;
92+ bool manual_mcs_set ;
9193
9294 size_t ssid_len ;
9395 /* Currently connected BSS id */
@@ -1436,38 +1438,55 @@ static int vwifi_get_station(struct wiphy *wiphy,
14361438 * https://semfionetworks.com/blog/mcs-table-updated-with-80211ax-data-rates/
14371439 * IEEE 802.11n : https://zh.wikipedia.org/zh-tw/IEEE_802.11n
14381440 */
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 );
14421441
1443- /* Dynamic modulation based on signal strength */
1442+
1443+
1444+ /* Checks vif->manual_mcs_set to use vif->manual_mcs if set;
1445+ * Assigns modulation string for manual MCS ; else auto change based
1446+ * on signal strength
1447+ */
14441448 int mcs_index ;
14451449 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" ;
1450+ if (vif -> manual_mcs_set ) {
1451+ mcs_index = vif -> manual_mcs ;
1452+ switch (mcs_index ) {
1453+ case 7 :
1454+ modulation = "BPSK" ;
1455+ break ;
1456+ case 15 :
1457+ modulation = "QPSK" ;
1458+ break ;
1459+ case 23 :
1460+ modulation = "16-QAM" ;
1461+ break ;
1462+ case 31 :
1463+ modulation = "64-QAM" ;
1464+ break ;
1465+ default :
1466+ modulation = "Unknown" ;
1467+ break ;
1468+ }
1469+ pr_info ("vwifi: Station %pM using manual MCS %d (%s)\n" , mac , mcs_index ,
1470+ modulation );
14591471 } else {
1460- /* Very weak signal: BPSK, MCS 7 */
1461- mcs_index = 7 ;
1462- modulation = "BPSK" ;
1472+ if (sinfo -> signal > -50 ) {
1473+ mcs_index = 31 ;
1474+ modulation = "64-QAM" ;
1475+ } else if (sinfo -> signal > -70 && sinfo -> signal <= -50 ) {
1476+ mcs_index = 23 ;
1477+ modulation = "16-QAM" ;
1478+ } else if (sinfo -> signal > -90 && sinfo -> signal <= -70 ) {
1479+ mcs_index = 15 ;
1480+ modulation = "QPSK" ;
1481+ } else {
1482+ mcs_index = 7 ;
1483+ modulation = "BPSK" ;
1484+ }
1485+ pr_info (
1486+ "vwifi: Station %pM signal %d dBm, using modulation %s (MCS %d)\n" ,
1487+ mac , sinfo -> signal , modulation , mcs_index );
14631488 }
14641489
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-
14711490 /* Configure RX and TX rates */
14721491 sinfo -> rxrate .flags = RATE_INFO_FLAGS_MCS ;
14731492 sinfo -> rxrate .mcs = mcs_index ;
@@ -2199,6 +2218,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
21992218
22002219 return 0 ;
22012220}
2221+ /* Callback to handle manual bitrate configuration via iw */
2222+ static int vwifi_set_bitrate_mask (struct wiphy * wiphy ,
2223+ struct net_device * dev ,
2224+ unsigned int link_id ,
2225+ const u8 * peer ,
2226+ const struct cfg80211_bitrate_mask * mask )
2227+ {
2228+ struct vwifi_vif * vif = netdev_priv (dev );
2229+ int mcs_index = -1 ;
2230+
2231+ if (!vif ) {
2232+ pr_err ("vwifi: Failed to get vwifi_vif for dev %s\n" , dev -> name );
2233+ return - EINVAL ;
2234+ }
2235+
2236+ if (vif -> sme_state != SME_CONNECTED ) {
2237+ pr_err ("vwifi: Dev %s not connected, cannot set bitrate\n" , dev -> name );
2238+ return - EINVAL ;
2239+ }
2240+
2241+ pr_info ("vwifi: set_bitrate_mask called for dev %s, link_id %u, peer %pM\n" ,
2242+ dev -> name , link_id , peer ? peer : vif -> bssid );
2243+ pr_info ("vwifi: 2.4GHz MCS mask: %02x %02x %02x %02x\n" ,
2244+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [0 ],
2245+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [1 ],
2246+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [2 ],
2247+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [3 ]);
2248+
2249+ /* Find the requested MCS index */
2250+ for (int i = 0 ; i < 4 ; i ++ ) {
2251+ if (mask -> control [NL80211_BAND_2GHZ ].ht_mcs [i ]) {
2252+ for (int j = 0 ; j < 8 ; j ++ ) {
2253+ if (mask -> control [NL80211_BAND_2GHZ ].ht_mcs [i ] & (1 << j )) {
2254+ mcs_index = i * 8 + j ;
2255+ pr_info ("vwifi: Requested MCS index %d\n" , mcs_index );
2256+ break ;
2257+ }
2258+ }
2259+ if (mcs_index != -1 )
2260+ break ;
2261+ }
2262+ }
2263+
2264+ if (mcs_index == -1 ) {
2265+ pr_err ("vwifi: No valid MCS index found\n" );
2266+ return - EINVAL ;
2267+ }
2268+
2269+ if (mcs_index != 7 && mcs_index != 15 && mcs_index != 23 &&
2270+ mcs_index != 31 ) {
2271+ pr_err ("vwifi: Unsupported MCS index %d\n" , mcs_index );
2272+ return - EINVAL ;
2273+ }
2274+
2275+ vif -> manual_mcs = mcs_index ;
2276+ vif -> manual_mcs_set = true;
2277+ pr_info ("vwifi: Set manual MCS %d for dev %s\n" , mcs_index , dev -> name );
2278+
2279+ return 0 ;
2280+ }
22022281
22032282/* Structure of functions for FullMAC 80211 drivers. Functions implemented
22042283 * along with fields/flags in the wiphy structure represent driver features.
@@ -2224,6 +2303,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
22242303 .get_tx_power = vwifi_get_tx_power ,
22252304 .join_ibss = vwifi_join_ibss ,
22262305 .leave_ibss = vwifi_leave_ibss ,
2306+ .set_bitrate_mask = vwifi_set_bitrate_mask ,
22272307};
22282308
22292309/* Macro for defining 2GHZ channel array */
@@ -2276,10 +2356,29 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
22762356 RATE_ENT (120 , 0x40 ), RATE_ENT (180 , 0x80 ), RATE_ENT (240 , 0x100 ),
22772357 RATE_ENT (360 , 0x200 ), RATE_ENT (480 , 0x400 ), RATE_ENT (540 , 0x800 ),
22782358};
2279-
22802359/* Describes supported band of 2GHz. */
2281- static struct ieee80211_supported_band nf_band_2ghz ;
2282-
2360+ static struct ieee80211_supported_band nf_band_2ghz = {
2361+ .band = NL80211_BAND_2GHZ ,
2362+ .channels = vwifi_supported_channels_2ghz ,
2363+ .n_channels = ARRAY_SIZE (vwifi_supported_channels_2ghz ),
2364+ .bitrates = vwifi_supported_rates ,
2365+ .n_bitrates = ARRAY_SIZE (vwifi_supported_rates ),
2366+ .ht_cap =
2367+ {
2368+ .ht_supported = true,
2369+ .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_GRN_FLD |
2370+ IEEE80211_HT_CAP_MAX_AMSDU |
2371+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 ,
2372+ .mcs =
2373+ {
2374+ .rx_mask = {0xff , 0xff , 0xff , 0xff }, /* MCS 0-31 */
2375+ .rx_highest = cpu_to_le16 (300 ),
2376+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED ,
2377+ },
2378+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K ,
2379+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16 ,
2380+ },
2381+ };
22832382/* Describes supported band of 5GHz. */
22842383static struct ieee80211_supported_band nf_band_5ghz ;
22852384
0 commit comments