Skip to content

Commit f63872b

Browse files
committed
Support transmit power
This commit introduces 'tx_power' to the virtual interface to specify the device's transmit power level. It also adds vwifi_set_tx_power() and vwifi_get_tx_power() to align with 'set_tx_power' and 'get_tx_power' in cfg80211_ops, respectively. The vwifi_set_tx_power() enables the setting of the device's transmit power, whereas vwifi_get_tx_power() facilitates the retrieval of this information. Users can adjust the transmit power by employing the command: iw dev [interface] set txpower auto/limit/fixed [transmit power (mBm)] auto: Use default transmit power limit: Restrict power limits to a specific value fixed: Set power freely Since using the above command results in the 'wdev' parameter NULL, a new function 'wiphy_get_vwifi_vif' was added to obtain the virtual interface. Additionally, the 'type' parameter is used to distinguish between "auto/limit/fixed". This commit also modifies the comments regarding mBm. In Linux source files, the correct terminology is mBm rather than mdBm. In traditional measurements, 'm' usually represents 10 to the power of negative three. However, 1 dBm equals 100 mBm, so using mdBm could be misleading.
1 parent a8bdf8a commit f63872b

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

scripts/verify.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ if [ $final_ret -eq 0 ]; then
2424
# to avoid device or resource busy error
2525
sleep 0.5
2626

27+
# set transmit power (mBm)
28+
sudo iw dev vw0 set txpower auto
29+
sudo iw dev vw1 set txpower fixed 1200
30+
sudo iw dev vw2 set txpower fixed 1300
31+
2732
# get phy number of each interface
2833
sudo iw dev > device.log
2934
vw0_phy=$(get_wiphy_name vw0)

vwifi.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

160163
static 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+
390407
static 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

Comments
 (0)