1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
7 #include "../mt76x02_usb.h"
9 static int mt76x2u_start(struct ieee80211_hw
*hw
)
11 struct mt76x02_dev
*dev
= hw
->priv
;
14 ret
= mt76x02u_mac_start(dev
);
18 ieee80211_queue_delayed_work(mt76_hw(dev
), &dev
->mt76
.mac_work
,
19 MT_MAC_WORK_INTERVAL
);
20 set_bit(MT76_STATE_RUNNING
, &dev
->mt76
.state
);
25 static void mt76x2u_stop(struct ieee80211_hw
*hw
)
27 struct mt76x02_dev
*dev
= hw
->priv
;
29 clear_bit(MT76_STATE_RUNNING
, &dev
->mt76
.state
);
30 mt76u_stop_tx(&dev
->mt76
);
35 mt76x2u_set_channel(struct mt76x02_dev
*dev
,
36 struct cfg80211_chan_def
*chandef
)
40 cancel_delayed_work_sync(&dev
->cal_work
);
41 mt76x02_pre_tbtt_enable(dev
, false);
43 mutex_lock(&dev
->mt76
.mutex
);
44 set_bit(MT76_RESET
, &dev
->mt76
.state
);
46 mt76_set_channel(&dev
->mt76
);
48 mt76x2_mac_stop(dev
, false);
50 err
= mt76x2u_phy_set_channel(dev
, chandef
);
52 mt76x02_mac_cc_reset(dev
);
53 mt76x2_mac_resume(dev
);
55 clear_bit(MT76_RESET
, &dev
->mt76
.state
);
56 mutex_unlock(&dev
->mt76
.mutex
);
58 mt76x02_pre_tbtt_enable(dev
, true);
59 mt76_txq_schedule_all(&dev
->mt76
);
65 mt76x2u_config(struct ieee80211_hw
*hw
, u32 changed
)
67 struct mt76x02_dev
*dev
= hw
->priv
;
70 mutex_lock(&dev
->mt76
.mutex
);
72 if (changed
& IEEE80211_CONF_CHANGE_MONITOR
) {
73 if (!(hw
->conf
.flags
& IEEE80211_CONF_MONITOR
))
74 dev
->mt76
.rxfilter
|= MT_RX_FILTR_CFG_PROMISC
;
76 dev
->mt76
.rxfilter
&= ~MT_RX_FILTR_CFG_PROMISC
;
77 mt76_wr(dev
, MT_RX_FILTR_CFG
, dev
->mt76
.rxfilter
);
80 if (changed
& IEEE80211_CONF_CHANGE_POWER
) {
81 dev
->mt76
.txpower_conf
= hw
->conf
.power_level
* 2;
83 /* convert to per-chain power for 2x2 devices */
84 dev
->mt76
.txpower_conf
-= 6;
86 if (test_bit(MT76_STATE_RUNNING
, &dev
->mt76
.state
))
87 mt76x2_phy_set_txpower(dev
);
90 mutex_unlock(&dev
->mt76
.mutex
);
92 if (changed
& IEEE80211_CONF_CHANGE_CHANNEL
) {
93 ieee80211_stop_queues(hw
);
94 err
= mt76x2u_set_channel(dev
, &hw
->conf
.chandef
);
95 ieee80211_wake_queues(hw
);
101 const struct ieee80211_ops mt76x2u_ops
= {
103 .start
= mt76x2u_start
,
104 .stop
= mt76x2u_stop
,
105 .add_interface
= mt76x02_add_interface
,
106 .remove_interface
= mt76x02_remove_interface
,
107 .sta_state
= mt76_sta_state
,
108 .set_key
= mt76x02_set_key
,
109 .ampdu_action
= mt76x02_ampdu_action
,
110 .config
= mt76x2u_config
,
111 .wake_tx_queue
= mt76_wake_tx_queue
,
112 .bss_info_changed
= mt76x02_bss_info_changed
,
113 .configure_filter
= mt76x02_configure_filter
,
114 .conf_tx
= mt76x02_conf_tx
,
115 .sw_scan_start
= mt76_sw_scan
,
116 .sw_scan_complete
= mt76x02_sw_scan_complete
,
117 .sta_rate_tbl_update
= mt76x02_sta_rate_tbl_update
,
118 .get_txpower
= mt76_get_txpower
,
119 .get_survey
= mt76_get_survey
,
120 .set_tim
= mt76_set_tim
,
121 .release_buffered_frames
= mt76_release_buffered_frames
,
122 .get_antenna
= mt76_get_antenna
,