Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7925/init.c
106175 views
1
// SPDX-License-Identifier: BSD-3-Clause-Clear
2
/* Copyright (C) 2023 MediaTek Inc. */
3
4
#include <linux/etherdevice.h>
5
#include <linux/hwmon.h>
6
#include <linux/hwmon-sysfs.h>
7
#include <linux/thermal.h>
8
#include <linux/firmware.h>
9
#include "mt7925.h"
10
#include "regd.h"
11
#include "mac.h"
12
#include "mcu.h"
13
14
#if defined(CONFIG_HWMON)
15
static ssize_t mt7925_thermal_temp_show(struct device *dev,
16
struct device_attribute *attr,
17
char *buf)
18
{
19
switch (to_sensor_dev_attr(attr)->index) {
20
case 0: {
21
struct mt792x_phy *phy = dev_get_drvdata(dev);
22
struct mt792x_dev *mdev = phy->dev;
23
int temperature;
24
25
mt792x_mutex_acquire(mdev);
26
temperature = mt7925_mcu_get_temperature(phy);
27
mt792x_mutex_release(mdev);
28
29
if (temperature < 0)
30
return temperature;
31
/* display in millidegree Celsius */
32
return sprintf(buf, "%u\n", temperature * 1000);
33
}
34
default:
35
return -EINVAL;
36
}
37
}
38
static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7925_thermal_temp, 0);
39
40
static struct attribute *mt7925_hwmon_attrs[] = {
41
&sensor_dev_attr_temp1_input.dev_attr.attr,
42
NULL,
43
};
44
ATTRIBUTE_GROUPS(mt7925_hwmon);
45
46
static int mt7925_thermal_init(struct mt792x_phy *phy)
47
{
48
struct wiphy *wiphy = phy->mt76->hw->wiphy;
49
struct device *hwmon;
50
const char *name;
51
52
if (!IS_REACHABLE(CONFIG_HWMON))
53
return 0;
54
55
name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7925_%s",
56
wiphy_name(wiphy));
57
if (!name)
58
return -ENOMEM;
59
60
hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,
61
mt7925_hwmon_groups);
62
return PTR_ERR_OR_ZERO(hwmon);
63
}
64
#endif
65
66
static void mt7925_mac_init_basic_rates(struct mt792x_dev *dev)
67
{
68
int i;
69
70
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
71
u16 rate = mt76_rates[i].hw_value;
72
u16 idx = MT792x_BASIC_RATES_TBL + i;
73
74
rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |
75
FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));
76
mt7925_mac_set_fixed_rate_table(dev, idx, rate);
77
}
78
}
79
80
int mt7925_mac_init(struct mt792x_dev *dev)
81
{
82
int i;
83
84
mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, 1536);
85
/* enable hardware de-agg */
86
mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);
87
88
for (i = 0; i < MT792x_WTBL_SIZE; i++)
89
mt7925_mac_wtbl_update(dev, i,
90
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
91
for (i = 0; i < 2; i++)
92
mt792x_mac_init_band(dev, i);
93
94
mt7925_mac_init_basic_rates(dev);
95
96
return 0;
97
}
98
EXPORT_SYMBOL_GPL(mt7925_mac_init);
99
100
static int __mt7925_init_hardware(struct mt792x_dev *dev)
101
{
102
int ret;
103
104
ret = mt792x_mcu_init(dev);
105
if (ret)
106
goto out;
107
108
ret = mt76_eeprom_override(&dev->mphy);
109
if (ret)
110
goto out;
111
112
ret = mt7925_mcu_set_eeprom(dev);
113
if (ret)
114
goto out;
115
116
ret = mt7925_mac_init(dev);
117
if (ret)
118
goto out;
119
120
out:
121
return ret;
122
}
123
124
static int mt7925_init_hardware(struct mt792x_dev *dev)
125
{
126
int ret, i;
127
128
set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
129
130
for (i = 0; i < MT792x_MCU_INIT_RETRY_COUNT; i++) {
131
ret = __mt7925_init_hardware(dev);
132
if (!ret)
133
break;
134
135
mt792x_init_reset(dev);
136
}
137
138
if (i == MT792x_MCU_INIT_RETRY_COUNT) {
139
dev_err(dev->mt76.dev, "hardware init failed\n");
140
return ret;
141
}
142
143
return 0;
144
}
145
146
static void mt7925_init_work(struct work_struct *work)
147
{
148
struct mt792x_dev *dev = container_of(work, struct mt792x_dev,
149
init_work);
150
int ret;
151
152
ret = mt7925_init_hardware(dev);
153
if (ret)
154
return;
155
156
mt76_set_stream_caps(&dev->mphy, true);
157
mt7925_set_stream_he_eht_caps(&dev->phy);
158
mt792x_config_mac_addr_list(dev);
159
160
ret = mt7925_init_mlo_caps(&dev->phy);
161
if (ret) {
162
dev_err(dev->mt76.dev, "MLO init failed\n");
163
return;
164
}
165
166
ret = mt76_register_device(&dev->mt76, true, mt76_rates,
167
ARRAY_SIZE(mt76_rates));
168
if (ret) {
169
dev_err(dev->mt76.dev, "register device failed\n");
170
return;
171
}
172
173
#if !defined(__FreeBSD__) || defined(CONFIG_MT7925_DEBUGFS)
174
ret = mt7925_init_debugfs(dev);
175
if (ret) {
176
dev_err(dev->mt76.dev, "register debugfs failed\n");
177
return;
178
}
179
#endif
180
181
#if defined(CONFIG_HWMON)
182
ret = mt7925_thermal_init(&dev->phy);
183
if (ret) {
184
dev_err(dev->mt76.dev, "thermal init failed\n");
185
return;
186
}
187
#endif
188
189
ret = mt7925_mcu_set_thermal_protect(dev);
190
if (ret) {
191
dev_err(dev->mt76.dev, "thermal protection enable failed\n");
192
return;
193
}
194
195
/* we support chip reset now */
196
dev->hw_init_done = true;
197
198
mt7925_mcu_set_deep_sleep(dev, dev->pm.ds_enable);
199
}
200
201
int mt7925_register_device(struct mt792x_dev *dev)
202
{
203
struct ieee80211_hw *hw = mt76_hw(dev);
204
int ret;
205
206
dev->phy.dev = dev;
207
dev->phy.mt76 = &dev->mt76.phy;
208
dev->mt76.phy.priv = &dev->phy;
209
dev->mt76.tx_worker.fn = mt792x_tx_worker;
210
211
INIT_DELAYED_WORK(&dev->pm.ps_work, mt792x_pm_power_save_work);
212
INIT_DELAYED_WORK(&dev->mlo_pm_work, mt7925_mlo_pm_work);
213
INIT_WORK(&dev->pm.wake_work, mt792x_pm_wake_work);
214
spin_lock_init(&dev->pm.wake.lock);
215
mutex_init(&dev->pm.mutex);
216
init_waitqueue_head(&dev->pm.wait);
217
init_waitqueue_head(&dev->wait);
218
spin_lock_init(&dev->pm.txq_lock);
219
INIT_DELAYED_WORK(&dev->mphy.mac_work, mt792x_mac_work);
220
INIT_DELAYED_WORK(&dev->phy.scan_work, mt7925_scan_work);
221
INIT_DELAYED_WORK(&dev->coredump.work, mt7925_coredump_work);
222
#if IS_ENABLED(CONFIG_IPV6)
223
INIT_WORK(&dev->ipv6_ns_work, mt7925_set_ipv6_ns_work);
224
skb_queue_head_init(&dev->ipv6_ns_list);
225
#endif
226
skb_queue_head_init(&dev->phy.scan_event_list);
227
skb_queue_head_init(&dev->coredump.msg_list);
228
229
INIT_WORK(&dev->reset_work, mt7925_mac_reset_work);
230
INIT_WORK(&dev->init_work, mt7925_init_work);
231
232
INIT_WORK(&dev->phy.roc_work, mt7925_roc_work);
233
timer_setup(&dev->phy.roc_timer, mt792x_roc_timer, 0);
234
init_waitqueue_head(&dev->phy.roc_wait);
235
236
dev->pm.idle_timeout = MT792x_PM_TIMEOUT;
237
dev->pm.stats.last_wake_event = jiffies;
238
dev->pm.stats.last_doze_event = jiffies;
239
if (!mt76_is_usb(&dev->mt76)) {
240
dev->pm.enable_user = true;
241
dev->pm.enable = true;
242
dev->pm.ds_enable_user = true;
243
dev->pm.ds_enable = true;
244
}
245
246
if (!mt76_is_mmio(&dev->mt76))
247
hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;
248
249
mt792x_init_acpi_sar(dev);
250
251
ret = mt792x_init_wcid(dev);
252
if (ret)
253
return ret;
254
255
ret = mt792x_init_wiphy(hw);
256
if (ret)
257
return ret;
258
259
hw->wiphy->reg_notifier = mt7925_regd_notifier;
260
dev->mphy.sband_2g.sband.ht_cap.cap |=
261
IEEE80211_HT_CAP_LDPC_CODING |
262
IEEE80211_HT_CAP_MAX_AMSDU;
263
dev->mphy.sband_2g.sband.ht_cap.ampdu_density =
264
IEEE80211_HT_MPDU_DENSITY_2;
265
dev->mphy.sband_5g.sband.ht_cap.cap |=
266
IEEE80211_HT_CAP_LDPC_CODING |
267
IEEE80211_HT_CAP_MAX_AMSDU;
268
dev->mphy.sband_2g.sband.ht_cap.ampdu_density =
269
IEEE80211_HT_MPDU_DENSITY_1;
270
dev->mphy.sband_5g.sband.vht_cap.cap |=
271
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
272
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
273
IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
274
IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
275
(3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
276
dev->mphy.sband_5g.sband.vht_cap.cap |=
277
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
278
IEEE80211_VHT_CAP_SHORT_GI_160;
279
280
dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;
281
dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;
282
283
queue_work(system_percpu_wq, &dev->init_work);
284
285
return 0;
286
}
287
EXPORT_SYMBOL_GPL(mt7925_register_device);
288
289