diff options
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x2.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x2_init.c | 238 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c | 259 |
4 files changed, 267 insertions, 239 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index bedb671200ea..8342b4d38220 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile | |||
@@ -8,7 +8,8 @@ mt76-y := \ | |||
8 | CFLAGS_trace.o := -I$(src) | 8 | CFLAGS_trace.o := -I$(src) |
9 | 9 | ||
10 | mt76x2-common-y := \ | 10 | mt76x2-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 | 13 | ||
13 | mt76x2e-y := \ | 14 | mt76x2e-y := \ |
14 | 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 6c5dd106057d..556a2961860b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h | |||
@@ -218,6 +218,8 @@ static inline bool wait_for_wpdma(struct mt76x2_dev *dev) | |||
218 | 218 | ||
219 | extern const struct ieee80211_ops mt76x2_ops; | 219 | extern const struct ieee80211_ops mt76x2_ops; |
220 | 220 | ||
221 | extern struct ieee80211_rate mt76x2_rates[12]; | ||
222 | |||
221 | struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev); | 223 | struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev); |
222 | int mt76x2_register_device(struct mt76x2_dev *dev); | 224 | int mt76x2_register_device(struct mt76x2_dev *dev); |
223 | void mt76x2_init_debugfs(struct mt76x2_dev *dev); | 225 | void mt76x2_init_debugfs(struct mt76x2_dev *dev); |
@@ -286,5 +288,9 @@ bool mt76x2_mac_load_tx_status(struct mt76x2_dev *dev, | |||
286 | struct mt76x2_tx_status *stat); | 288 | struct mt76x2_tx_status *stat); |
287 | void mt76x2_send_tx_status(struct mt76x2_dev *dev, | 289 | void mt76x2_send_tx_status(struct mt76x2_dev *dev, |
288 | struct mt76x2_tx_status *stat, u8 *update); | 290 | struct mt76x2_tx_status *stat, u8 *update); |
291 | void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable); | ||
292 | void mt76x2_init_txpower(struct mt76x2_dev *dev, | ||
293 | struct ieee80211_supported_band *sband); | ||
294 | void mt76_write_mac_initvals(struct mt76x2_dev *dev); | ||
289 | 295 | ||
290 | #endif | 296 | #endif |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index 309e55cf347c..b814391f79ac 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c | |||
@@ -19,11 +19,6 @@ | |||
19 | #include "mt76x2_eeprom.h" | 19 | #include "mt76x2_eeprom.h" |
20 | #include "mt76x2_mcu.h" | 20 | #include "mt76x2_mcu.h" |
21 | 21 | ||
22 | struct mt76x2_reg_pair { | ||
23 | u32 reg; | ||
24 | u32 value; | ||
25 | }; | ||
26 | |||
27 | static void | 22 | static void |
28 | mt76x2_mac_pbf_init(struct mt76x2_dev *dev) | 23 | mt76x2_mac_pbf_init(struct mt76x2_dev *dev) |
29 | { | 24 | { |
@@ -43,113 +38,6 @@ mt76x2_mac_pbf_init(struct mt76x2_dev *dev) | |||
43 | } | 38 | } |
44 | 39 | ||
45 | static void | 40 | static void |
46 | mt76x2_write_reg_pairs(struct mt76x2_dev *dev, | ||
47 | const struct mt76x2_reg_pair *data, int len) | ||
48 | { | ||
49 | while (len > 0) { | ||
50 | mt76_wr(dev, data->reg, data->value); | ||
51 | len--; | ||
52 | data++; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | static void | ||
57 | mt76_write_mac_initvals(struct mt76x2_dev *dev) | ||
58 | { | ||
59 | #define DEFAULT_PROT_CFG_CCK \ | ||
60 | (FIELD_PREP(MT_PROT_CFG_RATE, 0x3) | \ | ||
61 | FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ | ||
62 | FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) | \ | ||
63 | MT_PROT_CFG_RTS_THRESH) | ||
64 | |||
65 | #define DEFAULT_PROT_CFG_OFDM \ | ||
66 | (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) | \ | ||
67 | FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ | ||
68 | FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) | \ | ||
69 | MT_PROT_CFG_RTS_THRESH) | ||
70 | |||
71 | #define DEFAULT_PROT_CFG_20 \ | ||
72 | (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) | \ | ||
73 | FIELD_PREP(MT_PROT_CFG_CTRL, 1) | \ | ||
74 | FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ | ||
75 | FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x17)) | ||
76 | |||
77 | #define DEFAULT_PROT_CFG_40 \ | ||
78 | (FIELD_PREP(MT_PROT_CFG_RATE, 0x2084) | \ | ||
79 | FIELD_PREP(MT_PROT_CFG_CTRL, 1) | \ | ||
80 | FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ | ||
81 | FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f)) | ||
82 | |||
83 | static const struct mt76x2_reg_pair vals[] = { | ||
84 | /* Copied from MediaTek reference source */ | ||
85 | { MT_PBF_SYS_CTRL, 0x00080c00 }, | ||
86 | { MT_PBF_CFG, 0x1efebcff }, | ||
87 | { MT_FCE_PSE_CTRL, 0x00000001 }, | ||
88 | { MT_MAC_SYS_CTRL, 0x0000000c }, | ||
89 | { MT_MAX_LEN_CFG, 0x003e3f00 }, | ||
90 | { MT_AMPDU_MAX_LEN_20M1S, 0xaaa99887 }, | ||
91 | { MT_AMPDU_MAX_LEN_20M2S, 0x000000aa }, | ||
92 | { MT_XIFS_TIME_CFG, 0x33a40d0a }, | ||
93 | { MT_BKOFF_SLOT_CFG, 0x00000209 }, | ||
94 | { MT_TBTT_SYNC_CFG, 0x00422010 }, | ||
95 | { MT_PWR_PIN_CFG, 0x00000000 }, | ||
96 | { 0x1238, 0x001700c8 }, | ||
97 | { MT_TX_SW_CFG0, 0x00101001 }, | ||
98 | { MT_TX_SW_CFG1, 0x00010000 }, | ||
99 | { MT_TX_SW_CFG2, 0x00000000 }, | ||
100 | { MT_TXOP_CTRL_CFG, 0x0400583f }, | ||
101 | { MT_TX_RTS_CFG, 0x00100020 }, | ||
102 | { MT_TX_TIMEOUT_CFG, 0x000a2290 }, | ||
103 | { MT_TX_RETRY_CFG, 0x47f01f0f }, | ||
104 | { MT_EXP_ACK_TIME, 0x002c00dc }, | ||
105 | { MT_TX_PROT_CFG6, 0xe3f42004 }, | ||
106 | { MT_TX_PROT_CFG7, 0xe3f42084 }, | ||
107 | { MT_TX_PROT_CFG8, 0xe3f42104 }, | ||
108 | { MT_PIFS_TX_CFG, 0x00060fff }, | ||
109 | { MT_RX_FILTR_CFG, 0x00015f97 }, | ||
110 | { MT_LEGACY_BASIC_RATE, 0x0000017f }, | ||
111 | { MT_HT_BASIC_RATE, 0x00004003 }, | ||
112 | { MT_PN_PAD_MODE, 0x00000003 }, | ||
113 | { MT_TXOP_HLDR_ET, 0x00000002 }, | ||
114 | { 0xa44, 0x00000000 }, | ||
115 | { MT_HEADER_TRANS_CTRL_REG, 0x00000000 }, | ||
116 | { MT_TSO_CTRL, 0x00000000 }, | ||
117 | { MT_AUX_CLK_CFG, 0x00000000 }, | ||
118 | { MT_DACCLK_EN_DLY_CFG, 0x00000000 }, | ||
119 | { MT_TX_ALC_CFG_4, 0x00000000 }, | ||
120 | { MT_TX_ALC_VGA3, 0x00000000 }, | ||
121 | { MT_TX_PWR_CFG_0, 0x3a3a3a3a }, | ||
122 | { MT_TX_PWR_CFG_1, 0x3a3a3a3a }, | ||
123 | { MT_TX_PWR_CFG_2, 0x3a3a3a3a }, | ||
124 | { MT_TX_PWR_CFG_3, 0x3a3a3a3a }, | ||
125 | { MT_TX_PWR_CFG_4, 0x3a3a3a3a }, | ||
126 | { MT_TX_PWR_CFG_7, 0x3a3a3a3a }, | ||
127 | { MT_TX_PWR_CFG_8, 0x0000003a }, | ||
128 | { MT_TX_PWR_CFG_9, 0x0000003a }, | ||
129 | { MT_EFUSE_CTRL, 0x0000d000 }, | ||
130 | { MT_PAUSE_ENABLE_CONTROL1, 0x0000000a }, | ||
131 | { MT_FCE_WLAN_FLOW_CONTROL1, 0x60401c18 }, | ||
132 | { MT_WPDMA_DELAY_INT_CFG, 0x94ff0000 }, | ||
133 | { MT_TX_SW_CFG3, 0x00000004 }, | ||
134 | { MT_HT_FBK_TO_LEGACY, 0x00001818 }, | ||
135 | { MT_VHT_HT_FBK_CFG1, 0xedcba980 }, | ||
136 | { MT_PROT_AUTO_TX_CFG, 0x00830083 }, | ||
137 | { MT_HT_CTRL_CFG, 0x000001ff }, | ||
138 | }; | ||
139 | struct mt76x2_reg_pair prot_vals[] = { | ||
140 | { MT_CCK_PROT_CFG, DEFAULT_PROT_CFG_CCK }, | ||
141 | { MT_OFDM_PROT_CFG, DEFAULT_PROT_CFG_OFDM }, | ||
142 | { MT_MM20_PROT_CFG, DEFAULT_PROT_CFG_20 }, | ||
143 | { MT_MM40_PROT_CFG, DEFAULT_PROT_CFG_40 }, | ||
144 | { MT_GF20_PROT_CFG, DEFAULT_PROT_CFG_20 }, | ||
145 | { MT_GF40_PROT_CFG, DEFAULT_PROT_CFG_40 }, | ||
146 | }; | ||
147 | |||
148 | mt76x2_write_reg_pairs(dev, vals, ARRAY_SIZE(vals)); | ||
149 | mt76x2_write_reg_pairs(dev, prot_vals, ARRAY_SIZE(prot_vals)); | ||
150 | } | ||
151 | |||
152 | static void | ||
153 | mt76x2_fixup_xtal(struct mt76x2_dev *dev) | 41 | mt76x2_fixup_xtal(struct mt76x2_dev *dev) |
154 | { | 42 | { |
155 | u16 eep_val; | 43 | u16 eep_val; |
@@ -441,45 +329,6 @@ void mt76x2_set_tx_ackto(struct mt76x2_dev *dev) | |||
441 | MT_TX_TIMEOUT_CFG_ACKTO, ackto); | 329 | MT_TX_TIMEOUT_CFG_ACKTO, ackto); |
442 | } | 330 | } |
443 | 331 | ||
444 | static void | ||
445 | mt76x2_set_wlan_state(struct mt76x2_dev *dev, bool enable) | ||
446 | { | ||
447 | u32 val = mt76_rr(dev, MT_WLAN_FUN_CTRL); | ||
448 | |||
449 | if (enable) | ||
450 | val |= (MT_WLAN_FUN_CTRL_WLAN_EN | | ||
451 | MT_WLAN_FUN_CTRL_WLAN_CLK_EN); | ||
452 | else | ||
453 | val &= ~(MT_WLAN_FUN_CTRL_WLAN_EN | | ||
454 | MT_WLAN_FUN_CTRL_WLAN_CLK_EN); | ||
455 | |||
456 | mt76_wr(dev, MT_WLAN_FUN_CTRL, val); | ||
457 | udelay(20); | ||
458 | } | ||
459 | |||
460 | static void | ||
461 | mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable) | ||
462 | { | ||
463 | u32 val; | ||
464 | |||
465 | val = mt76_rr(dev, MT_WLAN_FUN_CTRL); | ||
466 | |||
467 | val &= ~MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL; | ||
468 | |||
469 | if (val & MT_WLAN_FUN_CTRL_WLAN_EN) { | ||
470 | val |= MT_WLAN_FUN_CTRL_WLAN_RESET_RF; | ||
471 | mt76_wr(dev, MT_WLAN_FUN_CTRL, val); | ||
472 | udelay(20); | ||
473 | |||
474 | val &= ~MT_WLAN_FUN_CTRL_WLAN_RESET_RF; | ||
475 | } | ||
476 | |||
477 | mt76_wr(dev, MT_WLAN_FUN_CTRL, val); | ||
478 | udelay(20); | ||
479 | |||
480 | mt76x2_set_wlan_state(dev, enable); | ||
481 | } | ||
482 | |||
483 | int mt76x2_init_hardware(struct mt76x2_dev *dev) | 332 | int mt76x2_init_hardware(struct mt76x2_dev *dev) |
484 | { | 333 | { |
485 | static const u16 beacon_offsets[16] = { | 334 | static const u16 beacon_offsets[16] = { |
@@ -601,34 +450,6 @@ static void mt76x2_regd_notifier(struct wiphy *wiphy, | |||
601 | mt76x2_dfs_set_domain(dev, request->dfs_region); | 450 | mt76x2_dfs_set_domain(dev, request->dfs_region); |
602 | } | 451 | } |
603 | 452 | ||
604 | #define CCK_RATE(_idx, _rate) { \ | ||
605 | .bitrate = _rate, \ | ||
606 | .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ | ||
607 | .hw_value = (MT_PHY_TYPE_CCK << 8) | _idx, \ | ||
608 | .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx), \ | ||
609 | } | ||
610 | |||
611 | #define OFDM_RATE(_idx, _rate) { \ | ||
612 | .bitrate = _rate, \ | ||
613 | .hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx, \ | ||
614 | .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx, \ | ||
615 | } | ||
616 | |||
617 | static struct ieee80211_rate mt76x2_rates[] = { | ||
618 | CCK_RATE(0, 10), | ||
619 | CCK_RATE(1, 20), | ||
620 | CCK_RATE(2, 55), | ||
621 | CCK_RATE(3, 110), | ||
622 | OFDM_RATE(0, 60), | ||
623 | OFDM_RATE(1, 90), | ||
624 | OFDM_RATE(2, 120), | ||
625 | OFDM_RATE(3, 180), | ||
626 | OFDM_RATE(4, 240), | ||
627 | OFDM_RATE(5, 360), | ||
628 | OFDM_RATE(6, 480), | ||
629 | OFDM_RATE(7, 540), | ||
630 | }; | ||
631 | |||
632 | static const struct ieee80211_iface_limit if_limits[] = { | 453 | static const struct ieee80211_iface_limit if_limits[] = { |
633 | { | 454 | { |
634 | .max = 1, | 455 | .max = 1, |
@@ -705,65 +526,6 @@ static void mt76x2_led_set_brightness(struct led_classdev *led_cdev, | |||
705 | mt76x2_led_set_config(mt76, 0xff, 0); | 526 | mt76x2_led_set_config(mt76, 0xff, 0); |
706 | } | 527 | } |
707 | 528 | ||
708 | static void | ||
709 | mt76x2_init_txpower(struct mt76x2_dev *dev, | ||
710 | struct ieee80211_supported_band *sband) | ||
711 | { | ||
712 | struct ieee80211_channel *chan; | ||
713 | struct mt76x2_tx_power_info txp; | ||
714 | struct mt76_rate_power t = {}; | ||
715 | int target_power; | ||
716 | int i; | ||
717 | |||
718 | for (i = 0; i < sband->n_channels; i++) { | ||
719 | chan = &sband->channels[i]; | ||
720 | |||
721 | mt76x2_get_power_info(dev, &txp, chan); | ||
722 | |||
723 | target_power = max_t(int, (txp.chain[0].target_power + | ||
724 | txp.chain[0].delta), | ||
725 | (txp.chain[1].target_power + | ||
726 | txp.chain[1].delta)); | ||
727 | |||
728 | mt76x2_get_rate_power(dev, &t, chan); | ||
729 | |||
730 | chan->max_power = mt76x2_get_max_rate_power(&t) + | ||
731 | target_power; | ||
732 | chan->max_power /= 2; | ||
733 | |||
734 | /* convert to combined output power on 2x2 devices */ | ||
735 | chan->max_power += 3; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | void mt76x2_init_device(struct mt76x2_dev *dev) | ||
740 | { | ||
741 | struct ieee80211_hw *hw = mt76_hw(dev); | ||
742 | |||
743 | hw->queues = 4; | ||
744 | hw->max_rates = 1; | ||
745 | hw->max_report_rates = 7; | ||
746 | hw->max_rate_tries = 1; | ||
747 | hw->extra_tx_headroom = 2; | ||
748 | |||
749 | hw->sta_data_size = sizeof(struct mt76x2_sta); | ||
750 | hw->vif_data_size = sizeof(struct mt76x2_vif); | ||
751 | |||
752 | ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); | ||
753 | ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); | ||
754 | |||
755 | dev->mt76.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
756 | dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
757 | |||
758 | dev->chainmask = 0x202; | ||
759 | dev->global_wcid.idx = 255; | ||
760 | dev->global_wcid.hw_key_idx = -1; | ||
761 | dev->slottime = 9; | ||
762 | |||
763 | /* init antenna configuration */ | ||
764 | dev->mt76.antenna_mask = 3; | ||
765 | } | ||
766 | |||
767 | int mt76x2_register_device(struct mt76x2_dev *dev) | 529 | int mt76x2_register_device(struct mt76x2_dev *dev) |
768 | { | 530 | { |
769 | struct ieee80211_hw *hw = mt76_hw(dev); | 531 | struct ieee80211_hw *hw = mt76_hw(dev); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c new file mode 100644 index 000000000000..324b2a4b8b67 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c | |||
@@ -0,0 +1,259 @@ | |||
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 | #include "mt76x2_eeprom.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 mt76x2_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(mt76x2_rates); | ||
49 | |||
50 | struct mt76x2_reg_pair { | ||
51 | u32 reg; | ||
52 | u32 value; | ||
53 | }; | ||
54 | |||
55 | static void | ||
56 | mt76x2_set_wlan_state(struct mt76x2_dev *dev, bool enable) | ||
57 | { | ||
58 | u32 val = mt76_rr(dev, MT_WLAN_FUN_CTRL); | ||
59 | |||
60 | if (enable) | ||
61 | val |= (MT_WLAN_FUN_CTRL_WLAN_EN | | ||
62 | MT_WLAN_FUN_CTRL_WLAN_CLK_EN); | ||
63 | else | ||
64 | val &= ~(MT_WLAN_FUN_CTRL_WLAN_EN | | ||
65 | MT_WLAN_FUN_CTRL_WLAN_CLK_EN); | ||
66 | |||
67 | mt76_wr(dev, MT_WLAN_FUN_CTRL, val); | ||
68 | udelay(20); | ||
69 | } | ||
70 | |||
71 | void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable) | ||
72 | { | ||
73 | u32 val; | ||
74 | |||
75 | val = mt76_rr(dev, MT_WLAN_FUN_CTRL); | ||
76 | |||
77 | val &= ~MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL; | ||
78 | |||
79 | if (val & MT_WLAN_FUN_CTRL_WLAN_EN) { | ||
80 | val |= MT_WLAN_FUN_CTRL_WLAN_RESET_RF; | ||
81 | mt76_wr(dev, MT_WLAN_FUN_CTRL, val); | ||
82 | udelay(20); | ||
83 | |||
84 | val &= ~MT_WLAN_FUN_CTRL_WLAN_RESET_RF; | ||
85 | } | ||
86 | |||
87 | mt76_wr(dev, MT_WLAN_FUN_CTRL, val); | ||
88 | udelay(20); | ||
89 | |||
90 | mt76x2_set_wlan_state(dev, enable); | ||
91 | } | ||
92 | EXPORT_SYMBOL_GPL(mt76x2_reset_wlan); | ||
93 | |||
94 | static void | ||
95 | mt76x2_write_reg_pairs(struct mt76x2_dev *dev, | ||
96 | const struct mt76x2_reg_pair *data, int len) | ||
97 | { | ||
98 | while (len > 0) { | ||
99 | mt76_wr(dev, data->reg, data->value); | ||
100 | len--; | ||
101 | data++; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | void mt76_write_mac_initvals(struct mt76x2_dev *dev) | ||
106 | { | ||
107 | #define DEFAULT_PROT_CFG_CCK \ | ||
108 | (FIELD_PREP(MT_PROT_CFG_RATE, 0x3) | \ | ||
109 | FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ | ||
110 | FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) | \ | ||
111 | MT_PROT_CFG_RTS_THRESH) | ||
112 | |||
113 | #define DEFAULT_PROT_CFG_OFDM \ | ||
114 | (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) | \ | ||
115 | FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ | ||
116 | FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) | \ | ||
117 | MT_PROT_CFG_RTS_THRESH) | ||
118 | |||
119 | #define DEFAULT_PROT_CFG_20 \ | ||
120 | (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) | \ | ||
121 | FIELD_PREP(MT_PROT_CFG_CTRL, 1) | \ | ||
122 | FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ | ||
123 | FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x17)) | ||
124 | |||
125 | #define DEFAULT_PROT_CFG_40 \ | ||
126 | (FIELD_PREP(MT_PROT_CFG_RATE, 0x2084) | \ | ||
127 | FIELD_PREP(MT_PROT_CFG_CTRL, 1) | \ | ||
128 | FIELD_PREP(MT_PROT_CFG_NAV, 1) | \ | ||
129 | FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f)) | ||
130 | |||
131 | static const struct mt76x2_reg_pair vals[] = { | ||
132 | /* Copied from MediaTek reference source */ | ||
133 | { MT_PBF_SYS_CTRL, 0x00080c00 }, | ||
134 | { MT_PBF_CFG, 0x1efebcff }, | ||
135 | { MT_FCE_PSE_CTRL, 0x00000001 }, | ||
136 | { MT_MAC_SYS_CTRL, 0x0000000c }, | ||
137 | { MT_MAX_LEN_CFG, 0x003e3f00 }, | ||
138 | { MT_AMPDU_MAX_LEN_20M1S, 0xaaa99887 }, | ||
139 | { MT_AMPDU_MAX_LEN_20M2S, 0x000000aa }, | ||
140 | { MT_XIFS_TIME_CFG, 0x33a40d0a }, | ||
141 | { MT_BKOFF_SLOT_CFG, 0x00000209 }, | ||
142 | { MT_TBTT_SYNC_CFG, 0x00422010 }, | ||
143 | { MT_PWR_PIN_CFG, 0x00000000 }, | ||
144 | { 0x1238, 0x001700c8 }, | ||
145 | { MT_TX_SW_CFG0, 0x00101001 }, | ||
146 | { MT_TX_SW_CFG1, 0x00010000 }, | ||
147 | { MT_TX_SW_CFG2, 0x00000000 }, | ||
148 | { MT_TXOP_CTRL_CFG, 0x0400583f }, | ||
149 | { MT_TX_RTS_CFG, 0x00100020 }, | ||
150 | { MT_TX_TIMEOUT_CFG, 0x000a2290 }, | ||
151 | { MT_TX_RETRY_CFG, 0x47f01f0f }, | ||
152 | { MT_EXP_ACK_TIME, 0x002c00dc }, | ||
153 | { MT_TX_PROT_CFG6, 0xe3f42004 }, | ||
154 | { MT_TX_PROT_CFG7, 0xe3f42084 }, | ||
155 | { MT_TX_PROT_CFG8, 0xe3f42104 }, | ||
156 | { MT_PIFS_TX_CFG, 0x00060fff }, | ||
157 | { MT_RX_FILTR_CFG, 0x00015f97 }, | ||
158 | { MT_LEGACY_BASIC_RATE, 0x0000017f }, | ||
159 | { MT_HT_BASIC_RATE, 0x00004003 }, | ||
160 | { MT_PN_PAD_MODE, 0x00000003 }, | ||
161 | { MT_TXOP_HLDR_ET, 0x00000002 }, | ||
162 | { 0xa44, 0x00000000 }, | ||
163 | { MT_HEADER_TRANS_CTRL_REG, 0x00000000 }, | ||
164 | { MT_TSO_CTRL, 0x00000000 }, | ||
165 | { MT_AUX_CLK_CFG, 0x00000000 }, | ||
166 | { MT_DACCLK_EN_DLY_CFG, 0x00000000 }, | ||
167 | { MT_TX_ALC_CFG_4, 0x00000000 }, | ||
168 | { MT_TX_ALC_VGA3, 0x00000000 }, | ||
169 | { MT_TX_PWR_CFG_0, 0x3a3a3a3a }, | ||
170 | { MT_TX_PWR_CFG_1, 0x3a3a3a3a }, | ||
171 | { MT_TX_PWR_CFG_2, 0x3a3a3a3a }, | ||
172 | { MT_TX_PWR_CFG_3, 0x3a3a3a3a }, | ||
173 | { MT_TX_PWR_CFG_4, 0x3a3a3a3a }, | ||
174 | { MT_TX_PWR_CFG_7, 0x3a3a3a3a }, | ||
175 | { MT_TX_PWR_CFG_8, 0x0000003a }, | ||
176 | { MT_TX_PWR_CFG_9, 0x0000003a }, | ||
177 | { MT_EFUSE_CTRL, 0x0000d000 }, | ||
178 | { MT_PAUSE_ENABLE_CONTROL1, 0x0000000a }, | ||
179 | { MT_FCE_WLAN_FLOW_CONTROL1, 0x60401c18 }, | ||
180 | { MT_WPDMA_DELAY_INT_CFG, 0x94ff0000 }, | ||
181 | { MT_TX_SW_CFG3, 0x00000004 }, | ||
182 | { MT_HT_FBK_TO_LEGACY, 0x00001818 }, | ||
183 | { MT_VHT_HT_FBK_CFG1, 0xedcba980 }, | ||
184 | { MT_PROT_AUTO_TX_CFG, 0x00830083 }, | ||
185 | { MT_HT_CTRL_CFG, 0x000001ff }, | ||
186 | }; | ||
187 | struct mt76x2_reg_pair prot_vals[] = { | ||
188 | { MT_CCK_PROT_CFG, DEFAULT_PROT_CFG_CCK }, | ||
189 | { MT_OFDM_PROT_CFG, DEFAULT_PROT_CFG_OFDM }, | ||
190 | { MT_MM20_PROT_CFG, DEFAULT_PROT_CFG_20 }, | ||
191 | { MT_MM40_PROT_CFG, DEFAULT_PROT_CFG_40 }, | ||
192 | { MT_GF20_PROT_CFG, DEFAULT_PROT_CFG_20 }, | ||
193 | { MT_GF40_PROT_CFG, DEFAULT_PROT_CFG_40 }, | ||
194 | }; | ||
195 | |||
196 | mt76x2_write_reg_pairs(dev, vals, ARRAY_SIZE(vals)); | ||
197 | mt76x2_write_reg_pairs(dev, prot_vals, ARRAY_SIZE(prot_vals)); | ||
198 | } | ||
199 | EXPORT_SYMBOL_GPL(mt76_write_mac_initvals); | ||
200 | |||
201 | void mt76x2_init_device(struct mt76x2_dev *dev) | ||
202 | { | ||
203 | struct ieee80211_hw *hw = mt76_hw(dev); | ||
204 | |||
205 | hw->queues = 4; | ||
206 | hw->max_rates = 1; | ||
207 | hw->max_report_rates = 7; | ||
208 | hw->max_rate_tries = 1; | ||
209 | hw->extra_tx_headroom = 2; | ||
210 | |||
211 | hw->sta_data_size = sizeof(struct mt76x2_sta); | ||
212 | hw->vif_data_size = sizeof(struct mt76x2_vif); | ||
213 | |||
214 | ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); | ||
215 | ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); | ||
216 | |||
217 | dev->mt76.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
218 | dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
219 | |||
220 | dev->chainmask = 0x202; | ||
221 | dev->global_wcid.idx = 255; | ||
222 | dev->global_wcid.hw_key_idx = -1; | ||
223 | dev->slottime = 9; | ||
224 | |||
225 | /* init antenna configuration */ | ||
226 | dev->mt76.antenna_mask = 3; | ||
227 | } | ||
228 | EXPORT_SYMBOL_GPL(mt76x2_init_device); | ||
229 | |||
230 | void mt76x2_init_txpower(struct mt76x2_dev *dev, | ||
231 | struct ieee80211_supported_band *sband) | ||
232 | { | ||
233 | struct ieee80211_channel *chan; | ||
234 | struct mt76x2_tx_power_info txp; | ||
235 | struct mt76_rate_power t = {}; | ||
236 | int target_power; | ||
237 | int i; | ||
238 | |||
239 | for (i = 0; i < sband->n_channels; i++) { | ||
240 | chan = &sband->channels[i]; | ||
241 | |||
242 | mt76x2_get_power_info(dev, &txp, chan); | ||
243 | |||
244 | target_power = max_t(int, (txp.chain[0].target_power + | ||
245 | txp.chain[0].delta), | ||
246 | (txp.chain[1].target_power + | ||
247 | txp.chain[1].delta)); | ||
248 | |||
249 | mt76x2_get_rate_power(dev, &t, chan); | ||
250 | |||
251 | chan->max_power = mt76x2_get_max_rate_power(&t) + | ||
252 | target_power; | ||
253 | chan->max_power /= 2; | ||
254 | |||
255 | /* convert to combined output power on 2x2 devices */ | ||
256 | chan->max_power += 3; | ||
257 | } | ||
258 | } | ||
259 | EXPORT_SYMBOL_GPL(mt76x2_init_txpower); | ||