@@ -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 ;
@@ -2209,6 +2225,66 @@ static int vwifi_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
22092225
22102226 return 0 ;
22112227}
2228+ /* Callback to handle manual bitrate configuration via iw */
2229+ static int vwifi_set_bitrate_mask (struct wiphy * wiphy ,
2230+ struct net_device * dev ,
2231+ unsigned int link_id ,
2232+ const u8 * peer ,
2233+ const struct cfg80211_bitrate_mask * mask )
2234+ {
2235+ struct vwifi_vif * vif = netdev_priv (dev );
2236+ int mcs_index = -1 ;
2237+
2238+ if (!vif ) {
2239+ pr_err ("vwifi: Failed to get vwifi_vif for dev %s\n" , dev -> name );
2240+ return - EINVAL ;
2241+ }
2242+
2243+ if (vif -> sme_state != SME_CONNECTED ) {
2244+ pr_err ("vwifi: Dev %s not connected, cannot set bitrate\n" , dev -> name );
2245+ return - EINVAL ;
2246+ }
2247+
2248+ pr_info ("vwifi: set_bitrate_mask called for dev %s, link_id %u, peer %pM\n" ,
2249+ dev -> name , link_id , peer ? peer : vif -> bssid );
2250+ pr_info ("vwifi: 2.4GHz MCS mask: %02x %02x %02x %02x\n" ,
2251+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [0 ],
2252+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [1 ],
2253+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [2 ],
2254+ mask -> control [NL80211_BAND_2GHZ ].ht_mcs [3 ]);
2255+
2256+ /* Find the requested MCS index */
2257+ for (int i = 0 ; i < 4 ; i ++ ) {
2258+ if (mask -> control [NL80211_BAND_2GHZ ].ht_mcs [i ]) {
2259+ for (int j = 0 ; j < 8 ; j ++ ) {
2260+ if (mask -> control [NL80211_BAND_2GHZ ].ht_mcs [i ] & (1 << j )) {
2261+ mcs_index = i * 8 + j ;
2262+ pr_info ("vwifi: Requested MCS index %d\n" , mcs_index );
2263+ break ;
2264+ }
2265+ }
2266+ if (mcs_index != -1 )
2267+ break ;
2268+ }
2269+ }
2270+
2271+ if (mcs_index == -1 ) {
2272+ pr_err ("vwifi: No valid MCS index found\n" );
2273+ return - EINVAL ;
2274+ }
2275+
2276+ if (mcs_index != 7 && mcs_index != 15 && mcs_index != 23 &&
2277+ mcs_index != 31 ) {
2278+ pr_err ("vwifi: Unsupported MCS index %d\n" , mcs_index );
2279+ return - EINVAL ;
2280+ }
2281+
2282+ vif -> manual_mcs = mcs_index ;
2283+ vif -> manual_mcs_set = true;
2284+ pr_info ("vwifi: Set manual MCS %d for dev %s\n" , mcs_index , dev -> name );
2285+
2286+ return 0 ;
2287+ }
22122288
22132289/* Structure of functions for FullMAC 80211 drivers. Functions implemented
22142290 * along with fields/flags in the wiphy structure represent driver features.
@@ -2234,6 +2310,7 @@ static struct cfg80211_ops vwifi_cfg_ops = {
22342310 .get_tx_power = vwifi_get_tx_power ,
22352311 .join_ibss = vwifi_join_ibss ,
22362312 .leave_ibss = vwifi_leave_ibss ,
2313+ .set_bitrate_mask = vwifi_set_bitrate_mask ,
22372314};
22382315
22392316/* Macro for defining 2GHZ channel array */
@@ -2288,8 +2365,28 @@ static const struct ieee80211_rate vwifi_supported_rates[] = {
22882365};
22892366
22902367/* Describes supported band of 2GHz. */
2291- static struct ieee80211_supported_band nf_band_2ghz ;
2292-
2368+ static struct ieee80211_supported_band nf_band_2ghz = {
2369+ .band = NL80211_BAND_2GHZ ,
2370+ .channels = vwifi_supported_channels_2ghz ,
2371+ .n_channels = ARRAY_SIZE (vwifi_supported_channels_2ghz ),
2372+ .bitrates = vwifi_supported_rates ,
2373+ .n_bitrates = ARRAY_SIZE (vwifi_supported_rates ),
2374+ .ht_cap =
2375+ {
2376+ .ht_supported = true,
2377+ .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_GRN_FLD |
2378+ IEEE80211_HT_CAP_MAX_AMSDU |
2379+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 ,
2380+ .mcs =
2381+ {
2382+ .rx_mask = {0xff , 0xff , 0xff , 0xff }, /* MCS 0-31 */
2383+ .rx_highest = cpu_to_le16 (300 ),
2384+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED ,
2385+ },
2386+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K ,
2387+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16 ,
2388+ },
2389+ };
22932390/* Describes supported band of 5GHz. */
22942391static struct ieee80211_supported_band nf_band_5ghz ;
22952392
0 commit comments