Skip to content

Commit

Permalink
mt76: mt7615: add dual-phy support for mac80211 ops
Browse files Browse the repository at this point in the history
Allows them to be used by a separately registered wiphy later

Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
Felix Fietkau committed Feb 14, 2020
1 parent c9619df commit fdd2e57
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 108 deletions.
15 changes: 8 additions & 7 deletions drivers/net/wireless/mediatek/mt76/mt7615/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static void mt7615_mac_init(struct mt7615_dev *dev)
MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
MT_TMAC_CTCR0_INS_DDLMT_EN);

mt7615_mcu_set_rts_thresh(dev, 0x92b);
mt7615_mcu_set_rts_thresh(&dev->phy, 0x92b);
mt7615_mac_set_scs(dev, true);

mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS,
Expand Down Expand Up @@ -132,7 +132,7 @@ static int mt7615_init_hardware(struct mt7615_dev *dev)
mt7615_mcu_set_eeprom(dev);
mt7615_mac_init(dev);
mt7615_phy_init(dev);
mt7615_mcu_ctrl_pm_state(dev, 0);
mt7615_mcu_ctrl_pm_state(dev, 0, 0);
mt7615_mcu_del_wtbl_all(dev);

/* Beacon and mgmt frames should occupy wcid 0 */
Expand Down Expand Up @@ -246,11 +246,9 @@ mt7615_regd_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct mt7615_dev *dev = hw->priv;
struct cfg80211_chan_def *chandef = &dev->mphy.chandef;

if (request->dfs_region == dev->mt76.region)
return;
struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt76_phy *mphy = hw->priv;
struct cfg80211_chan_def *chandef = &mphy->chandef;

dev->mt76.region = request->dfs_region;

Expand All @@ -271,6 +269,9 @@ int mt7615_register_device(struct mt7615_dev *dev)
struct wiphy *wiphy = hw->wiphy;
int ret;

dev->phy.dev = dev;
dev->phy.mt76 = &dev->mt76.phy;
dev->mt76.phy.priv = &dev->phy;
INIT_DELAYED_WORK(&dev->mt76.mac_work, mt7615_mac_work);
INIT_LIST_HEAD(&dev->sta_poll_list);
spin_lock_init(&dev->sta_poll_lock);
Expand Down
96 changes: 70 additions & 26 deletions drivers/net/wireless/mediatek/mt76/mt7615/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,20 @@ void mt7615_mac_reset_counters(struct mt7615_dev *dev)
mt76_rr(dev, MT_TX_AGG_CNT(i));

memset(dev->mt76.aggr_stats, 0, sizeof(dev->mt76.aggr_stats));

/* TODO: add DBDC support */
dev->mt76.phy.survey_time = ktime_get_boottime();
if (dev->mt76.phy2)
dev->mt76.phy2->survey_time = ktime_get_boottime();

/* reset airtime counters */
mt76_rr(dev, MT_MIB_SDR9(0));
mt76_rr(dev, MT_MIB_SDR9(1));

mt76_rr(dev, MT_MIB_SDR36(0));
mt76_rr(dev, MT_MIB_SDR36(1));

mt76_rr(dev, MT_MIB_SDR37(0));
mt76_rr(dev, MT_MIB_SDR37(1));

mt76_set(dev, MT_WF_RMAC_MIB_TIME0, MT_WF_RMAC_MIB_RXTIME_CLR);
mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0, MT_WF_RMAC_MIB_RXTIME_CLR);
}
Expand Down Expand Up @@ -291,6 +298,7 @@ void mt7615_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,

static u16
mt7615_mac_tx_rate_val(struct mt7615_dev *dev,
struct mt76_phy *mphy,
const struct ieee80211_tx_rate *rate,
bool stbc, u8 *bw)
{
Expand Down Expand Up @@ -319,11 +327,11 @@ mt7615_mac_tx_rate_val(struct mt7615_dev *dev,
*bw = 1;
} else {
const struct ieee80211_rate *r;
int band = dev->mphy.chandef.chan->band;
int band = mphy->chandef.chan->band;
u16 val;

nss = 1;
r = &mt76_hw(dev)->wiphy->bands[band]->bitrates[rate->idx];
r = &mphy->hw->wiphy->bands[band]->bitrates[rate->idx];
if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
val = r->hw_value_short;
else
Expand Down Expand Up @@ -355,6 +363,7 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
bool multicast = is_multicast_ether_addr(hdr->addr1);
struct ieee80211_vif *vif = info->control.vif;
struct mt76_phy *mphy = &dev->mphy;
int tx_count = 8;
u8 fc_type, fc_stype, p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
__le16 fc = hdr->frame_control;
Expand All @@ -374,6 +383,9 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
tx_count = msta->rate_count;
}

if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && dev->mt76.phy2)
mphy = dev->mt76.phy2;

fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;

Expand Down Expand Up @@ -431,7 +443,8 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
!(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) {
bool stbc = info->flags & IEEE80211_TX_CTL_STBC;
u8 bw;
u16 rateval = mt7615_mac_tx_rate_val(dev, rate, stbc, &bw);
u16 rateval = mt7615_mac_tx_rate_val(dev, mphy, rate, stbc,
&bw);

txwi[2] |= cpu_to_le32(MT_TXD2_FIX_RATE);

Expand Down Expand Up @@ -588,10 +601,12 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev)
rcu_read_unlock();
}

void mt7615_mac_set_rates(struct mt7615_dev *dev, struct mt7615_sta *sta,
void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
struct ieee80211_tx_rate *probe_rate,
struct ieee80211_tx_rate *rates)
{
struct mt7615_dev *dev = phy->dev;
struct mt76_phy *mphy = phy->mt76;
struct ieee80211_tx_rate *ref;
int wcid = sta->wcid.idx;
u32 addr = mt7615_mac_wtbl_addr(wcid);
Expand Down Expand Up @@ -649,11 +664,12 @@ void mt7615_mac_set_rates(struct mt7615_dev *dev, struct mt7615_sta *sta,
}
}

val[0] = mt7615_mac_tx_rate_val(dev, &rates[0], stbc, &bw);
val[0] = mt7615_mac_tx_rate_val(dev, mphy, &rates[0], stbc, &bw);
bw_prev = bw;

if (probe_rate) {
probe_val = mt7615_mac_tx_rate_val(dev, probe_rate, stbc, &bw);
probe_val = mt7615_mac_tx_rate_val(dev, mphy, probe_rate,
stbc, &bw);
if (bw)
bw_idx = 1;
else
Expand All @@ -662,19 +678,19 @@ void mt7615_mac_set_rates(struct mt7615_dev *dev, struct mt7615_sta *sta,
probe_val = val[0];
}

val[1] = mt7615_mac_tx_rate_val(dev, &rates[1], stbc, &bw);
val[1] = mt7615_mac_tx_rate_val(dev, mphy, &rates[1], stbc, &bw);
if (bw_prev) {
bw_idx = 3;
bw_prev = bw;
}

val[2] = mt7615_mac_tx_rate_val(dev, &rates[2], stbc, &bw);
val[2] = mt7615_mac_tx_rate_val(dev, mphy, &rates[2], stbc, &bw);
if (bw_prev) {
bw_idx = 5;
bw_prev = bw;
}

val[3] = mt7615_mac_tx_rate_val(dev, &rates[3], stbc, &bw);
val[3] = mt7615_mac_tx_rate_val(dev, mphy, &rates[3], stbc, &bw);
if (bw_prev)
bw_idx = 7;

Expand Down Expand Up @@ -906,8 +922,13 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);

if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
struct mt7615_phy *phy = &dev->phy;

if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && mdev->phy2)
phy = mdev->phy2->priv;

