rtw88: add support for set/get antennas

User space program such as iw can set antenna mask for the device.
So add set antenna support by configure the trx mode.

This is useful for some tests want to see the output of different
antenna configuration (e.g. path A v.s. path B).

Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200410100950.3199-3-yhchuang@realtek.com
This commit is contained in:
Yan-Hsuan Chuang 2020-04-10 18:09:50 +08:00 committed by Kalle Valo
parent b9ed7e9505
commit 297bcf8222
3 changed files with 71 additions and 0 deletions

View file

@ -754,6 +754,37 @@ static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw,
return 0;
}
static int rtw_ops_set_antenna(struct ieee80211_hw *hw,
u32 tx_antenna,
u32 rx_antenna)
{
struct rtw_dev *rtwdev = hw->priv;
struct rtw_chip_info *chip = rtwdev->chip;
int ret;
if (!chip->ops->set_antenna)
return -EOPNOTSUPP;
mutex_lock(&rtwdev->mutex);
ret = chip->ops->set_antenna(rtwdev, tx_antenna, rx_antenna);
mutex_unlock(&rtwdev->mutex);
return ret;
}
static int rtw_ops_get_antenna(struct ieee80211_hw *hw,
u32 *tx_antenna,
u32 *rx_antenna)
{
struct rtw_dev *rtwdev = hw->priv;
struct rtw_hal *hal = &rtwdev->hal;
*tx_antenna = hal->antenna_tx;
*rx_antenna = hal->antenna_rx;
return 0;
}
#ifdef CONFIG_PM
static int rtw_ops_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan)
@ -815,6 +846,8 @@ const struct ieee80211_ops rtw_ops = {
.sta_statistics = rtw_ops_sta_statistics,
.flush = rtw_ops_flush,
.set_bitrate_mask = rtw_ops_set_bitrate_mask,
.set_antenna = rtw_ops_set_antenna,
.get_antenna = rtw_ops_get_antenna,
#ifdef CONFIG_PM
.suspend = rtw_ops_suspend,
.resume = rtw_ops_resume,

View file

@ -1450,6 +1450,7 @@ EXPORT_SYMBOL(rtw_core_deinit);
int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
{
struct rtw_hal *hal = &rtwdev->hal;
int max_tx_headroom = 0;
int ret;
@ -1478,6 +1479,8 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
hw->wiphy->available_antennas_tx = hal->antenna_tx;
hw->wiphy->available_antennas_rx = hal->antenna_rx;
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
WIPHY_FLAG_TDLS_EXTERNAL_SETUP;

View file

@ -1890,6 +1890,40 @@ static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev)
}
}
static int rtw8822c_set_antenna(struct rtw_dev *rtwdev,
u32 antenna_tx,
u32 antenna_rx)
{
struct rtw_hal *hal = &rtwdev->hal;
switch (antenna_tx) {
case BB_PATH_A:
case BB_PATH_B:
case BB_PATH_AB:
break;
default:
rtw_info(rtwdev, "unsupport tx path 0x%x\n", antenna_tx);
return -EINVAL;
}
/* path B only is not available for RX */
switch (antenna_rx) {
case BB_PATH_A:
case BB_PATH_AB:
break;
default:
rtw_info(rtwdev, "unsupport rx path 0x%x\n", antenna_rx);
return -EINVAL;
}
hal->antenna_tx = antenna_tx;
hal->antenna_rx = antenna_rx;
rtw8822c_config_trx_mode(rtwdev, antenna_tx, antenna_rx, false);
return 0;
}
static void rtw8822c_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
{
u8 ldo_pwr;
@ -3794,6 +3828,7 @@ static struct rtw_chip_ops rtw8822c_ops = {
.read_rf = rtw_phy_read_rf,
.write_rf = rtw_phy_write_rf_reg_mix,
.set_tx_power_index = rtw8822c_set_tx_power_index,
.set_antenna = rtw8822c_set_antenna,
.cfg_ldo25 = rtw8822c_cfg_ldo25,
.false_alarm_statistics = rtw8822c_false_alarm_statistics,
.dpk_track = rtw8822c_dpk_track,