aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo.bianconi@redhat.com>2018-10-05 04:00:32 -0400
committerFelix Fietkau <nbd@nbd.name>2018-10-05 14:05:46 -0400
commit8e3ed0017bdd866a90eb9c19f67a4a8c06c892cc (patch)
tree8b1311f103c55ba8a247c10ad5ee01442c1ba52f /drivers/net/wireless
parent2f0308d0b19de89352d5e89589e4bfe8d1e7ef9f (diff)
mt76: move txrx shared routines in mt76x02_txrx.c
Add mt76x02_txrx.c source file in order to contain tx/rx shared routines for mt76x0 and mt76x2 drivers Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/mediatek/mt76/Makefile3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c162
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_util.c140
3 files changed, 164 insertions, 141 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile
index 907b9e2d7044..09c90eef61a4 100644
--- a/drivers/net/wireless/mediatek/mt76/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/Makefile
@@ -12,7 +12,8 @@ CFLAGS_trace.o := -I$(src)
12CFLAGS_usb_trace.o := -I$(src) 12CFLAGS_usb_trace.o := -I$(src)
13 13
14mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ 14mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
15 mt76x02_eeprom.o mt76x02_phy.o mt76x02_mmio.o 15 mt76x02_eeprom.o mt76x02_phy.o mt76x02_mmio.o \
16 mt76x02_txrx.o
16 17
17mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o 18mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
18 19
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
new file mode 100644
index 000000000000..caa9bb107e68
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -0,0 +1,162 @@
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 <linux/kernel.h>
19
20#include "mt76.h"
21#include "mt76x02_regs.h"
22#include "mt76x02_dma.h"
23#include "mt76x02_util.h"
24
25void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
26 struct sk_buff *skb)
27{
28 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
29 struct mt76x02_dev *dev = hw->priv;
30 struct ieee80211_vif *vif = info->control.vif;
31 struct mt76_wcid *wcid = &dev->mt76.global_wcid;
32
33 if (control->sta) {
34 struct mt76x02_sta *msta;
35
36 msta = (struct mt76x02_sta *)control->sta->drv_priv;
37 wcid = &msta->wcid;
38 /* sw encrypted frames */
39 if (!info->control.hw_key && wcid->hw_key_idx != 0xff)
40 control->sta = NULL;
41 }
42
43 if (vif && !control->sta) {
44 struct mt76x02_vif *mvif;
45
46 mvif = (struct mt76x02_vif *)vif->drv_priv;
47 wcid = &mvif->group_wcid;
48 }
49
50 mt76_tx(&dev->mt76, control->sta, wcid, skb);
51}
52EXPORT_SYMBOL_GPL(mt76x02_tx);
53
54void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
55 struct sk_buff *skb)
56{
57 struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
58 void *rxwi = skb->data;
59
60 if (q == MT_RXQ_MCU) {
61 /* this is used just by mmio code */
62 skb_queue_tail(&mdev->mmio.mcu.res_q, skb);
63 wake_up(&mdev->mmio.mcu.wait);
64 return;
65 }
66
67 skb_pull(skb, sizeof(struct mt76x02_rxwi));
68 if (mt76x02_mac_process_rx(dev, skb, rxwi)) {
69 dev_kfree_skb(skb);
70 return;
71 }
72
73 mt76_rx(mdev, q, skb);
74}
75EXPORT_SYMBOL_GPL(mt76x02_queue_rx_skb);
76
77s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev,
78 const struct ieee80211_tx_rate *rate)
79{
80 s8 max_txpwr;
81
82 if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
83 u8 mcs = ieee80211_rate_get_vht_mcs(rate);
84
85 if (mcs == 8 || mcs == 9) {
86 max_txpwr = dev->rate_power.vht[8];
87 } else {
88 u8 nss, idx;
89
90 nss = ieee80211_rate_get_vht_nss(rate);
91 idx = ((nss - 1) << 3) + mcs;
92 max_txpwr = dev->rate_power.ht[idx & 0xf];
93 }
94 } else if (rate->flags & IEEE80211_TX_RC_MCS) {
95 max_txpwr = dev->rate_power.ht[rate->idx & 0xf];
96 } else {
97 enum nl80211_band band = dev->chandef.chan->band;
98
99 if (band == NL80211_BAND_2GHZ) {
100 const struct ieee80211_rate *r;
101 struct wiphy *wiphy = dev->hw->wiphy;
102 struct mt76_rate_power *rp = &dev->rate_power;
103
104 r = &wiphy->bands[band]->bitrates[rate->idx];
105 if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE)
106 max_txpwr = rp->cck[r->hw_value & 0x3];
107 else
108 max_txpwr = rp->ofdm[r->hw_value & 0x7];
109 } else {
110 max_txpwr = dev->rate_power.ofdm[rate->idx & 0x7];
111 }
112 }
113
114 return max_txpwr;
115}
116EXPORT_SYMBOL_GPL(mt76x02_tx_get_max_txpwr_adj);
117
118static void mt76x02_remove_dma_hdr(struct sk_buff *skb)
119{
120 int hdr_len;
121
122 skb_pull(skb, sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN);
123 hdr_len = ieee80211_get_hdrlen_from_skb(skb);
124 if (hdr_len % 4)
125 mt76x02_remove_hdr_pad(skb, 2);
126}
127
128void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb)
129{
130 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
131
132 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
133 ieee80211_free_txskb(dev->hw, skb);
134 } else {
135 ieee80211_tx_info_clear_status(info);
136 info->status.rates[0].idx = -1;
137 info->flags |= IEEE80211_TX_STAT_ACK;
138 ieee80211_tx_status(dev->hw, skb);
139 }
140}
141EXPORT_SYMBOL_GPL(mt76x02_tx_complete);
142
143void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
144 struct mt76_queue_entry *e, bool flush)
145{
146 mt76x02_remove_dma_hdr(e->skb);
147 mt76x02_tx_complete(mdev, e->skb);
148}
149EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
150
151bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update)
152{
153 struct mt76x02_tx_status stat;
154
155 if (!mt76x02_mac_load_tx_status(dev, &stat))
156 return false;
157
158 mt76x02_send_tx_status(dev, &stat, update);
159
160 return true;
161}
162EXPORT_SYMBOL_GPL(mt76x02_tx_status_data);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 1d7bec697842..6e123ae3bbe8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -17,7 +17,6 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include "mt76.h" 19#include "mt76.h"
20#include "mt76x02_dma.h"
21#include "mt76x02_regs.h" 20#include "mt76x02_regs.h"
22#include "mt76x02_mac.h" 21#include "mt76x02_mac.h"
23#include "mt76x02_util.h" 22#include "mt76x02_util.h"
@@ -359,47 +358,6 @@ int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
359} 358}
360EXPORT_SYMBOL_GPL(mt76x02_conf_tx); 359EXPORT_SYMBOL_GPL(mt76x02_conf_tx);
361 360
362s8 mt76x02_tx_get_max_txpwr_adj(struct mt76_dev *dev,
363 const struct ieee80211_tx_rate *rate)
364{
365 s8 max_txpwr;
366
367 if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
368 u8 mcs = ieee80211_rate_get_vht_mcs(rate);
369
370 if (mcs == 8 || mcs == 9) {
371 max_txpwr = dev->rate_power.vht[8];
372 } else {
373 u8 nss, idx;
374
375 nss = ieee80211_rate_get_vht_nss(rate);
376 idx = ((nss - 1) << 3) + mcs;
377 max_txpwr = dev->rate_power.ht[idx & 0xf];
378 }
379 } else if (rate->flags & IEEE80211_TX_RC_MCS) {
380 max_txpwr = dev->rate_power.ht[rate->idx & 0xf];
381 } else {
382 enum nl80211_band band = dev->chandef.chan->band;
383
384 if (band == NL80211_BAND_2GHZ) {
385 const struct ieee80211_rate *r;
386 struct wiphy *wiphy = dev->hw->wiphy;
387 struct mt76_rate_power *rp = &dev->rate_power;
388
389 r = &wiphy->bands[band]->bitrates[rate->idx];
390 if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE)
391 max_txpwr = rp->cck[r->hw_value & 0x3];
392 else
393 max_txpwr = rp->ofdm[r->hw_value & 0x7];
394 } else {
395 max_txpwr = dev->rate_power.ofdm[rate->idx & 0x7];
396 }
397 }
398
399 return max_txpwr;
400}
401EXPORT_SYMBOL_GPL(mt76x02_tx_get_max_txpwr_adj);
402
403void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, 361void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw,
404 struct ieee80211_vif *vif, 362 struct ieee80211_vif *vif,
405 struct ieee80211_sta *sta) 363 struct ieee80211_sta *sta)
@@ -448,52 +406,6 @@ void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len)
448} 406}
449EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad); 407EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad);
450 408
451static void mt76x02_remove_dma_hdr(struct sk_buff *skb)
452{
453 int hdr_len;
454
455 skb_pull(skb, sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN);
456 hdr_len = ieee80211_get_hdrlen_from_skb(skb);
457 if (hdr_len % 4)
458 mt76x02_remove_hdr_pad(skb, 2);
459}
460
461void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb)
462{
463 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
464
465 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
466 ieee80211_free_txskb(dev->hw, skb);
467 } else {
468 ieee80211_tx_info_clear_status(info);
469 info->status.rates[0].idx = -1;
470 info->flags |= IEEE80211_TX_STAT_ACK;
471 ieee80211_tx_status(dev->hw, skb);
472 }
473}
474EXPORT_SYMBOL_GPL(mt76x02_tx_complete);
475
476void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
477 struct mt76_queue_entry *e, bool flush)
478{
479 mt76x02_remove_dma_hdr(e->skb);
480 mt76x02_tx_complete(mdev, e->skb);
481}
482EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
483
484bool mt76x02_tx_status_data(struct mt76_dev *dev, u8 *update)
485{
486 struct mt76x02_tx_status stat;
487
488 if (!mt76x02_mac_load_tx_status(dev, &stat))
489 return false;
490
491 mt76x02_send_tx_status(dev, &stat, update);
492
493 return true;
494}
495EXPORT_SYMBOL_GPL(mt76x02_tx_status_data);
496
497const u16 mt76x02_beacon_offsets[16] = { 409const u16 mt76x02_beacon_offsets[16] = {
498 /* 1024 byte per beacon */ 410 /* 1024 byte per beacon */
499 0xc000, 411 0xc000,
@@ -532,56 +444,4 @@ void mt76x02_set_beacon_offsets(struct mt76_dev *dev)
532} 444}
533EXPORT_SYMBOL_GPL(mt76x02_set_beacon_offsets); 445EXPORT_SYMBOL_GPL(mt76x02_set_beacon_offsets);
534 446
535void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
536 struct sk_buff *skb)
537{
538 struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
539 void *rxwi = skb->data;
540
541 if (q == MT_RXQ_MCU) {
542 /* this is used just by mmio code */
543 skb_queue_tail(&mdev->mmio.mcu.res_q, skb);
544 wake_up(&mdev->mmio.mcu.wait);
545 return;
546 }
547
548 skb_pull(skb, sizeof(struct mt76x02_rxwi));
549 if (mt76x02_mac_process_rx(dev, skb, rxwi)) {
550 dev_kfree_skb(skb);
551 return;
552 }
553
554 mt76_rx(mdev, q, skb);
555}
556EXPORT_SYMBOL_GPL(mt76x02_queue_rx_skb);
557
558void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
559 struct sk_buff *skb)
560{
561 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
562 struct mt76x02_dev *dev = hw->priv;
563 struct ieee80211_vif *vif = info->control.vif;
564 struct mt76_wcid *wcid = &dev->mt76.global_wcid;
565
566 if (control->sta) {
567 struct mt76x02_sta *msta;
568
569 msta = (struct mt76x02_sta *)control->sta->drv_priv;
570 wcid = &msta->wcid;
571 /* sw encrypted frames */
572 if (!info->control.hw_key && wcid->hw_key_idx != 0xff)
573 control->sta = NULL;
574 }
575
576 if (vif && !control->sta) {
577 struct mt76x02_vif *mvif;
578
579 mvif = (struct mt76x02_vif *)vif->drv_priv;
580 wcid = &mvif->group_wcid;
581 }
582
583 mt76_tx(&dev->mt76, control->sta, wcid, skb);
584}
585EXPORT_SYMBOL_GPL(mt76x02_tx);
586
587MODULE_LICENSE("Dual BSD/GPL"); 447MODULE_LICENSE("Dual BSD/GPL");