@@ -155,6 +155,9 @@ struct vwifi_vif {
155
155
156
156
/* Packet virtio header size */
157
157
u8 vnet_hdr_len ;
158
+
159
+ /* Transmit power */
160
+ s32 tx_power ;
158
161
};
159
162
160
163
static int station = 2 ;
@@ -387,6 +390,20 @@ static inline struct vwifi_vif *wdev_get_vwifi_vif(struct wireless_dev *wdev)
387
390
return container_of (wdev , struct vwifi_vif , wdev );
388
391
}
389
392
393
+ /* helper function to retrieve vif from wiphy */
394
+ static struct vwifi_vif * wiphy_get_vwifi_vif (struct wiphy * wiphy )
395
+ {
396
+ struct wireless_dev * wdev ;
397
+ struct vwifi_vif * vif = NULL ;
398
+
399
+ list_for_each_entry (wdev , & wiphy -> wdev_list , list ) {
400
+ vif = container_of (wdev , struct vwifi_vif , wdev );
401
+ break ; /* Assuming only one virtual interface is present */
402
+ }
403
+
404
+ return vif ;
405
+ }
406
+
390
407
static inline u32 vwifi_mac_to_32 (const u8 * mac )
391
408
{
392
409
u32 h = 3323198485U ;
@@ -1840,6 +1857,64 @@ static int vwifi_delete_interface(struct vwifi_vif *vif)
1840
1857
return 0 ;
1841
1858
}
1842
1859
1860
+ /* Set transmit power for the virtual interface */
1861
+ static int vwifi_set_tx_power (struct wiphy * wiphy ,
1862
+ struct wireless_dev * wdev ,
1863
+ enum nl80211_tx_power_setting type ,
1864
+ int mbm )
1865
+ {
1866
+ struct vwifi_vif * vif = wiphy_get_vwifi_vif (wiphy );
1867
+ /* Validate vif pointer */
1868
+ if (!vif )
1869
+ return - EINVAL ;
1870
+
1871
+ if (mutex_lock_interruptible (& vif -> lock ))
1872
+ return - ERESTARTSYS ;
1873
+
1874
+ int power = MBM_TO_DBM (mbm );
1875
+ switch (type ) {
1876
+ case NL80211_TX_POWER_AUTOMATIC :
1877
+ /* Use default transmit power (11 dBm) */
1878
+ vif -> tx_power = 11 ;
1879
+ break ;
1880
+
1881
+ case NL80211_TX_POWER_LIMITED :
1882
+ /* Restrict power limits to a specific value (0 ~ 18 dBm) */
1883
+ if (power < 0 )
1884
+ vif -> tx_power = 0 ;
1885
+ else if (power > 18 )
1886
+ vif -> tx_power = 18 ;
1887
+ else
1888
+ vif -> tx_power = power ;
1889
+ break ;
1890
+
1891
+ case NL80211_TX_POWER_FIXED :
1892
+ /* Set power freely */
1893
+ vif -> tx_power = power ;
1894
+ break ;
1895
+
1896
+ default :
1897
+ return - EINVAL ; /* Invalid parameter */
1898
+ }
1899
+
1900
+ mutex_unlock (& vif -> lock );
1901
+
1902
+ return 0 ;
1903
+ }
1904
+
1905
+ /* Get transmit power from the virtual interface */
1906
+ static int vwifi_get_tx_power (struct wiphy * wiphy ,
1907
+ struct wireless_dev * wdev ,
1908
+ int * dbm )
1909
+ {
1910
+ struct vwifi_vif * vif = wdev_get_vwifi_vif (wdev );
1911
+ /* Validate vif pointer */
1912
+ if (!vif )
1913
+ return - EINVAL ;
1914
+ * dbm = vif -> tx_power ;
1915
+ return 0 ;
1916
+ }
1917
+
1843
1918
/* Structure of functions for FullMAC 80211 drivers. Functions implemented
1844
1919
* along with fields/flags in the wiphy structure represent driver features.
1845
1920
* This module can only perform "scan" and "connect". Some functions cannot
@@ -1860,6 +1935,8 @@ static struct cfg80211_ops vwifi_cfg_ops = {
1860
1935
.del_key = vwifi_del_key ,
1861
1936
.set_default_key = vwifi_set_default_key ,
1862
1937
.change_station = vwifi_change_station ,
1938
+ .set_tx_power = vwifi_set_tx_power ,
1939
+ .get_tx_power = vwifi_get_tx_power ,
1863
1940
};
1864
1941
1865
1942
/* Macro for defining 2GHZ channel array */
@@ -2044,7 +2121,7 @@ static struct wiphy *vwifi_cfg80211_add(void)
2044
2121
/* Signal type
2045
2122
* CFG80211_SIGNAL_TYPE_UNSPEC allows us specify signal strength from 0 to
2046
2123
* 100. The reasonable value for CFG80211_SIGNAL_TYPE_MBM is -3000 to -10000
2047
- * (mdBm ).
2124
+ * (mBm ).
2048
2125
*/
2049
2126
wiphy -> signal_type = CFG80211_SIGNAL_TYPE_MBM ;
2050
2127
0 commit comments