void mt76_set_channel(struct mt76_dev *dev) { struct ieee80211_hw *hw = dev->hw; struct cfg80211_chan_def *chandef = &hw->conf.chandef; struct mt76_channel_state *state; bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL; int timeout = HZ / 5; if (offchannel) set_bit(MT76_OFFCHANNEL, &dev->state); else clear_bit(MT76_OFFCHANNEL, &dev->state); wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(dev), timeout); if (dev->drv->update_survey) dev->drv->update_survey(dev); dev->chandef = *chandef; if (!offchannel) dev->main_chan = chandef->chan; if (chandef->chan != dev->main_chan) { state = mt76_channel_state(dev, chandef->chan); memset(state, 0, sizeof(*state)); } }
void mt76x2_update_channel(struct mt76_dev *mdev) { struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); struct mt76_channel_state *state; u32 active, busy; state = mt76_channel_state(&dev->mt76, dev->mt76.chandef.chan); busy = mt76_rr(dev, MT_CH_BUSY); active = busy + mt76_rr(dev, MT_CH_IDLE); spin_lock_bh(&dev->mt76.cc_lock); state->cc_busy += busy; state->cc_active += active; spin_unlock_bh(&dev->mt76.cc_lock); }
int mt76_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) { struct mt76_dev *dev = hw->priv; struct mt76_sband *sband; struct ieee80211_channel *chan; struct mt76_channel_state *state; int ret = 0; if (idx == 0 && dev->drv->update_survey) dev->drv->update_survey(dev); sband = &dev->sband_2g; if (idx >= sband->sband.n_channels) { idx -= sband->sband.n_channels; sband = &dev->sband_5g; } if (idx >= sband->sband.n_channels) return -ENOENT; chan = &sband->sband.channels[idx]; state = mt76_channel_state(dev, chan); memset(survey, 0, sizeof(*survey)); survey->channel = chan; survey->filled = SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY; if (chan == dev->main_chan) survey->filled |= SURVEY_INFO_IN_USE; spin_lock_bh(&dev->cc_lock); survey->time = div_u64(state->cc_active, 1000); survey->time_busy = div_u64(state->cc_busy, 1000); spin_unlock_bh(&dev->cc_lock); return ret; }