spin_lock_bh(&dev->mt76.lock);
mt7615_mac_set_rates(dev, msta, &info->control.rates[0],
mt7615_mac_set_rates(phy, msta, &info->control.rates[0],
msta->rates);
msta->rate_probe = true;
spin_unlock_bh(&dev->mt76.lock);
Expand Down Expand Up @@ -962,6 +983,7 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,
{
struct ieee80211_supported_band *sband;
struct mt7615_rate_set *rs;
struct mt76_phy *mphy;
int first_idx = 0, last_idx;
int i, idx, count;
bool fixed_rate, ack_timeout;
Expand Down Expand Up @@ -1019,7 +1041,12 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,

spin_lock_bh(&dev->mt76.lock);
if (sta->rate_probe) {
mt7615_mac_set_rates(dev, sta, NULL, sta->rates);
struct mt7615_phy *phy = &dev->phy;

if (sta->wcid.ext_phy && dev->mt76.phy2)
phy = dev->mt76.phy2->priv;

mt7615_mac_set_rates(phy, sta, NULL, sta->rates);
sta->rate_probe = false;
}
spin_unlock_bh(&dev->mt76.lock);
Expand Down Expand Up @@ -1059,10 +1086,14 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,
cck = true;
/* fall through */
case MT_PHY_TYPE_OFDM:
if (dev->mphy.chandef.chan->band == NL80211_BAND_5GHZ)
sband = &dev->mphy.sband_5g.sband;
mphy = &dev->mphy;
if (sta->wcid.ext_phy && dev->mt76.phy2)
mphy = dev->mt76.phy2;

if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
sband = &mphy->sband_5g.sband;
else
sband = &dev->mphy.sband_2g.sband;
sband = &mphy->sband_2g.sband;
final_rate &= MT_TX_RATE_IDX;
final_rate = mt76_get_rate(&dev->mt76, sband, final_rate,
cck);
Expand Down Expand Up @@ -1128,6 +1159,7 @@ void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data)
struct ieee80211_sta *sta = NULL;
struct mt7615_sta *msta = NULL;
struct mt76_wcid *wcid;
struct mt76_phy *mphy = &dev->mt76.phy;
__le32 *txs_data = data;
u32 txs;
u8 wcidx;
Expand Down Expand Up @@ -1164,8 +1196,11 @@ void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data)
if (wcidx >= MT7615_WTBL_STA || !sta)
goto out;

if (wcid->ext_phy && dev->mt76.phy2)
mphy = dev->mt76.phy2;

if (mt7615_fill_txs(dev, msta, &info, txs_data))
ieee80211_tx_status_noskb(mt76_hw(dev), sta, &info);
ieee80211_tx_status_noskb(mphy->hw, sta, &info);

out:
rcu_read_unlock();
Expand Down Expand Up @@ -1367,27 +1402,36 @@ mt7615_mac_scs_check(struct mt7615_dev *dev)
mt7615_mac_set_default_sensitivity(dev);
}

void mt7615_update_channel(struct mt76_dev *mdev)
static void
mt7615_phy_update_channel(struct mt76_phy *mphy, int idx)
{
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
struct mt7615_dev *dev = container_of(mphy->dev, struct mt7615_dev, mt76);
struct mt76_channel_state *state;
u64 busy_time, tx_time, rx_time, obss_time;
u32 obss_reg = idx ? MT_WF_RMAC_MIB_TIME6 : MT_WF_RMAC_MIB_TIME5;

/* TODO: add DBDC support */
busy_time = mt76_get_field(dev, MT_MIB_SDR9(0),
busy_time = mt76_get_field(dev, MT_MIB_SDR9(idx),
MT_MIB_SDR9_BUSY_MASK);
tx_time = mt76_get_field(dev, MT_MIB_SDR36(0),
tx_time = mt76_get_field(dev, MT_MIB_SDR36(idx),
MT_MIB_SDR36_TXTIME_MASK);
rx_time = mt76_get_field(dev, MT_MIB_SDR37(0),
rx_time = mt76_get_field(dev, MT_MIB_SDR37(idx),
MT_MIB_SDR37_RXTIME_MASK);
obss_time = mt76_get_field(dev, MT_WF_RMAC_MIB_TIME5,
MT_MIB_OBSSTIME_MASK);
obss_time = mt76_get_field(dev, obss_reg, MT_MIB_OBSSTIME_MASK);

state = mdev->phy.chan_state;
state = mphy->chan_state;
state->cc_busy += busy_time;
state->cc_tx += tx_time;
state->cc_rx += rx_time + obss_time;
state->cc_bss_rx += rx_time;
}

void mt7615_update_channel(struct mt76_dev *mdev)
{
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);

mt7615_phy_update_channel(&mdev->phy, 0);
if (mdev->phy2)
mt7615_phy_update_channel(mdev->phy2, 1);

/* reset obss airtime */
mt76_set(dev, MT_WF_RMAC_MIB_TIME0, MT_WF_RMAC_MIB_RXTIME_CLR);
Expand Down
Loading

0 comments on commit fdd2e57

Please sign in to comment.