18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org> 48c2ecf20Sopenharmony_ci * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl> 58c2ecf20Sopenharmony_ci * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/etherdevice.h> 98c2ecf20Sopenharmony_ci#include "mt76x0.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic void 128c2ecf20Sopenharmony_cimt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci cancel_delayed_work_sync(&dev->cal_work); 158c2ecf20Sopenharmony_ci mt76x02_pre_tbtt_enable(dev, false); 168c2ecf20Sopenharmony_ci if (mt76_is_mmio(&dev->mt76)) 178c2ecf20Sopenharmony_ci tasklet_disable(&dev->dfs_pd.dfs_tasklet); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci mt76_set_channel(&dev->mphy); 208c2ecf20Sopenharmony_ci mt76x0_phy_set_channel(dev, chandef); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci mt76x02_mac_cc_reset(dev); 238c2ecf20Sopenharmony_ci mt76x02_edcca_init(dev); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci if (mt76_is_mmio(&dev->mt76)) { 268c2ecf20Sopenharmony_ci mt76x02_dfs_init_params(dev); 278c2ecf20Sopenharmony_ci tasklet_enable(&dev->dfs_pd.dfs_tasklet); 288c2ecf20Sopenharmony_ci } 298c2ecf20Sopenharmony_ci mt76x02_pre_tbtt_enable(dev, true); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci mt76_txq_schedule_all(&dev->mphy); 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ciint mt76x0_config(struct ieee80211_hw *hw, u32 changed) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci struct mt76x02_dev *dev = hw->priv; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci mutex_lock(&dev->mt76.mutex); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 418c2ecf20Sopenharmony_ci ieee80211_stop_queues(hw); 428c2ecf20Sopenharmony_ci mt76x0_set_channel(dev, &hw->conf.chandef); 438c2ecf20Sopenharmony_ci ieee80211_wake_queues(hw); 448c2ecf20Sopenharmony_ci } 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci if (changed & IEEE80211_CONF_CHANGE_POWER) { 478c2ecf20Sopenharmony_ci dev->txpower_conf = hw->conf.power_level * 2; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) 508c2ecf20Sopenharmony_ci mt76x0_phy_set_txpower(dev); 518c2ecf20Sopenharmony_ci } 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (changed & IEEE80211_CONF_CHANGE_MONITOR) { 548c2ecf20Sopenharmony_ci if (!(hw->conf.flags & IEEE80211_CONF_MONITOR)) 558c2ecf20Sopenharmony_ci dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC; 568c2ecf20Sopenharmony_ci else 578c2ecf20Sopenharmony_ci dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter); 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci mutex_unlock(&dev->mt76.mutex); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci return 0; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76x0_config); 67