Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7615/pci_init.c
48525 views
1
// SPDX-License-Identifier: ISC
2
/* Copyright (C) 2019 MediaTek Inc.
3
*
4
* Author: Roy Luo <[email protected]>
5
* Ryder Lee <[email protected]>
6
* Felix Fietkau <[email protected]>
7
* Lorenzo Bianconi <[email protected]>
8
*/
9
10
#include <linux/etherdevice.h>
11
#if defined(__FreeBSD__)
12
#include <linux/delay.h>
13
#endif
14
#include "mt7615.h"
15
#include "mac.h"
16
#include "eeprom.h"
17
18
static void mt7615_pci_init_work(struct work_struct *work)
19
{
20
struct mt7615_dev *dev = container_of(work, struct mt7615_dev,
21
mcu_work);
22
int i, ret;
23
24
ret = mt7615_mcu_init(dev);
25
for (i = 0; (ret == -EAGAIN) && (i < 10); i++) {
26
msleep(200);
27
ret = mt7615_mcu_init(dev);
28
}
29
30
if (ret)
31
return;
32
33
mt7615_init_work(dev);
34
}
35
36
static int mt7615_init_hardware(struct mt7615_dev *dev)
37
{
38
u32 addr = mt7615_reg_map(dev, MT_EFUSE_BASE);
39
int ret, idx;
40
41
mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
42
43
INIT_WORK(&dev->mcu_work, mt7615_pci_init_work);
44
ret = mt7615_eeprom_init(dev, addr);
45
if (ret < 0)
46
return ret;
47
48
if (is_mt7663(&dev->mt76)) {
49
/* Reset RGU */
50
mt76_clear(dev, MT_MCU_CIRQ_IRQ_SEL(4), BIT(1));
51
mt76_set(dev, MT_MCU_CIRQ_IRQ_SEL(4), BIT(1));
52
}
53
54
ret = mt7615_dma_init(dev);
55
if (ret)
56
return ret;
57
58
set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
59
60
/* Beacon and mgmt frames should occupy wcid 0 */
61
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
62
if (idx)
63
return -ENOSPC;
64
65
dev->mt76.global_wcid.idx = idx;
66
dev->mt76.global_wcid.hw_key_idx = -1;
67
rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
68
69
return 0;
70
}
71
72
int mt7615_register_device(struct mt7615_dev *dev)
73
{
74
int ret;
75
76
mt7615_init_device(dev);
77
INIT_WORK(&dev->reset_work, mt7615_mac_reset_work);
78
79
/* init led callbacks */
80
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
81
dev->mphy.leds.cdev.brightness_set = mt7615_led_set_brightness;
82
dev->mphy.leds.cdev.blink_set = mt7615_led_set_blink;
83
}
84
85
ret = mt7622_wmac_init(dev);
86
if (ret)
87
return ret;
88
89
ret = mt7615_init_hardware(dev);
90
if (ret)
91
return ret;
92
93
ret = mt76_register_device(&dev->mt76, true, mt76_rates,
94
ARRAY_SIZE(mt76_rates));
95
if (ret)
96
return ret;
97
98
#if defined(__linux__)
99
ret = mt7615_thermal_init(dev);
100
if (ret)
101
return ret;
102
#endif
103
104
ieee80211_queue_work(mt76_hw(dev), &dev->mcu_work);
105
mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);
106
mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);
107
108
if (dev->dbdc_support) {
109
ret = mt7615_register_ext_phy(dev);
110
if (ret)
111
return ret;
112
}
113
114
#if defined(CONFIG_MT7615_DEBUGFS)
115
return mt7615_init_debugfs(dev);
116
#else
117
return 0;
118
#endif
119
}
120
121
void mt7615_unregister_device(struct mt7615_dev *dev)
122
{
123
bool mcu_running;
124
125
mcu_running = mt7615_wait_for_mcu_init(dev);
126
127
mt7615_unregister_ext_phy(dev);
128
mt76_unregister_device(&dev->mt76);
129
if (mcu_running)
130
mt7615_mcu_exit(dev);
131
132
mt7615_tx_token_put(dev);
133
mt7615_dma_cleanup(dev);
134
tasklet_disable(&dev->mt76.irq_tasklet);
135
136
mt76_free_device(&dev->mt76);
137
}
138
139