@@ -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 */
@@ -1435,38 +1437,52 @@ static int vwifi_get_station(struct wiphy *wiphy,
14351437 * https://semfionetworks.com/blog/mcs-table-updated-with-80211ax-data-rates/
14361438 * IEEE 802.11n : https://zh.wikipedia.org/zh-tw/IEEE_802.11n
14371439 */
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+ */
14431444 int mcs_index ;
14441445 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 );
14581467 } 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 );
14621484 }
14631485
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-
14701486 /* Configure RX and TX rates */
14711487 sinfo -> rxrate .flags = RATE_INFO_FLAGS_MCS ;
14721488 sinfo -> rxrate .mcs = mcs_index ;
@@ -2198,6 +2214,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
21982214
21992215 return 0 ;
22002216}
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+ }
22012277
22022278/* Structure of functions for FullMAC 80211 drivers. Functions implemented
22032279 * along with fields/flags in the wiphy structure represent driver features.
@@ -2223,6 +2299,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
22232299 .get_tx_power = vwifi_get_tx_power ,
22242300 .join_ibss = vwifi_join_ibss ,
22252301 .leave_ibss = vwifi_leave_ibss ,
2302+ .set_bitrate_mask = vwifi_set_bitrate_mask ,
22262303};
22272304
22282305/* Macro for defining 2GHZ channel array */
@@ -2277,8 +2354,28 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
22772354};
22782355
22792356/* 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+ };
22822379/* Describes supported band of 5GHz. */
22832380static struct ieee80211_supported_band nf_band_5ghz ;
22842381
0 commit comments