Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
0004  */
0005 
0006 #include "mt76x2u.h"
0007 #include "../mt76x02_usb.h"
0008 
0009 static int mt76x2u_start(struct ieee80211_hw *hw)
0010 {
0011     struct mt76x02_dev *dev = hw->priv;
0012     int ret;
0013 
0014     ret = mt76x02u_mac_start(dev);
0015     if (ret)
0016         return ret;
0017 
0018     ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
0019                      MT_MAC_WORK_INTERVAL);
0020     set_bit(MT76_STATE_RUNNING, &dev->mphy.state);
0021 
0022     return 0;
0023 }
0024 
0025 static void mt76x2u_stop(struct ieee80211_hw *hw)
0026 {
0027     struct mt76x02_dev *dev = hw->priv;
0028 
0029     clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
0030     mt76u_stop_tx(&dev->mt76);
0031     mt76x2u_stop_hw(dev);
0032 }
0033 
0034 static int
0035 mt76x2u_set_channel(struct mt76x02_dev *dev,
0036             struct cfg80211_chan_def *chandef)
0037 {
0038     int err;
0039 
0040     cancel_delayed_work_sync(&dev->cal_work);
0041     mt76x02_pre_tbtt_enable(dev, false);
0042 
0043     mutex_lock(&dev->mt76.mutex);
0044     set_bit(MT76_RESET, &dev->mphy.state);
0045 
0046     mt76_set_channel(&dev->mphy);
0047 
0048     mt76x2_mac_stop(dev, false);
0049 
0050     err = mt76x2u_phy_set_channel(dev, chandef);
0051 
0052     mt76x02_mac_cc_reset(dev);
0053     mt76x2_mac_resume(dev);
0054 
0055     clear_bit(MT76_RESET, &dev->mphy.state);
0056     mutex_unlock(&dev->mt76.mutex);
0057 
0058     mt76x02_pre_tbtt_enable(dev, true);
0059     mt76_txq_schedule_all(&dev->mphy);
0060 
0061     return err;
0062 }
0063 
0064 static int
0065 mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
0066 {
0067     struct mt76x02_dev *dev = hw->priv;
0068     int err = 0;
0069 
0070     mutex_lock(&dev->mt76.mutex);
0071 
0072     if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
0073         if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
0074             dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC;
0075         else
0076             dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
0077         mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
0078     }
0079 
0080     if (changed & IEEE80211_CONF_CHANGE_POWER) {
0081         struct mt76_phy *mphy = &dev->mphy;
0082 
0083         dev->txpower_conf = hw->conf.power_level * 2;
0084         dev->txpower_conf = mt76_get_sar_power(mphy,
0085                                mphy->chandef.chan,
0086                                dev->txpower_conf);
0087         /* convert to per-chain power for 2x2 devices */
0088         dev->txpower_conf -= 6;
0089 
0090         if (test_bit(MT76_STATE_RUNNING, &mphy->state))
0091             mt76x2_phy_set_txpower(dev);
0092     }
0093 
0094     mutex_unlock(&dev->mt76.mutex);
0095 
0096     if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
0097         ieee80211_stop_queues(hw);
0098         err = mt76x2u_set_channel(dev, &hw->conf.chandef);
0099         ieee80211_wake_queues(hw);
0100     }
0101 
0102     return err;
0103 }
0104 
0105 const struct ieee80211_ops mt76x2u_ops = {
0106     .tx = mt76x02_tx,
0107     .start = mt76x2u_start,
0108     .stop = mt76x2u_stop,
0109     .add_interface = mt76x02_add_interface,
0110     .remove_interface = mt76x02_remove_interface,
0111     .sta_state = mt76_sta_state,
0112     .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
0113     .set_key = mt76x02_set_key,
0114     .ampdu_action = mt76x02_ampdu_action,
0115     .config = mt76x2u_config,
0116     .wake_tx_queue = mt76_wake_tx_queue,
0117     .bss_info_changed = mt76x02_bss_info_changed,
0118     .configure_filter = mt76x02_configure_filter,
0119     .conf_tx = mt76x02_conf_tx,
0120     .sw_scan_start = mt76_sw_scan,
0121     .sw_scan_complete = mt76x02_sw_scan_complete,
0122     .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
0123     .get_txpower = mt76_get_txpower,
0124     .get_survey = mt76_get_survey,
0125     .set_tim = mt76_set_tim,
0126     .release_buffered_frames = mt76_release_buffered_frames,
0127     .get_antenna = mt76_get_antenna,
0128     .set_sar_specs = mt76x2_set_sar_specs,
0129 };