158 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>4 */5 6#include "mt76x2.h"7#include "../mt76x02_mac.h"8 9static int10mt76x2_start(struct ieee80211_hw *hw)11{12 struct mt76x02_dev *dev = hw->priv;13 14 mt76x02_mac_start(dev);15 mt76x2_phy_start(dev);16 17 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,18 MT_MAC_WORK_INTERVAL);19 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->wdt_work,20 MT_WATCHDOG_TIME);21 22 set_bit(MT76_STATE_RUNNING, &dev->mphy.state);23 return 0;24}25 26static void27mt76x2_stop(struct ieee80211_hw *hw, bool suspend)28{29 struct mt76x02_dev *dev = hw->priv;30 31 clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);32 mt76x2_stop_hardware(dev);33}34 35int mt76x2e_set_channel(struct mt76_phy *phy)36{37 struct mt76x02_dev *dev = container_of(phy->dev, struct mt76x02_dev, mt76);38 39 tasklet_disable(&dev->mt76.pre_tbtt_tasklet);40 tasklet_disable(&dev->dfs_pd.dfs_tasklet);41 42 mt76x2_mac_stop(dev, true);43 mt76x2_phy_set_channel(dev, &phy->chandef);44 45 mt76x02_mac_cc_reset(dev);46 mt76x02_dfs_init_params(dev);47 48 mt76x2_mac_resume(dev);49 50 tasklet_enable(&dev->dfs_pd.dfs_tasklet);51 tasklet_enable(&dev->mt76.pre_tbtt_tasklet);52 53 return 0;54}55 56static int57mt76x2_config(struct ieee80211_hw *hw, u32 changed)58{59 struct mt76x02_dev *dev = hw->priv;60 61 mutex_lock(&dev->mt76.mutex);62 63 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {64 if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))65 dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC;66 else67 dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;68 69 mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);70 }71 72 if (changed & IEEE80211_CONF_CHANGE_POWER) {73 struct mt76_phy *mphy = &dev->mphy;74 75 dev->txpower_conf = hw->conf.power_level * 2;76 dev->txpower_conf = mt76_get_sar_power(mphy,77 mphy->chandef.chan,78 dev->txpower_conf);79 /* convert to per-chain power for 2x2 devices */80 dev->txpower_conf -= 6;81 82 if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state)) {83 mt76x2_phy_set_txpower(dev);84 mt76x02_tx_set_txpwr_auto(dev, dev->txpower_conf);85 }86 }87 88 mutex_unlock(&dev->mt76.mutex);89 90 if (changed & IEEE80211_CONF_CHANGE_CHANNEL)91 mt76_update_channel(&dev->mphy);92 93 return 0;94}95 96static void97mt76x2_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,98 u32 queues, bool drop)99{100}101 102static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant,103 u32 rx_ant)104{105 struct mt76x02_dev *dev = hw->priv;106 107 if (!tx_ant || tx_ant > 3 || tx_ant != rx_ant)108 return -EINVAL;109 110 mutex_lock(&dev->mt76.mutex);111 112 dev->mphy.chainmask = (tx_ant == 3) ? 0x202 : 0x101;113 dev->mphy.antenna_mask = tx_ant;114 115 mt76_set_stream_caps(&dev->mphy, true);116 mt76x2_phy_set_antenna(dev);117 118 mutex_unlock(&dev->mt76.mutex);119 120 return 0;121}122 123const struct ieee80211_ops mt76x2_ops = {124 .add_chanctx = ieee80211_emulate_add_chanctx,125 .remove_chanctx = ieee80211_emulate_remove_chanctx,126 .change_chanctx = ieee80211_emulate_change_chanctx,127 .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,128 .tx = mt76x02_tx,129 .start = mt76x2_start,130 .stop = mt76x2_stop,131 .add_interface = mt76x02_add_interface,132 .remove_interface = mt76x02_remove_interface,133 .config = mt76x2_config,134 .configure_filter = mt76x02_configure_filter,135 .bss_info_changed = mt76x02_bss_info_changed,136 .sta_state = mt76_sta_state,137 .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,138 .set_key = mt76x02_set_key,139 .conf_tx = mt76x02_conf_tx,140 .sw_scan_start = mt76_sw_scan,141 .sw_scan_complete = mt76x02_sw_scan_complete,142 .flush = mt76x2_flush,143 .ampdu_action = mt76x02_ampdu_action,144 .get_txpower = mt76_get_txpower,145 .wake_tx_queue = mt76_wake_tx_queue,146 .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,147 .release_buffered_frames = mt76_release_buffered_frames,148 .set_coverage_class = mt76x02_set_coverage_class,149 .get_survey = mt76_get_survey,150 .set_tim = mt76_set_tim,151 .set_antenna = mt76x2_set_antenna,152 .get_antenna = mt76_get_antenna,153 .set_rts_threshold = mt76x02_set_rts_threshold,154 .reconfig_complete = mt76x02_reconfig_complete,155 .set_sar_specs = mt76x2_set_sar_specs,156};157 158