mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
wifi: mt76: add multi-radio support to a few core hw ops
Iterate over all phys if multi-radio is supported by the driver Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
+66
-19
@@ -807,6 +807,22 @@ void mt76_free_device(struct mt76_dev *dev)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76_free_device);
|
EXPORT_SYMBOL_GPL(mt76_free_device);
|
||||||
|
|
||||||
|
static struct mt76_phy *
|
||||||
|
mt76_vif_phy(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||||
|
{
|
||||||
|
struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv;
|
||||||
|
struct mt76_chanctx *ctx;
|
||||||
|
|
||||||
|
if (!hw->wiphy->n_radio)
|
||||||
|
return hw->priv;
|
||||||
|
|
||||||
|
if (!mlink->ctx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctx = (struct mt76_chanctx *)mlink->ctx->drv_priv;
|
||||||
|
return ctx->phy;
|
||||||
|
}
|
||||||
|
|
||||||
static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
|
static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = phy->rx_amsdu[q].head;
|
struct sk_buff *skb = phy->rx_amsdu[q].head;
|
||||||
@@ -1015,33 +1031,52 @@ int mt76_update_channel(struct mt76_phy *phy)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76_update_channel);
|
EXPORT_SYMBOL_GPL(mt76_update_channel);
|
||||||
|
|
||||||
|
static struct mt76_sband *
|
||||||
|
mt76_get_survey_sband(struct mt76_phy *phy, int *idx)
|
||||||
|
{
|
||||||
|
if (idx == 0 && phy->dev->drv->update_survey)
|
||||||
|
mt76_update_survey(phy);
|
||||||
|
|
||||||
|
if (*idx < phy->sband_2g.sband.n_channels)
|
||||||
|
return &phy->sband_2g;
|
||||||
|
|
||||||
|
*idx -= phy->sband_2g.sband.n_channels;
|
||||||
|
if (*idx < phy->sband_5g.sband.n_channels)
|
||||||
|
return &phy->sband_5g;
|
||||||
|
|
||||||
|
*idx -= phy->sband_5g.sband.n_channels;
|
||||||
|
if (*idx < phy->sband_6g.sband.n_channels)
|
||||||
|
return &phy->sband_6g;
|
||||||
|
|
||||||
|
*idx -= phy->sband_6g.sband.n_channels;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int mt76_get_survey(struct ieee80211_hw *hw, int idx,
|
int mt76_get_survey(struct ieee80211_hw *hw, int idx,
|
||||||
struct survey_info *survey)
|
struct survey_info *survey)
|
||||||
{
|
{
|
||||||
struct mt76_phy *phy = hw->priv;
|
struct mt76_phy *phy = hw->priv;
|
||||||
struct mt76_dev *dev = phy->dev;
|
struct mt76_dev *dev = phy->dev;
|
||||||
struct mt76_sband *sband;
|
struct mt76_sband *sband = NULL;
|
||||||
struct ieee80211_channel *chan;
|
struct ieee80211_channel *chan;
|
||||||
struct mt76_channel_state *state;
|
struct mt76_channel_state *state;
|
||||||
|
int phy_idx = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&dev->mutex);
|
mutex_lock(&dev->mutex);
|
||||||
if (idx == 0 && dev->drv->update_survey)
|
|
||||||
mt76_update_survey(phy);
|
|
||||||
|
|
||||||
if (idx >= phy->sband_2g.sband.n_channels +
|
for (phy_idx = 0; phy_idx < ARRAY_SIZE(dev->phys); phy_idx++) {
|
||||||
phy->sband_5g.sband.n_channels) {
|
sband = NULL;
|
||||||
idx -= (phy->sband_2g.sband.n_channels +
|
phy = dev->phys[phy_idx];
|
||||||
phy->sband_5g.sband.n_channels);
|
if (!phy || phy->hw != hw)
|
||||||
sband = &phy->sband_6g;
|
continue;
|
||||||
} else if (idx >= phy->sband_2g.sband.n_channels) {
|
|
||||||
idx -= phy->sband_2g.sband.n_channels;
|
sband = mt76_get_survey_sband(phy, &idx);
|
||||||
sband = &phy->sband_5g;
|
if (sband || !hw->wiphy->n_radio)
|
||||||
} else {
|
break;
|
||||||
sband = &phy->sband_2g;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx >= sband->sband.n_channels) {
|
if (!sband) {
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1547,6 +1582,10 @@ int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
struct mt76_dev *dev = phy->dev;
|
struct mt76_dev *dev = phy->dev;
|
||||||
enum mt76_sta_event ev;
|
enum mt76_sta_event ev;
|
||||||
|
|
||||||
|
phy = mt76_vif_phy(hw, vif);
|
||||||
|
if (!phy)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (old_state == IEEE80211_STA_NOTEXIST &&
|
if (old_state == IEEE80211_STA_NOTEXIST &&
|
||||||
new_state == IEEE80211_STA_NONE)
|
new_state == IEEE80211_STA_NONE)
|
||||||
return mt76_sta_add(phy, vif, sta);
|
return mt76_sta_add(phy, vif, sta);
|
||||||
@@ -1639,10 +1678,14 @@ EXPORT_SYMBOL_GPL(mt76_wcid_cleanup);
|
|||||||
int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
int *dbm)
|
int *dbm)
|
||||||
{
|
{
|
||||||
struct mt76_phy *phy = hw->priv;
|
struct mt76_phy *phy = mt76_vif_phy(hw, vif);
|
||||||
int n_chains = hweight16(phy->chainmask);
|
int n_chains, delta;
|
||||||
int delta = mt76_tx_power_nss_delta(n_chains);
|
|
||||||
|
|
||||||
|
if (!phy)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
n_chains = hweight16(phy->chainmask);
|
||||||
|
delta = mt76_tx_power_nss_delta(n_chains);
|
||||||
*dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
|
*dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1817,10 +1860,14 @@ int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
|||||||
{
|
{
|
||||||
struct mt76_phy *phy = hw->priv;
|
struct mt76_phy *phy = hw->priv;
|
||||||
struct mt76_dev *dev = phy->dev;
|
struct mt76_dev *dev = phy->dev;
|
||||||
|
int i;
|
||||||
|
|
||||||
mutex_lock(&dev->mutex);
|
mutex_lock(&dev->mutex);
|
||||||
*tx_ant = phy->antenna_mask;
|
*tx_ant = 0;
|
||||||
*rx_ant = phy->antenna_mask;
|
for (i = 0; i < ARRAY_SIZE(dev->phys); i++)
|
||||||
|
if (dev->phys[i] && dev->phys[i]->hw == hw)
|
||||||
|
*tx_ant |= dev->phys[i]->chainmask;
|
||||||
|
*rx_ant = *tx_ant;
|
||||||
mutex_unlock(&dev->mutex);
|
mutex_unlock(&dev->mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user