block: don't deal with discard limit in blkdev_issue_discard()
[linux-2.6-block.git] / drivers / net / wireless / mediatek / mt76 / mt76x0 / main.c
1 /*
2  * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
3  * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
4  * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2
8  * as published by the Free Software Foundation
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  */
15
16 #include "mt76x0.h"
17 #include "mac.h"
18 #include <linux/etherdevice.h>
19
20 static int mt76x0_start(struct ieee80211_hw *hw)
21 {
22         struct mt76x0_dev *dev = hw->priv;
23         int ret;
24
25         mutex_lock(&dev->mutex);
26
27         ret = mt76x0_mac_start(dev);
28         if (ret)
29                 goto out;
30
31         ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work,
32                                      MT_CALIBRATE_INTERVAL);
33         ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
34                                      MT_CALIBRATE_INTERVAL);
35 out:
36         mutex_unlock(&dev->mutex);
37         return ret;
38 }
39
40 static void mt76x0_stop(struct ieee80211_hw *hw)
41 {
42         struct mt76x0_dev *dev = hw->priv;
43
44         mutex_lock(&dev->mutex);
45
46         cancel_delayed_work_sync(&dev->cal_work);
47         cancel_delayed_work_sync(&dev->mac_work);
48         mt76x0_mac_stop(dev);
49
50         mutex_unlock(&dev->mutex);
51 }
52
53
54 static int mt76x0_add_interface(struct ieee80211_hw *hw,
55                                  struct ieee80211_vif *vif)
56 {
57         struct mt76x0_dev *dev = hw->priv;
58         struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv;
59         unsigned int idx;
60
61         idx = ffs(~dev->vif_mask);
62         if (!idx || idx > 8)
63                 return -ENOSPC;
64
65         idx--;
66         dev->vif_mask |= BIT(idx);
67
68         mvif->idx = idx;
69         mvif->group_wcid.idx = GROUP_WCID(idx);
70         mvif->group_wcid.hw_key_idx = -1;
71
72         return 0;
73 }
74
75 static void mt76x0_remove_interface(struct ieee80211_hw *hw,
76                                      struct ieee80211_vif *vif)
77 {
78         struct mt76x0_dev *dev = hw->priv;
79         struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv;
80         unsigned int wcid = mvif->group_wcid.idx;
81
82         dev->wcid_mask[wcid / BITS_PER_LONG] &= ~BIT(wcid % BITS_PER_LONG);
83 }
84
85 static int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
86 {
87         struct mt76x0_dev *dev = hw->priv;
88         int ret = 0;
89
90         mutex_lock(&dev->mutex);
91
92         if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
93                 if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
94                         dev->rxfilter |= MT_RX_FILTR_CFG_PROMISC;
95                 else
96                         dev->rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
97
98                 mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter);
99         }
100
101         if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
102                 ieee80211_stop_queues(hw);
103                 ret = mt76x0_phy_set_channel(dev, &hw->conf.chandef);
104                 ieee80211_wake_queues(hw);
105         }
106
107         mutex_unlock(&dev->mutex);
108
109         return ret;
110 }
111
112 static void
113 mt76_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
114                       unsigned int *total_flags, u64 multicast)
115 {
116         struct mt76x0_dev *dev = hw->priv;
117         u32 flags = 0;
118
119 #define MT76_FILTER(_flag, _hw) do { \
120                 flags |= *total_flags & FIF_##_flag;                    \
121                 dev->rxfilter &= ~(_hw);                                \
122                 dev->rxfilter |= !(flags & FIF_##_flag) * (_hw);        \
123         } while (0)
124
125         mutex_lock(&dev->mutex);
126
127         dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS;
128
129         MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR);
130         MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR);
131         MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK |
132                              MT_RX_FILTR_CFG_CTS |
133                              MT_RX_FILTR_CFG_CFEND |
134                              MT_RX_FILTR_CFG_CFACK |
135                              MT_RX_FILTR_CFG_BA |
136                              MT_RX_FILTR_CFG_CTRL_RSV);
137         MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL);
138
139         *total_flags = flags;
140         mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter);
141
142         mutex_unlock(&dev->mutex);
143 }
144
145 static void
146 mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
147                          struct ieee80211_bss_conf *info, u32 changed)
148 {
149         struct mt76x0_dev *dev = hw->priv;
150
151         mutex_lock(&dev->mutex);
152
153         if (changed & BSS_CHANGED_ASSOC)
154                 mt76x0_phy_con_cal_onoff(dev, info);
155
156         if (changed & BSS_CHANGED_BSSID) {
157                 mt76x0_addr_wr(dev, MT_MAC_BSSID_DW0, info->bssid);
158
159                 /* Note: this is a hack because beacon_int is not changed
160                  *       on leave nor is any more appropriate event generated.
161                  *       rt2x00 doesn't seem to be bothered though.
162                  */
163                 if (is_zero_ether_addr(info->bssid))
164                         mt76x0_mac_config_tsf(dev, false, 0);
165         }
166
167         if (changed & BSS_CHANGED_BASIC_RATES) {
168                 mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates);
169                 mt76_wr(dev, MT_HT_FBK_CFG0, 0x65432100);
170                 mt76_wr(dev, MT_HT_FBK_CFG1, 0xedcba980);
171                 mt76_wr(dev, MT_LG_FBK_CFG0, 0xedcba988);
172                 mt76_wr(dev, MT_LG_FBK_CFG1, 0x00002100);
173         }
174
175         if (changed & BSS_CHANGED_BEACON_INT)
176                 mt76x0_mac_config_tsf(dev, true, info->beacon_int);
177
178         if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
179                 mt76x0_mac_set_protection(dev, info->use_cts_prot,
180                                            info->ht_operation_mode);
181
182         if (changed & BSS_CHANGED_ERP_PREAMBLE)
183                 mt76x0_mac_set_short_preamble(dev, info->use_short_preamble);
184
185         if (changed & BSS_CHANGED_ERP_SLOT) {
186                 int slottime = info->use_short_slot ? 9 : 20;
187
188                 mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
189                                MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
190         }
191
192         if (changed & BSS_CHANGED_ASSOC)
193                 mt76x0_phy_recalibrate_after_assoc(dev);
194
195         mutex_unlock(&dev->mutex);
196 }
197
198 static int
199 mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
200                 struct ieee80211_sta *sta)
201 {
202         struct mt76x0_dev *dev = hw->priv;
203         struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
204         struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv;
205         int ret = 0;
206         int idx = 0;
207
208         mutex_lock(&dev->mutex);
209
210         idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid));
211         if (idx < 0) {
212                 ret = -ENOSPC;
213                 goto out;
214         }
215
216         msta->wcid.idx = idx;
217         msta->wcid.hw_key_idx = -1;
218         mt76x0_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
219         mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx));
220         rcu_assign_pointer(dev->wcid[idx], &msta->wcid);
221         mt76x0_mac_set_ampdu_factor(dev);
222
223 out:
224         mutex_unlock(&dev->mutex);
225
226         return ret;
227 }
228
229 static int
230 mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
231                    struct ieee80211_sta *sta)
232 {
233         struct mt76x0_dev *dev = hw->priv;
234         struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
235         int idx = msta->wcid.idx;
236
237         mutex_lock(&dev->mutex);
238         rcu_assign_pointer(dev->wcid[idx], NULL);
239         mt76_set(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx));
240         dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG);
241         mt76x0_mac_wcid_setup(dev, idx, 0, NULL);
242         mt76x0_mac_set_ampdu_factor(dev);
243         mutex_unlock(&dev->mutex);
244
245         return 0;
246 }
247
248 static void
249 mt76x0_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
250                    enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
251 {
252 }
253
254 static void
255 mt76x0_sw_scan(struct ieee80211_hw *hw,
256                 struct ieee80211_vif *vif,
257                 const u8 *mac_addr)
258 {
259         struct mt76x0_dev *dev = hw->priv;
260
261         cancel_delayed_work_sync(&dev->cal_work);
262         mt76x0_agc_save(dev);
263         set_bit(MT76_SCANNING, &dev->mt76.state);
264 }
265
266 static void
267 mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
268                          struct ieee80211_vif *vif)
269 {
270         struct mt76x0_dev *dev = hw->priv;
271
272         mt76x0_agc_restore(dev);
273         clear_bit(MT76_SCANNING, &dev->mt76.state);
274
275         ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
276                                      MT_CALIBRATE_INTERVAL);
277 }
278
279 static int
280 mt76x0_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
281                 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
282                 struct ieee80211_key_conf *key)
283 {
284         struct mt76x0_dev *dev = hw->priv;
285         struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv;
286         struct mt76_sta *msta = sta ? (struct mt76_sta *) sta->drv_priv : NULL;
287         struct mt76_wcid *wcid = msta ? &msta->wcid : &mvif->group_wcid;
288         int idx = key->keyidx;
289         int ret;
290
291         if (cmd == SET_KEY) {
292                 key->hw_key_idx = wcid->idx;
293                 wcid->hw_key_idx = idx;
294         } else {
295                 if (idx == wcid->hw_key_idx)
296                         wcid->hw_key_idx = -1;
297
298                 key = NULL;
299         }
300
301         if (!msta) {
302                 if (key || wcid->hw_key_idx == idx) {
303                         ret = mt76x0_mac_wcid_set_key(dev, wcid->idx, key);
304                         if (ret)
305                                 return ret;
306                 }
307
308                 return mt76x0_mac_shared_key_setup(dev, mvif->idx, idx, key);
309         }
310
311         return mt76x0_mac_wcid_set_key(dev, msta->wcid.idx, key);
312 }
313
314 static int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
315 {
316         struct mt76x0_dev *dev = hw->priv;
317
318         mt76_rmw_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH, value);
319
320         return 0;
321 }
322
323 static int
324 mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
325                   struct ieee80211_ampdu_params *params)
326 {
327         struct mt76x0_dev *dev = hw->priv;
328         struct ieee80211_sta *sta = params->sta;
329         enum ieee80211_ampdu_mlme_action action = params->action;
330         u16 tid = params->tid;
331         u16 *ssn = &params->ssn;
332         struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
333
334         WARN_ON(msta->wcid.idx > N_WCIDS);
335
336         switch (action) {
337         case IEEE80211_AMPDU_RX_START:
338                 mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
339                 break;
340         case IEEE80211_AMPDU_RX_STOP:
341                 mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
342                 break;
343         case IEEE80211_AMPDU_TX_OPERATIONAL:
344                 ieee80211_send_bar(vif, sta->addr, tid, msta->agg_ssn[tid]);
345                 break;
346         case IEEE80211_AMPDU_TX_STOP_FLUSH:
347         case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
348                 break;
349         case IEEE80211_AMPDU_TX_START:
350                 msta->agg_ssn[tid] = *ssn << 4;
351                 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
352                 break;
353         case IEEE80211_AMPDU_TX_STOP_CONT:
354                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
355                 break;
356         }
357
358         return 0;
359 }
360
361 static void
362 mt76_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
363                          struct ieee80211_sta *sta)
364 {
365         struct mt76x0_dev *dev = hw->priv;
366         struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
367         struct ieee80211_sta_rates *rates;
368         struct ieee80211_tx_rate rate = {};
369
370         rcu_read_lock();
371         rates = rcu_dereference(sta->rates);
372
373         if (!rates)
374                 goto out;
375
376         rate.idx = rates->rate[0].idx;
377         rate.flags = rates->rate[0].flags;
378         mt76x0_mac_wcid_set_rate(dev, &msta->wcid, &rate);
379
380 out:
381         rcu_read_unlock();
382 }
383
384 const struct ieee80211_ops mt76x0_ops = {
385         .tx = mt76x0_tx,
386         .start = mt76x0_start,
387         .stop = mt76x0_stop,
388         .add_interface = mt76x0_add_interface,
389         .remove_interface = mt76x0_remove_interface,
390         .config = mt76x0_config,
391         .configure_filter = mt76_configure_filter,
392         .bss_info_changed = mt76x0_bss_info_changed,
393         .sta_add = mt76x0_sta_add,
394         .sta_remove = mt76x0_sta_remove,
395         .sta_notify = mt76x0_sta_notify,
396         .set_key = mt76x0_set_key,
397         .conf_tx = mt76x0_conf_tx,
398         .sw_scan_start = mt76x0_sw_scan,
399         .sw_scan_complete = mt76x0_sw_scan_complete,
400         .ampdu_action = mt76_ampdu_action,
401         .sta_rate_tbl_update = mt76_sta_rate_tbl_update,
402         .set_rts_threshold = mt76x0_set_rts_threshold,
403 };