mt76_connac.h (5483B)
1/* SPDX-License-Identifier: ISC */ 2/* Copyright (C) 2020 MediaTek Inc. */ 3 4#ifndef __MT76_CONNAC_H 5#define __MT76_CONNAC_H 6 7#include "mt76.h" 8 9#define MT76_CONNAC_SCAN_IE_LEN 600 10#define MT76_CONNAC_MAX_NUM_SCHED_SCAN_INTERVAL 10 11#define MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL U16_MAX 12#define MT76_CONNAC_MAX_SCHED_SCAN_SSID 10 13#define MT76_CONNAC_MAX_SCAN_MATCH 16 14 15#define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20) 16#define MT76_CONNAC_COREDUMP_SZ (1300 * 1024) 17 18enum { 19 CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20, 20 CMD_CBW_40MHZ = IEEE80211_STA_RX_BW_40, 21 CMD_CBW_80MHZ = IEEE80211_STA_RX_BW_80, 22 CMD_CBW_160MHZ = IEEE80211_STA_RX_BW_160, 23 CMD_CBW_10MHZ, 24 CMD_CBW_5MHZ, 25 CMD_CBW_8080MHZ, 26 27 CMD_HE_MCS_BW80 = 0, 28 CMD_HE_MCS_BW160, 29 CMD_HE_MCS_BW8080, 30 CMD_HE_MCS_BW_NUM 31}; 32 33enum { 34 HW_BSSID_0 = 0x0, 35 HW_BSSID_1, 36 HW_BSSID_2, 37 HW_BSSID_3, 38 HW_BSSID_MAX = HW_BSSID_3, 39 EXT_BSSID_START = 0x10, 40 EXT_BSSID_1, 41 EXT_BSSID_15 = 0x1f, 42 EXT_BSSID_MAX = EXT_BSSID_15, 43 REPEATER_BSSID_START = 0x20, 44 REPEATER_BSSID_MAX = 0x3f, 45}; 46 47struct mt76_connac_pm { 48 bool enable:1; 49 bool enable_user:1; 50 bool ds_enable:1; 51 bool ds_enable_user:1; 52 bool suspended:1; 53 54 spinlock_t txq_lock; 55 struct { 56 struct mt76_wcid *wcid; 57 struct sk_buff *skb; 58 } tx_q[IEEE80211_NUM_ACS]; 59 60 struct work_struct wake_work; 61 wait_queue_head_t wait; 62 63 struct { 64 spinlock_t lock; 65 u32 count; 66 } wake; 67 struct mutex mutex; 68 69 struct delayed_work ps_work; 70 unsigned long last_activity; 71 unsigned long idle_timeout; 72 73 struct { 74 unsigned long last_wake_event; 75 unsigned long awake_time; 76 unsigned long last_doze_event; 77 unsigned long doze_time; 78 unsigned int lp_wake; 79 } stats; 80}; 81 82struct mt76_connac_coredump { 83 struct sk_buff_head msg_list; 84 struct delayed_work work; 85 unsigned long last_activity; 86}; 87 88struct mt76_connac_sta_key_conf { 89 s8 keyidx; 90 u8 key[16]; 91}; 92 93extern const struct wiphy_wowlan_support mt76_connac_wowlan_support; 94 95static inline bool is_mt7922(struct mt76_dev *dev) 96{ 97 return mt76_chip(dev) == 0x7922; 98} 99 100static inline bool is_mt7921(struct mt76_dev *dev) 101{ 102 return mt76_chip(dev) == 0x7961 || is_mt7922(dev); 103} 104 105static inline bool is_mt7663(struct mt76_dev *dev) 106{ 107 return mt76_chip(dev) == 0x7663; 108} 109 110static inline bool is_mt7915(struct mt76_dev *dev) 111{ 112 return mt76_chip(dev) == 0x7915; 113} 114 115static inline bool is_mt7916(struct mt76_dev *dev) 116{ 117 return mt76_chip(dev) == 0x7906; 118} 119 120static inline bool is_mt7986(struct mt76_dev *dev) 121{ 122 return mt76_chip(dev) == 0x7986; 123} 124 125static inline bool is_mt7622(struct mt76_dev *dev) 126{ 127 if (!IS_ENABLED(CONFIG_MT7622_WMAC)) 128 return false; 129 130 return mt76_chip(dev) == 0x7622; 131} 132 133static inline bool is_mt7615(struct mt76_dev *dev) 134{ 135 return mt76_chip(dev) == 0x7615 || mt76_chip(dev) == 0x7611; 136} 137 138static inline bool is_mt7611(struct mt76_dev *dev) 139{ 140 return mt76_chip(dev) == 0x7611; 141} 142 143static inline bool is_connac_v1(struct mt76_dev *dev) 144{ 145 return is_mt7615(dev) || is_mt7663(dev) || is_mt7622(dev); 146} 147 148static inline u8 mt76_connac_chan_bw(struct cfg80211_chan_def *chandef) 149{ 150 static const u8 width_to_bw[] = { 151 [NL80211_CHAN_WIDTH_40] = CMD_CBW_40MHZ, 152 [NL80211_CHAN_WIDTH_80] = CMD_CBW_80MHZ, 153 [NL80211_CHAN_WIDTH_80P80] = CMD_CBW_8080MHZ, 154 [NL80211_CHAN_WIDTH_160] = CMD_CBW_160MHZ, 155 [NL80211_CHAN_WIDTH_5] = CMD_CBW_5MHZ, 156 [NL80211_CHAN_WIDTH_10] = CMD_CBW_10MHZ, 157 [NL80211_CHAN_WIDTH_20] = CMD_CBW_20MHZ, 158 [NL80211_CHAN_WIDTH_20_NOHT] = CMD_CBW_20MHZ, 159 }; 160 161 if (chandef->width >= ARRAY_SIZE(width_to_bw)) 162 return 0; 163 164 return width_to_bw[chandef->width]; 165} 166 167static inline u8 mt76_connac_lmac_mapping(u8 ac) 168{ 169 /* LMAC uses the reverse order of mac80211 AC indexes */ 170 return 3 - ac; 171} 172 173int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm); 174void mt76_connac_power_save_sched(struct mt76_phy *phy, 175 struct mt76_connac_pm *pm); 176void mt76_connac_free_pending_tx_skbs(struct mt76_connac_pm *pm, 177 struct mt76_wcid *wcid); 178 179static inline bool 180mt76_connac_pm_ref(struct mt76_phy *phy, struct mt76_connac_pm *pm) 181{ 182 bool ret = false; 183 184 spin_lock_bh(&pm->wake.lock); 185 if (test_bit(MT76_STATE_PM, &phy->state)) 186 goto out; 187 188 pm->wake.count++; 189 ret = true; 190out: 191 spin_unlock_bh(&pm->wake.lock); 192 193 return ret; 194} 195 196static inline void 197mt76_connac_pm_unref(struct mt76_phy *phy, struct mt76_connac_pm *pm) 198{ 199 spin_lock_bh(&pm->wake.lock); 200 201 pm->last_activity = jiffies; 202 if (--pm->wake.count == 0 && 203 test_bit(MT76_STATE_MCU_RUNNING, &phy->state)) 204 mt76_connac_power_save_sched(phy, pm); 205 206 spin_unlock_bh(&pm->wake.lock); 207} 208 209static inline bool 210mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm) 211{ 212 struct mt76_dev *dev = phy->dev; 213 bool ret; 214 215 if (dev->token_count) 216 return true; 217 218 spin_lock_bh(&pm->wake.lock); 219 ret = pm->wake.count || test_and_set_bit(MT76_STATE_PM, &phy->state); 220 spin_unlock_bh(&pm->wake.lock); 221 222 return ret; 223} 224 225static inline void 226mt76_connac_mutex_acquire(struct mt76_dev *dev, struct mt76_connac_pm *pm) 227 __acquires(&dev->mutex) 228{ 229 mutex_lock(&dev->mutex); 230 mt76_connac_pm_wake(&dev->phy, pm); 231} 232 233static inline void 234mt76_connac_mutex_release(struct mt76_dev *dev, struct mt76_connac_pm *pm) 235 __releases(&dev->mutex) 236{ 237 mt76_connac_power_save_sched(&dev->phy, pm); 238 mutex_unlock(&dev->mutex); 239} 240 241void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw, 242 struct mt76_connac_pm *pm, 243 struct mt76_wcid *wcid, 244 struct sk_buff *skb); 245void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy, 246 struct mt76_connac_pm *pm); 247 248#endif /* __MT76_CONNAC_H */