aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo.bianconi@redhat.com>2018-07-31 04:09:16 -0400
committerKalle Valo <kvalo@codeaurora.org>2018-08-02 14:48:11 -0400
commit2de8c3eb7ed7a450e19b0edfa51f2acd6a81ec40 (patch)
tree128a9a126cdc7dddc4f4801b09d8a6ac582ff478
parent43930193a8741a0b7ddcf64c6da1ed4630dcfc51 (diff)
mt76: add mt76x2_common to mt76x2-common module
Move core related code shared between mt76x2 and mt76x2u in mt76x2-common module Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/mediatek/mt76/Makefile2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2.h21
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2_common.c350
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2_dma.c21
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2_main.c307
5 files changed, 372 insertions, 329 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile
index 8342b4d38220..a184e16a5d54 100644
--- a/drivers/net/wireless/mediatek/mt76/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/Makefile
@@ -9,7 +9,7 @@ CFLAGS_trace.o := -I$(src)
9 9
10mt76x2-common-y := \ 10mt76x2-common-y := \
11 mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \ 11 mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \
12 mt76x2_init_common.o 12 mt76x2_init_common.o mt76x2_common.o
13 13
14mt76x2e-y := \ 14mt76x2e-y := \
15 mt76x2_pci.o mt76x2_dma.o \ 15 mt76x2_pci.o mt76x2_dma.o \
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h
index 556a2961860b..0c129d6a9466 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h
@@ -293,4 +293,25 @@ void mt76x2_init_txpower(struct mt76x2_dev *dev,
293 struct ieee80211_supported_band *sband); 293 struct ieee80211_supported_band *sband);
294void mt76_write_mac_initvals(struct mt76x2_dev *dev); 294void mt76_write_mac_initvals(struct mt76x2_dev *dev);
295 295
296int mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
297 struct ieee80211_ampdu_params *params);
298int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
299 struct ieee80211_sta *sta);
300int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
301 struct ieee80211_sta *sta);
302void mt76x2_remove_interface(struct ieee80211_hw *hw,
303 struct ieee80211_vif *vif);
304int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
305 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
306 struct ieee80211_key_conf *key);
307int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
308 u16 queue, const struct ieee80211_tx_queue_params *params);
309void mt76x2_configure_filter(struct ieee80211_hw *hw,
310 unsigned int changed_flags,
311 unsigned int *total_flags, u64 multicast);
312void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq);
313void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw,
314 struct ieee80211_vif *vif,
315 struct ieee80211_sta *sta);
316
296#endif 317#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c
new file mode 100644
index 000000000000..a2338ba139b4
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c
@@ -0,0 +1,350 @@
1/*
2 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "mt76x2.h"
19
20void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq)
21{
22 struct mt76_txq *mtxq;
23
24 if (!txq)
25 return;
26
27 mtxq = (struct mt76_txq *) txq->drv_priv;
28 if (txq->sta) {
29 struct mt76x2_sta *sta;
30
31 sta = (struct mt76x2_sta *) txq->sta->drv_priv;
32 mtxq->wcid = &sta->wcid;
33 } else {
34 struct mt76x2_vif *mvif;
35
36 mvif = (struct mt76x2_vif *) txq->vif->drv_priv;
37 mtxq->wcid = &mvif->group_wcid;
38 }
39
40 mt76_txq_init(&dev->mt76, txq);
41}
42EXPORT_SYMBOL_GPL(mt76x2_txq_init);
43
44int mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
45 struct ieee80211_ampdu_params *params)
46{
47 enum ieee80211_ampdu_mlme_action action = params->action;
48 struct ieee80211_sta *sta = params->sta;
49 struct mt76x2_dev *dev = hw->priv;
50 struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
51 struct ieee80211_txq *txq = sta->txq[params->tid];
52 u16 tid = params->tid;
53 u16 *ssn = &params->ssn;
54 struct mt76_txq *mtxq;
55
56 if (!txq)
57 return -EINVAL;
58
59 mtxq = (struct mt76_txq *)txq->drv_priv;
60
61 switch (action) {
62 case IEEE80211_AMPDU_RX_START:
63 mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, *ssn, params->buf_size);
64 mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
65 break;
66 case IEEE80211_AMPDU_RX_STOP:
67 mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
68 mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4,
69 BIT(16 + tid));
70 break;
71 case IEEE80211_AMPDU_TX_OPERATIONAL:
72 mtxq->aggr = true;
73 mtxq->send_bar = false;
74 ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
75 break;
76 case IEEE80211_AMPDU_TX_STOP_FLUSH:
77 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
78 mtxq->aggr = false;
79 ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
80 break;
81 case IEEE80211_AMPDU_TX_START:
82 mtxq->agg_ssn = *ssn << 4;
83 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
84 break;
85 case IEEE80211_AMPDU_TX_STOP_CONT:
86 mtxq->aggr = false;
87 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
88 break;
89 }
90
91 return 0;
92}
93EXPORT_SYMBOL_GPL(mt76x2_ampdu_action);
94
95int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
96 struct ieee80211_sta *sta)
97{
98 struct mt76x2_dev *dev = hw->priv;
99 struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
100 struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv;
101 int ret = 0;
102 int idx = 0;
103 int i;
104
105 mutex_lock(&dev->mutex);
106
107 idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid));
108 if (idx < 0) {
109 ret = -ENOSPC;
110 goto out;
111 }
112
113 msta->vif = mvif;
114 msta->wcid.sta = 1;
115 msta->wcid.idx = idx;
116 msta->wcid.hw_key_idx = -1;
117 mt76x2_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
118 mt76x2_mac_wcid_set_drop(dev, idx, false);
119 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
120 mt76x2_txq_init(dev, sta->txq[i]);
121
122 if (vif->type == NL80211_IFTYPE_AP)
123 set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
124
125 ewma_signal_init(&msta->rssi);
126
127 rcu_assign_pointer(dev->wcid[idx], &msta->wcid);
128
129out:
130 mutex_unlock(&dev->mutex);
131
132 return ret;
133}
134EXPORT_SYMBOL_GPL(mt76x2_sta_add);
135
136int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
137 struct ieee80211_sta *sta)
138{
139 struct mt76x2_dev *dev = hw->priv;
140 struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
141 int idx = msta->wcid.idx;
142 int i;
143
144 mutex_lock(&dev->mutex);
145 rcu_assign_pointer(dev->wcid[idx], NULL);
146 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
147 mt76_txq_remove(&dev->mt76, sta->txq[i]);
148 mt76x2_mac_wcid_set_drop(dev, idx, true);
149 mt76_wcid_free(dev->wcid_mask, idx);
150 mt76x2_mac_wcid_setup(dev, idx, 0, NULL);
151 mutex_unlock(&dev->mutex);
152
153 return 0;
154}
155EXPORT_SYMBOL_GPL(mt76x2_sta_remove);
156
157void mt76x2_remove_interface(struct ieee80211_hw *hw,
158 struct ieee80211_vif *vif)
159{
160 struct mt76x2_dev *dev = hw->priv;
161
162 mt76_txq_remove(&dev->mt76, vif->txq);
163}
164EXPORT_SYMBOL_GPL(mt76x2_remove_interface);
165
166int mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
167 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
168 struct ieee80211_key_conf *key)
169{
170 struct mt76x2_dev *dev = hw->priv;
171 struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv;
172 struct mt76x2_sta *msta;
173 struct mt76_wcid *wcid;
174 int idx = key->keyidx;
175 int ret;
176
177 /* fall back to sw encryption for unsupported ciphers */
178 switch (key->cipher) {
179 case WLAN_CIPHER_SUITE_WEP40:
180 case WLAN_CIPHER_SUITE_WEP104:
181 case WLAN_CIPHER_SUITE_TKIP:
182 case WLAN_CIPHER_SUITE_CCMP:
183 break;
184 default:
185 return -EOPNOTSUPP;
186 }
187
188 /*
189 * The hardware does not support per-STA RX GTK, fall back
190 * to software mode for these.
191 */
192 if ((vif->type == NL80211_IFTYPE_ADHOC ||
193 vif->type == NL80211_IFTYPE_MESH_POINT) &&
194 (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
195 key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
196 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
197 return -EOPNOTSUPP;
198
199 msta = sta ? (struct mt76x2_sta *) sta->drv_priv : NULL;
200 wcid = msta ? &msta->wcid : &mvif->group_wcid;
201
202 if (cmd == SET_KEY) {
203 key->hw_key_idx = wcid->idx;
204 wcid->hw_key_idx = idx;
205 if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
206 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
207 wcid->sw_iv = true;
208 }
209 } else {
210 if (idx == wcid->hw_key_idx) {
211 wcid->hw_key_idx = -1;
212 wcid->sw_iv = true;
213 }
214
215 key = NULL;
216 }
217 mt76_wcid_key_setup(&dev->mt76, wcid, key);
218
219 if (!msta) {
220 if (key || wcid->hw_key_idx == idx) {
221 ret = mt76x2_mac_wcid_set_key(dev, wcid->idx, key);
222 if (ret)
223 return ret;
224 }
225
226 return mt76x2_mac_shared_key_setup(dev, mvif->idx, idx, key);
227 }
228
229 return mt76x2_mac_wcid_set_key(dev, msta->wcid.idx, key);
230}
231EXPORT_SYMBOL_GPL(mt76x2_set_key);
232
233int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
234 u16 queue, const struct ieee80211_tx_queue_params *params)
235{
236 struct mt76x2_dev *dev = hw->priv;
237 u8 cw_min = 5, cw_max = 10, qid;
238 u32 val;
239
240 qid = dev->mt76.q_tx[queue].hw_idx;
241
242 if (params->cw_min)
243 cw_min = fls(params->cw_min);
244 if (params->cw_max)
245 cw_max = fls(params->cw_max);
246
247 val = FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop) |
248 FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) |
249 FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) |
250 FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max);
251 mt76_wr(dev, MT_EDCA_CFG_AC(qid), val);
252
253 val = mt76_rr(dev, MT_WMM_TXOP(qid));
254 val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid));
255 val |= params->txop << MT_WMM_TXOP_SHIFT(qid);
256 mt76_wr(dev, MT_WMM_TXOP(qid), val);
257
258 val = mt76_rr(dev, MT_WMM_AIFSN);
259 val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid));
260 val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid);
261 mt76_wr(dev, MT_WMM_AIFSN, val);
262
263 val = mt76_rr(dev, MT_WMM_CWMIN);
264 val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid));
265 val |= cw_min << MT_WMM_CWMIN_SHIFT(qid);
266 mt76_wr(dev, MT_WMM_CWMIN, val);
267
268 val = mt76_rr(dev, MT_WMM_CWMAX);
269 val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid));
270 val |= cw_max << MT_WMM_CWMAX_SHIFT(qid);
271 mt76_wr(dev, MT_WMM_CWMAX, val);
272
273 return 0;
274}
275EXPORT_SYMBOL_GPL(mt76x2_conf_tx);
276
277void mt76x2_configure_filter(struct ieee80211_hw *hw,
278 unsigned int changed_flags,
279 unsigned int *total_flags, u64 multicast)
280{
281 struct mt76x2_dev *dev = hw->priv;
282 u32 flags = 0;
283
284#define MT76_FILTER(_flag, _hw) do { \
285 flags |= *total_flags & FIF_##_flag; \
286 dev->rxfilter &= ~(_hw); \
287 dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \
288 } while (0)
289
290 mutex_lock(&dev->mutex);
291
292 dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS;
293
294 MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR);
295 MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR);
296 MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK |
297 MT_RX_FILTR_CFG_CTS |
298 MT_RX_FILTR_CFG_CFEND |
299 MT_RX_FILTR_CFG_CFACK |
300 MT_RX_FILTR_CFG_BA |
301 MT_RX_FILTR_CFG_CTRL_RSV);
302 MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL);
303
304 *total_flags = flags;
305 mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter);
306
307 mutex_unlock(&dev->mutex);
308}
309EXPORT_SYMBOL_GPL(mt76x2_configure_filter);
310
311void mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw,
312 struct ieee80211_vif *vif,
313 struct ieee80211_sta *sta)
314{
315 struct mt76x2_dev *dev = hw->priv;
316 struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
317 struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates);
318 struct ieee80211_tx_rate rate = {};
319
320 if (!rates)
321 return;
322
323 rate.idx = rates->rate[0].idx;
324 rate.flags = rates->rate[0].flags;
325 mt76x2_mac_wcid_set_rate(dev, &msta->wcid, &rate);
326 msta->wcid.max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(dev, &rate);
327}
328EXPORT_SYMBOL_GPL(mt76x2_sta_rate_tbl_update);
329
330void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
331 struct sk_buff *skb)
332{
333 struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
334 void *rxwi = skb->data;
335
336 if (q == MT_RXQ_MCU) {
337 skb_queue_tail(&dev->mcu.res_q, skb);
338 wake_up(&dev->mcu.wait);
339 return;
340 }
341
342 skb_pull(skb, sizeof(struct mt76x2_rxwi));
343 if (mt76x2_mac_process_rx(dev, skb, rxwi)) {
344 dev_kfree_skb(skb);
345 return;
346 }
347
348 mt76_rx(&dev->mt76, q, skb);
349}
350EXPORT_SYMBOL_GPL(mt76x2_queue_rx_skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c
index fd1ec4743e0b..6720a6a1313f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c
@@ -66,27 +66,6 @@ mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76_queue *q,
66 return 0; 66 return 0;
67} 67}
68 68
69void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
70 struct sk_buff *skb)
71{
72 struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
73 void *rxwi = skb->data;
74
75 if (q == MT_RXQ_MCU) {
76 skb_queue_tail(&dev->mcu.res_q, skb);
77 wake_up(&dev->mcu.wait);
78 return;
79 }
80
81 skb_pull(skb, sizeof(struct mt76x2_rxwi));
82 if (mt76x2_mac_process_rx(dev, skb, rxwi)) {
83 dev_kfree_skb(skb);
84 return;
85 }
86
87 mt76_rx(&dev->mt76, q, skb);
88}
89
90static int 69static int
91mt76x2_init_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, 70mt76x2_init_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q,
92 int idx, int n_desc, int bufsize) 71 int idx, int n_desc, int bufsize)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index 1f4d3e5ae64b..680a89f8aa87 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -53,30 +53,6 @@ mt76x2_stop(struct ieee80211_hw *hw)
53 mutex_unlock(&dev->mutex); 53 mutex_unlock(&dev->mutex);
54} 54}
55 55
56static void
57mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq)
58{
59 struct mt76_txq *mtxq;
60
61 if (!txq)
62 return;
63
64 mtxq = (struct mt76_txq *) txq->drv_priv;
65 if (txq->sta) {
66 struct mt76x2_sta *sta;
67
68 sta = (struct mt76x2_sta *) txq->sta->drv_priv;
69 mtxq->wcid = &sta->wcid;
70 } else {
71 struct mt76x2_vif *mvif;
72
73 mvif = (struct mt76x2_vif *) txq->vif->drv_priv;
74 mtxq->wcid = &mvif->group_wcid;
75 }
76
77 mt76_txq_init(&dev->mt76, txq);
78}
79
80static int 56static int
81mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 57mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
82{ 58{
@@ -111,14 +87,6 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
111 return 0; 87 return 0;
112} 88}
113 89
114static void
115mt76x2_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
116{
117 struct mt76x2_dev *dev = hw->priv;
118
119 mt76_txq_remove(&dev->mt76, vif->txq);
120}
121
122static int 90static int
123mt76x2_set_channel(struct mt76x2_dev *dev, struct cfg80211_chan_def *chandef) 91mt76x2_set_channel(struct mt76x2_dev *dev, struct cfg80211_chan_def *chandef)
124{ 92{
@@ -194,39 +162,6 @@ mt76x2_config(struct ieee80211_hw *hw, u32 changed)
194} 162}
195 163
196static void 164static void
197mt76x2_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
198 unsigned int *total_flags, u64 multicast)
199{
200 struct mt76x2_dev *dev = hw->priv;
201 u32 flags = 0;
202
203#define MT76_FILTER(_flag, _hw) do { \
204 flags |= *total_flags & FIF_##_flag; \
205 dev->rxfilter &= ~(_hw); \
206 dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \
207 } while (0)
208
209 mutex_lock(&dev->mutex);
210
211 dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS;
212
213 MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR);
214 MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR);
215 MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK |
216 MT_RX_FILTR_CFG_CTS |
217 MT_RX_FILTR_CFG_CFEND |
218 MT_RX_FILTR_CFG_CFACK |
219 MT_RX_FILTR_CFG_BA |
220 MT_RX_FILTR_CFG_CTRL_RSV);
221 MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL);
222
223 *total_flags = flags;
224 mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter);
225
226 mutex_unlock(&dev->mutex);
227}
228
229static void
230mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 165mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
231 struct ieee80211_bss_conf *info, u32 changed) 166 struct ieee80211_bss_conf *info, u32 changed)
232{ 167{
@@ -263,68 +198,6 @@ mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
263 mutex_unlock(&dev->mutex); 198 mutex_unlock(&dev->mutex);
264} 199}
265 200
266static int
267mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
268 struct ieee80211_sta *sta)
269{
270 struct mt76x2_dev *dev = hw->priv;
271 struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
272 struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv;
273 int ret = 0;
274 int idx = 0;
275 int i;
276
277 mutex_lock(&dev->mutex);
278
279 idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid));
280 if (idx < 0) {
281 ret = -ENOSPC;
282 goto out;
283 }
284
285 msta->vif = mvif;
286 msta->wcid.sta = 1;
287 msta->wcid.idx = idx;
288 msta->wcid.hw_key_idx = -1;
289 mt76x2_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
290 mt76x2_mac_wcid_set_drop(dev, idx, false);
291 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
292 mt76x2_txq_init(dev, sta->txq[i]);
293
294 if (vif->type == NL80211_IFTYPE_AP)
295 set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
296
297 ewma_signal_init(&msta->rssi);
298
299 rcu_assign_pointer(dev->wcid[idx], &msta->wcid);
300
301out:
302 mutex_unlock(&dev->mutex);
303
304 return ret;
305}
306
307static int
308mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
309 struct ieee80211_sta *sta)
310{
311 struct mt76x2_dev *dev = hw->priv;
312 struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
313 int idx = msta->wcid.idx;
314 int i;
315
316 mutex_lock(&dev->mutex);
317 rcu_assign_pointer(dev->wcid[idx], NULL);
318 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
319 mt76_txq_remove(&dev->mt76, sta->txq[i]);
320 mt76x2_mac_wcid_set_drop(dev, idx, true);
321 mt76_wcid_free(dev->wcid_mask, idx);
322 mt76x2_mac_wcid_setup(dev, idx, 0, NULL);
323 mutex_unlock(&dev->mutex);
324
325 return 0;
326}
327
328void 201void
329mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps) 202mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
330{ 203{
@@ -336,117 +209,6 @@ mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
336 mt76x2_mac_wcid_set_drop(dev, idx, ps); 209 mt76x2_mac_wcid_set_drop(dev, idx, ps);
337} 210}
338 211
339static int
340mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
341 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
342 struct ieee80211_key_conf *key)
343{
344 struct mt76x2_dev *dev = hw->priv;
345 struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv;
346 struct mt76x2_sta *msta;
347 struct mt76_wcid *wcid;
348 int idx = key->keyidx;
349 int ret;
350
351 /* fall back to sw encryption for unsupported ciphers */
352 switch (key->cipher) {
353 case WLAN_CIPHER_SUITE_WEP40:
354 case WLAN_CIPHER_SUITE_WEP104:
355 case WLAN_CIPHER_SUITE_TKIP:
356 case WLAN_CIPHER_SUITE_CCMP:
357 break;
358 default:
359 return -EOPNOTSUPP;
360 }
361
362 /*
363 * The hardware does not support per-STA RX GTK, fall back
364 * to software mode for these.
365 */
366 if ((vif->type == NL80211_IFTYPE_ADHOC ||
367 vif->type == NL80211_IFTYPE_MESH_POINT) &&
368 (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
369 key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
370 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
371 return -EOPNOTSUPP;
372
373 msta = sta ? (struct mt76x2_sta *) sta->drv_priv : NULL;
374 wcid = msta ? &msta->wcid : &mvif->group_wcid;
375
376 if (cmd == SET_KEY) {
377 key->hw_key_idx = wcid->idx;
378 wcid->hw_key_idx = idx;
379 if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
380 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
381 wcid->sw_iv = true;
382 }
383 } else {
384 if (idx == wcid->hw_key_idx) {
385 wcid->hw_key_idx = -1;
386 wcid->sw_iv = true;
387 }
388
389 key = NULL;
390 }
391 mt76_wcid_key_setup(&dev->mt76, wcid, key);
392
393 if (!msta) {
394 if (key || wcid->hw_key_idx == idx) {
395 ret = mt76x2_mac_wcid_set_key(dev, wcid->idx, key);
396 if (ret)
397 return ret;
398 }
399
400 return mt76x2_mac_shared_key_setup(dev, mvif->idx, idx, key);
401 }
402
403 return mt76x2_mac_wcid_set_key(dev, msta->wcid.idx, key);
404}
405
406static int
407mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
408 const struct ieee80211_tx_queue_params *params)
409{
410 struct mt76x2_dev *dev = hw->priv;
411 u8 cw_min = 5, cw_max = 10, qid;
412 u32 val;
413
414 qid = dev->mt76.q_tx[queue].hw_idx;
415
416 if (params->cw_min)
417 cw_min = fls(params->cw_min);
418 if (params->cw_max)
419 cw_max = fls(params->cw_max);
420
421 val = FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop) |
422 FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) |
423 FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) |
424 FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max);
425 mt76_wr(dev, MT_EDCA_CFG_AC(qid), val);
426
427 val = mt76_rr(dev, MT_WMM_TXOP(qid));
428 val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid));
429 val |= params->txop << MT_WMM_TXOP_SHIFT(qid);
430 mt76_wr(dev, MT_WMM_TXOP(qid), val);
431
432 val = mt76_rr(dev, MT_WMM_AIFSN);
433 val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid));
434 val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid);
435 mt76_wr(dev, MT_WMM_AIFSN, val);
436
437 val = mt76_rr(dev, MT_WMM_CWMIN);
438 val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid));
439 val |= cw_min << MT_WMM_CWMIN_SHIFT(qid);
440 mt76_wr(dev, MT_WMM_CWMIN, val);
441
442 val = mt76_rr(dev, MT_WMM_CWMAX);
443 val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid));
444 val |= cw_max << MT_WMM_CWMAX_SHIFT(qid);
445 mt76_wr(dev, MT_WMM_CWMAX, val);
446
447 return 0;
448}
449
450static void 212static void
451mt76x2_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 213mt76x2_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
452 const u8 *mac) 214 const u8 *mac)
@@ -485,75 +247,6 @@ mt76x2_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm)
485 return 0; 247 return 0;
486} 248}
487 249
488static int
489mt76x2_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
490 struct ieee80211_ampdu_params *params)
491{
492 enum ieee80211_ampdu_mlme_action action = params->action;
493 struct ieee80211_sta *sta = params->sta;
494 struct mt76x2_dev *dev = hw->priv;
495 struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
496 struct ieee80211_txq *txq = sta->txq[params->tid];
497 u16 tid = params->tid;
498 u16 *ssn = &params->ssn;
499 struct mt76_txq *mtxq;
500
501 if (!txq)
502 return -EINVAL;
503
504 mtxq = (struct mt76_txq *)txq->drv_priv;
505
506 switch (action) {
507 case IEEE80211_AMPDU_RX_START:
508 mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, *ssn, params->buf_size);
509 mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
510 break;
511 case IEEE80211_AMPDU_RX_STOP:
512 mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
513 mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4,
514 BIT(16 + tid));
515 break;
516 case IEEE80211_AMPDU_TX_OPERATIONAL:
517 mtxq->aggr = true;
518 mtxq->send_bar = false;
519 ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
520 break;
521 case IEEE80211_AMPDU_TX_STOP_FLUSH:
522 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
523 mtxq->aggr = false;
524 ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
525 break;
526 case IEEE80211_AMPDU_TX_START:
527 mtxq->agg_ssn = *ssn << 4;
528 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
529 break;
530 case IEEE80211_AMPDU_TX_STOP_CONT:
531 mtxq->aggr = false;
532 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
533 break;
534 }
535
536 return 0;
537}
538
539static void
540mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
541 struct ieee80211_sta *sta)
542{
543 struct mt76x2_dev *dev = hw->priv;
544 struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
545 struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates);
546 struct ieee80211_tx_rate rate = {};
547
548 if (!rates)
549 return;
550
551 rate.idx = rates->rate[0].idx;
552 rate.flags = rates->rate[0].flags;
553 mt76x2_mac_wcid_set_rate(dev, &msta->wcid, &rate);
554 msta->wcid.max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(dev, &rate);
555}
556
557static void mt76x2_set_coverage_class(struct ieee80211_hw *hw, 250static void mt76x2_set_coverage_class(struct ieee80211_hw *hw,
558 s16 coverage_class) 251 s16 coverage_class)
559{ 252{