netfilter: netns: shrink netns_ct struct
[linux-2.6-microblaze.git] / drivers / net / wireless / mediatek / mt76 / mt76x02_util.c
1 /*
2  * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
3  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
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 <linux/module.h>
19 #include "mt76x02.h"
20
21 #define CCK_RATE(_idx, _rate) {                                 \
22         .bitrate = _rate,                                       \
23         .flags = IEEE80211_RATE_SHORT_PREAMBLE,                 \
24         .hw_value = (MT_PHY_TYPE_CCK << 8) | _idx,              \
25         .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx),  \
26 }
27
28 #define OFDM_RATE(_idx, _rate) {                                \
29         .bitrate = _rate,                                       \
30         .hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx,             \
31         .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx,       \
32 }
33
34 struct ieee80211_rate mt76x02_rates[] = {
35         CCK_RATE(0, 10),
36         CCK_RATE(1, 20),
37         CCK_RATE(2, 55),
38         CCK_RATE(3, 110),
39         OFDM_RATE(0, 60),
40         OFDM_RATE(1, 90),
41         OFDM_RATE(2, 120),
42         OFDM_RATE(3, 180),
43         OFDM_RATE(4, 240),
44         OFDM_RATE(5, 360),
45         OFDM_RATE(6, 480),
46         OFDM_RATE(7, 540),
47 };
48 EXPORT_SYMBOL_GPL(mt76x02_rates);
49
50 void mt76x02_configure_filter(struct ieee80211_hw *hw,
51                               unsigned int changed_flags,
52                               unsigned int *total_flags, u64 multicast)
53 {
54         struct mt76x02_dev *dev = hw->priv;
55         u32 flags = 0;
56
57 #define MT76_FILTER(_flag, _hw) do { \
58                 flags |= *total_flags & FIF_##_flag;                    \
59                 dev->mt76.rxfilter &= ~(_hw);                           \
60                 dev->mt76.rxfilter |= !(flags & FIF_##_flag) * (_hw);   \
61         } while (0)
62
63         mutex_lock(&dev->mt76.mutex);
64
65         dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS;
66
67         MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR);
68         MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR);
69         MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK |
70                              MT_RX_FILTR_CFG_CTS |
71                              MT_RX_FILTR_CFG_CFEND |
72                              MT_RX_FILTR_CFG_CFACK |
73                              MT_RX_FILTR_CFG_BA |
74                              MT_RX_FILTR_CFG_CTRL_RSV);
75         MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL);
76
77         *total_flags = flags;
78         mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
79
80         mutex_unlock(&dev->mt76.mutex);
81 }
82 EXPORT_SYMBOL_GPL(mt76x02_configure_filter);
83
84 int mt76x02_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
85                     struct ieee80211_sta *sta)
86 {
87         struct mt76x02_dev *dev = hw->priv;
88         struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
89         struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
90         int ret = 0;
91         int idx = 0;
92         int i;
93
94         mutex_lock(&dev->mt76.mutex);
95
96         idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid));
97         if (idx < 0) {
98                 ret = -ENOSPC;
99                 goto out;
100         }
101
102         msta->vif = mvif;
103         msta->wcid.sta = 1;
104         msta->wcid.idx = idx;
105         msta->wcid.hw_key_idx = -1;
106         mt76x02_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
107         mt76x02_mac_wcid_set_drop(dev, idx, false);
108         for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
109                 mt76x02_txq_init(dev, sta->txq[i]);
110
111         if (vif->type == NL80211_IFTYPE_AP)
112                 set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
113
114         ewma_signal_init(&msta->rssi);
115
116         rcu_assign_pointer(dev->mt76.wcid[idx], &msta->wcid);
117
118 out:
119         mutex_unlock(&dev->mt76.mutex);
120
121         return ret;
122 }
123 EXPORT_SYMBOL_GPL(mt76x02_sta_add);
124
125 int mt76x02_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
126                        struct ieee80211_sta *sta)
127 {
128         struct mt76x02_dev *dev = hw->priv;
129         struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
130         int idx = msta->wcid.idx;
131         int i;
132
133         mutex_lock(&dev->mt76.mutex);
134         rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
135         for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
136                 mt76_txq_remove(&dev->mt76, sta->txq[i]);
137         mt76x02_mac_wcid_set_drop(dev, idx, true);
138         mt76_wcid_free(dev->mt76.wcid_mask, idx);
139         mt76x02_mac_wcid_setup(dev, idx, 0, NULL);
140         mutex_unlock(&dev->mt76.mutex);
141
142         return 0;
143 }
144 EXPORT_SYMBOL_GPL(mt76x02_sta_remove);
145
146 void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
147                       unsigned int idx)
148 {
149         struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
150
151         mvif->idx = idx;
152         mvif->group_wcid.idx = MT_VIF_WCID(idx);
153         mvif->group_wcid.hw_key_idx = -1;
154         mt76x02_txq_init(dev, vif->txq);
155 }
156 EXPORT_SYMBOL_GPL(mt76x02_vif_init);
157
158 int
159 mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
160 {
161         struct mt76x02_dev *dev = hw->priv;
162         unsigned int idx = 0;
163
164         if (vif->addr[0] & BIT(1))
165                 idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7);
166
167         /*
168          * Client mode typically only has one configurable BSSID register,
169          * which is used for bssidx=0. This is linked to the MAC address.
170          * Since mac80211 allows changing interface types, and we cannot
171          * force the use of the primary MAC address for a station mode
172          * interface, we need some other way of configuring a per-interface
173          * remote BSSID.
174          * The hardware provides an AP-Client feature, where bssidx 0-7 are
175          * used for AP mode and bssidx 8-15 for client mode.
176          * We shift the station interface bss index by 8 to force the
177          * hardware to recognize the BSSID.
178          * The resulting bssidx mismatch for unicast frames is ignored by hw.
179          */
180         if (vif->type == NL80211_IFTYPE_STATION)
181                 idx += 8;
182
183         mt76x02_vif_init(dev, vif, idx);
184         return 0;
185 }
186 EXPORT_SYMBOL_GPL(mt76x02_add_interface);
187
188 void mt76x02_remove_interface(struct ieee80211_hw *hw,
189                               struct ieee80211_vif *vif)
190 {
191         struct mt76x02_dev *dev = hw->priv;
192
193         mt76_txq_remove(&dev->mt76, vif->txq);
194 }
195 EXPORT_SYMBOL_GPL(mt76x02_remove_interface);
196
197 int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
198                          struct ieee80211_ampdu_params *params)
199 {
200         enum ieee80211_ampdu_mlme_action action = params->action;
201         struct ieee80211_sta *sta = params->sta;
202         struct mt76x02_dev *dev = hw->priv;
203         struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv;
204         struct ieee80211_txq *txq = sta->txq[params->tid];
205         u16 tid = params->tid;
206         u16 *ssn = &params->ssn;
207         struct mt76_txq *mtxq;
208
209         if (!txq)
210                 return -EINVAL;
211
212         mtxq = (struct mt76_txq *)txq->drv_priv;
213
214         switch (action) {
215         case IEEE80211_AMPDU_RX_START:
216                 mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid,
217                                    *ssn, params->buf_size);
218                 mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
219                 break;
220         case IEEE80211_AMPDU_RX_STOP:
221                 mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
222                 mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4,
223                            BIT(16 + tid));
224                 break;
225         case IEEE80211_AMPDU_TX_OPERATIONAL:
226                 mtxq->aggr = true;
227                 mtxq->send_bar = false;
228                 ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
229                 break;
230         case IEEE80211_AMPDU_TX_STOP_FLUSH:
231         case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
232                 mtxq->aggr = false;
233                 ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
234                 break;
235         case IEEE80211_AMPDU_TX_START:
236                 mtxq->agg_ssn = *ssn << 4;
237                 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
238                 break;
239         case IEEE80211_AMPDU_TX_STOP_CONT:
240                 mtxq->aggr = false;
241                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
242                 break;
243         }
244
245         return 0;
246 }
247 EXPORT_SYMBOL_GPL(mt76x02_ampdu_action);
248
249 int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
250                     struct ieee80211_vif *vif, struct ieee80211_sta *sta,
251                     struct ieee80211_key_conf *key)
252 {
253         struct mt76x02_dev *dev = hw->priv;
254         struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
255         struct mt76x02_sta *msta;
256         struct mt76_wcid *wcid;
257         int idx = key->keyidx;
258         int ret;
259
260         /* fall back to sw encryption for unsupported ciphers */
261         switch (key->cipher) {
262         case WLAN_CIPHER_SUITE_WEP40:
263         case WLAN_CIPHER_SUITE_WEP104:
264         case WLAN_CIPHER_SUITE_TKIP:
265         case WLAN_CIPHER_SUITE_CCMP:
266                 break;
267         default:
268                 return -EOPNOTSUPP;
269         }
270
271         /*
272          * The hardware does not support per-STA RX GTK, fall back
273          * to software mode for these.
274          */
275         if ((vif->type == NL80211_IFTYPE_ADHOC ||
276              vif->type == NL80211_IFTYPE_MESH_POINT) &&
277             (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
278              key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
279             !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
280                 return -EOPNOTSUPP;
281
282         msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL;
283         wcid = msta ? &msta->wcid : &mvif->group_wcid;
284
285         if (cmd == SET_KEY) {
286                 key->hw_key_idx = wcid->idx;
287                 wcid->hw_key_idx = idx;
288                 if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
289                         key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
290                         wcid->sw_iv = true;
291                 }
292         } else {
293                 if (idx == wcid->hw_key_idx) {
294                         wcid->hw_key_idx = -1;
295                         wcid->sw_iv = true;
296                 }
297
298                 key = NULL;
299         }
300         mt76_wcid_key_setup(&dev->mt76, wcid, key);
301
302         if (!msta) {
303                 if (key || wcid->hw_key_idx == idx) {
304                         ret = mt76x02_mac_wcid_set_key(dev, wcid->idx, key);
305                         if (ret)
306                                 return ret;
307                 }
308
309                 return mt76x02_mac_shared_key_setup(dev, mvif->idx, idx, key);
310         }
311
312         return mt76x02_mac_wcid_set_key(dev, msta->wcid.idx, key);
313 }
314 EXPORT_SYMBOL_GPL(mt76x02_set_key);
315
316 int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
317                     u16 queue, const struct ieee80211_tx_queue_params *params)
318 {
319         struct mt76x02_dev *dev = hw->priv;
320         u8 cw_min = 5, cw_max = 10, qid;
321         u32 val;
322
323         qid = dev->mt76.q_tx[queue].hw_idx;
324
325         if (params->cw_min)
326                 cw_min = fls(params->cw_min);
327         if (params->cw_max)
328                 cw_max = fls(params->cw_max);
329
330         val = FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop) |
331               FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) |
332               FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) |
333               FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max);
334         mt76_wr(dev, MT_EDCA_CFG_AC(qid), val);
335
336         val = mt76_rr(dev, MT_WMM_TXOP(qid));
337         val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid));
338         val |= params->txop << MT_WMM_TXOP_SHIFT(qid);
339         mt76_wr(dev, MT_WMM_TXOP(qid), val);
340
341         val = mt76_rr(dev, MT_WMM_AIFSN);
342         val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid));
343         val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid);
344         mt76_wr(dev, MT_WMM_AIFSN, val);
345
346         val = mt76_rr(dev, MT_WMM_CWMIN);
347         val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid));
348         val |= cw_min << MT_WMM_CWMIN_SHIFT(qid);
349         mt76_wr(dev, MT_WMM_CWMIN, val);
350
351         val = mt76_rr(dev, MT_WMM_CWMAX);
352         val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid));
353         val |= cw_max << MT_WMM_CWMAX_SHIFT(qid);
354         mt76_wr(dev, MT_WMM_CWMAX, val);
355
356         return 0;
357 }
358 EXPORT_SYMBOL_GPL(mt76x02_conf_tx);
359
360 void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw,
361                                 struct ieee80211_vif *vif,
362                                 struct ieee80211_sta *sta)
363 {
364         struct mt76x02_dev *dev = hw->priv;
365         struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv;
366         struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates);
367         struct ieee80211_tx_rate rate = {};
368
369         if (!rates)
370                 return;
371
372         rate.idx = rates->rate[0].idx;
373         rate.flags = rates->rate[0].flags;
374         mt76x02_mac_wcid_set_rate(dev, &msta->wcid, &rate);
375         msta->wcid.max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, &rate);
376 }
377 EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update);
378
379 int mt76x02_insert_hdr_pad(struct sk_buff *skb)
380 {
381         int len = ieee80211_get_hdrlen_from_skb(skb);
382
383         if (len % 4 == 0)
384                 return 0;
385
386         skb_push(skb, 2);
387         memmove(skb->data, skb->data + 2, len);
388
389         skb->data[len] = 0;
390         skb->data[len + 1] = 0;
391         return 2;
392 }
393 EXPORT_SYMBOL_GPL(mt76x02_insert_hdr_pad);
394
395 void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len)
396 {
397         int hdrlen;
398
399         if (!len)
400                 return;
401
402         hdrlen = ieee80211_get_hdrlen_from_skb(skb);
403         memmove(skb->data + len, skb->data, hdrlen);
404         skb_pull(skb, len);
405 }
406 EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad);
407
408 const u16 mt76x02_beacon_offsets[16] = {
409         /* 1024 byte per beacon */
410         0xc000,
411         0xc400,
412         0xc800,
413         0xcc00,
414         0xd000,
415         0xd400,
416         0xd800,
417         0xdc00,
418         /* BSS idx 8-15 not used for beacons */
419         0xc000,
420         0xc000,
421         0xc000,
422         0xc000,
423         0xc000,
424         0xc000,
425         0xc000,
426         0xc000,
427 };
428 EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets);
429
430 void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
431 {
432         u16 val, base = MT_BEACON_BASE;
433         u32 regs[4] = {};
434         int i;
435
436         for (i = 0; i < 16; i++) {
437                 val = mt76x02_beacon_offsets[i] - base;
438                 regs[i / 4] |= (val / 64) << (8 * (i % 4));
439         }
440
441         for (i = 0; i < 4; i++)
442                 mt76_wr(dev, MT_BCN_OFFSET(i), regs[i]);
443 }
444 EXPORT_SYMBOL_GPL(mt76x02_set_beacon_offsets);
445
446 MODULE_LICENSE("Dual BSD/GPL");