summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76/mt76_connac.h
blob: e7f01c2978a28d0db4c1088ebe44a6a4a95c3598 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* SPDX-License-Identifier: ISC */
/* Copyright (C) 2020 MediaTek Inc. */

#ifndef __MT76_CONNAC_H
#define __MT76_CONNAC_H

#include "mt76.h"

#define MT76_CONNAC_SCAN_IE_LEN			600
#define MT76_CONNAC_MAX_NUM_SCHED_SCAN_INTERVAL	 10
#define MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL U16_MAX
#define MT76_CONNAC_MAX_SCHED_SCAN_SSID		10
#define MT76_CONNAC_MAX_SCAN_MATCH		16

#define MT76_CONNAC_COREDUMP_TIMEOUT		(HZ / 20)
#define MT76_CONNAC_COREDUMP_SZ			(1300 * 1024)

enum {
	CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20,
	CMD_CBW_40MHZ = IEEE80211_STA_RX_BW_40,
	CMD_CBW_80MHZ = IEEE80211_STA_RX_BW_80,
	CMD_CBW_160MHZ = IEEE80211_STA_RX_BW_160,
	CMD_CBW_10MHZ,
	CMD_CBW_5MHZ,
	CMD_CBW_8080MHZ,

	CMD_HE_MCS_BW80 = 0,
	CMD_HE_MCS_BW160,
	CMD_HE_MCS_BW8080,
	CMD_HE_MCS_BW_NUM
};

enum {
	HW_BSSID_0 = 0x0,
	HW_BSSID_1,
	HW_BSSID_2,
	HW_BSSID_3,
	HW_BSSID_MAX = HW_BSSID_3,
	EXT_BSSID_START = 0x10,
	EXT_BSSID_1,
	EXT_BSSID_15 = 0x1f,
	EXT_BSSID_MAX = EXT_BSSID_15,
	REPEATER_BSSID_START = 0x20,
	REPEATER_BSSID_MAX = 0x3f,
};

struct mt76_connac_pm {
	bool enable;
	bool ds_enable;
	bool suspended;

	spinlock_t txq_lock;
	struct {
		struct mt76_wcid *wcid;
		struct sk_buff *skb;
	} tx_q[IEEE80211_NUM_ACS];

	struct work_struct wake_work;
	wait_queue_head_t wait;

	struct {
		spinlock_t lock;
		u32 count;
	} wake;
	struct mutex mutex;

	struct delayed_work ps_work;
	unsigned long last_activity;
	unsigned long idle_timeout;

	struct {
		unsigned long last_wake_event;
		unsigned long awake_time;
		unsigned long last_doze_event;
		unsigned long doze_time;
		unsigned int lp_wake;
	} stats;
};

struct mt76_connac_coredump {
	struct sk_buff_head msg_list;
	struct delayed_work work;
	unsigned long last_activity;
};

extern const struct wiphy_wowlan_support mt76_connac_wowlan_support;

static inline bool is_mt7922(struct mt76_dev *dev)
{
	return mt76_chip(dev) == 0x7922;
}

static inline bool is_mt7921(struct mt76_dev *dev)
{
	return mt76_chip(dev) == 0x7961 || is_mt7922(dev);
}

static inline bool is_mt7663(struct mt76_dev *dev)
{
	return mt76_chip(dev) == 0x7663;
}

int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm);
void mt76_connac_power_save_sched(struct mt76_phy *phy,
				  struct mt76_connac_pm *pm);
void mt76_connac_free_pending_tx_skbs(struct mt76_connac_pm *pm,
				      struct mt76_wcid *wcid);

static inline bool
mt76_connac_pm_ref(struct mt76_phy *phy, struct mt76_connac_pm *pm)
{
	bool ret = false;

	spin_lock_bh(&pm->wake.lock);
	if (test_bit(MT76_STATE_PM, &phy->state))
		goto out;

	pm->wake.count++;
	ret = true;
out:
	spin_unlock_bh(&pm->wake.lock);

	return ret;
}

static inline void
mt76_connac_pm_unref(struct mt76_phy *phy, struct mt76_connac_pm *pm)
{
	spin_lock_bh(&pm->wake.lock);

	pm->last_activity = jiffies;
	if (--pm->wake.count == 0 &&
	    test_bit(MT76_STATE_MCU_RUNNING, &phy->state))
		mt76_connac_power_save_sched(phy, pm);

	spin_unlock_bh(&pm->wake.lock);
}

static inline bool
mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm)
{
	struct mt76_dev *dev = phy->dev;
	bool ret;

	if (dev->token_count)
		return true;

	spin_lock_bh(&pm->wake.lock);
	ret = pm->wake.count || test_and_set_bit(MT76_STATE_PM, &phy->state);
	spin_unlock_bh(&pm->wake.lock);

	return ret;
}

static inline void
mt76_connac_mutex_acquire(struct mt76_dev *dev, struct mt76_connac_pm *pm)
	__acquires(&dev->mutex)
{
	mutex_lock(&dev->mutex);
	mt76_connac_pm_wake(&dev->phy, pm);
}

static inline void
mt76_connac_mutex_release(struct mt76_dev *dev, struct mt76_connac_pm *pm)
	__releases(&dev->mutex)
{
	mt76_connac_power_save_sched(&dev->phy, pm);
	mutex_unlock(&dev->mutex);
}

void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw,
			      struct mt76_connac_pm *pm,
			      struct mt76_wcid *wcid,
			      struct sk_buff *skb);
void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,
				 struct mt76_connac_pm *pm);

#endif /* __MT76_CONNAC_H */