File Index
Files and directories
Sign in
FILE

init.c

File preview with syntax highlighting.

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