@@ -155,6 +155,9 @@ struct vwifi_vif {
155155
156156 /* Packet virtio header size */
157157 u8 vnet_hdr_len ;
158+
159+ /* Transmit power */
160+ s32 tx_power ;
158161};
159162
160163static int station = 2 ;
@@ -387,6 +390,20 @@ static inline struct vwifi_vif *wdev_get_vwifi_vif(struct wireless_dev *wdev)
387390 return container_of (wdev , struct vwifi_vif , wdev );
388391}
389392
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+
390407static inline u32 vwifi_mac_to_32 (const u8 * mac )
391408{
392409 u32 h = 3323198485U ;
@@ -1840,6 +1857,64 @@ static int vwifi_delete_interface(struct vwifi_vif *vif)
18401857 return 0 ;
18411858}
18421859
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+
18431918/* Structure of functions for FullMAC 80211 drivers. Functions implemented
18441919 * along with fields/flags in the wiphy structure represent driver features.
18451920 * This module can only perform "scan" and "connect". Some functions cannot
@@ -1860,6 +1935,8 @@ static struct cfg80211_ops vwifi_cfg_ops = {
18601935 .del_key = vwifi_del_key ,
18611936 .set_default_key = vwifi_set_default_key ,
18621937 .change_station = vwifi_change_station ,
1938+ .set_tx_power = vwifi_set_tx_power ,
1939+ .get_tx_power = vwifi_get_tx_power ,
18631940};
18641941
18651942/* Macro for defining 2GHZ channel array */
@@ -2044,7 +2121,7 @@ static struct wiphy *vwifi_cfg80211_add(void)
20442121 /* Signal type
20452122 * CFG80211_SIGNAL_TYPE_UNSPEC allows us specify signal strength from 0 to
20462123 * 100. The reasonable value for CFG80211_SIGNAL_TYPE_MBM is -3000 to -10000
2047- * (mdBm ).
2124+ * (mBm ).
20482125 */
20492126 wiphy -> signal_type = CFG80211_SIGNAL_TYPE_MBM ;
20502127
0 commit comments