Commit b566b2e8 authored by Kalle Valo's avatar Kalle Valo

Merge tag 'mt76-for-kvalo-2021-06-18' of https://github.com/nbd168/wireless into pending

mt76 patches for 5.14

* mt7915 MSI support
* disable ASPM on mt7915
* mt7915 tx status reporting
* mt7921 decap offload
* driver fixes
* cleanups
* mt7921 runtime power management improvements
* testmode improvements/fixes
* runtime PM improvements
parents 0c337952 61a1f99d
...@@ -191,6 +191,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, ...@@ -191,6 +191,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
q->entry[idx].txwi = txwi; q->entry[idx].txwi = txwi;
q->entry[idx].skb = skb; q->entry[idx].skb = skb;
q->entry[idx].wcid = 0xffff;
return idx; return idx;
} }
...@@ -349,6 +350,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, ...@@ -349,6 +350,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_wcid *wcid, struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta) struct ieee80211_sta *sta)
{ {
struct ieee80211_tx_status status = {
.sta = sta,
};
struct mt76_tx_info tx_info = { struct mt76_tx_info tx_info = {
.skb = skb, .skb = skb,
}; };
...@@ -360,11 +364,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, ...@@ -360,11 +364,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
u8 *txwi; u8 *txwi;
t = mt76_get_txwi(dev); t = mt76_get_txwi(dev);
if (!t) { if (!t)
hw = mt76_tx_status_get_hw(dev, skb); goto free_skb;
ieee80211_free_txskb(hw, skb);
return -ENOMEM;
}
txwi = mt76_get_txwi_ptr(dev, t); txwi = mt76_get_txwi_ptr(dev, t);
skb->prev = skb->next = NULL; skb->prev = skb->next = NULL;
...@@ -427,8 +429,13 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, ...@@ -427,8 +429,13 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
} }
#endif #endif
dev_kfree_skb(tx_info.skb);
mt76_put_txwi(dev, t); mt76_put_txwi(dev, t);
free_skb:
status.skb = tx_info.skb;
hw = mt76_tx_status_get_hw(dev, tx_info.skb);
ieee80211_tx_status_ext(hw, &status);
return ret; return ret;
} }
......
...@@ -83,6 +83,22 @@ static const struct ieee80211_tpt_blink mt76_tpt_blink[] = { ...@@ -83,6 +83,22 @@ static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
{ .throughput = 300 * 1024, .blink_time = 50 }, { .throughput = 300 * 1024, .blink_time = 50 },
}; };
struct ieee80211_rate mt76_rates[] = {
CCK_RATE(0, 10),
CCK_RATE(1, 20),
CCK_RATE(2, 55),
CCK_RATE(3, 110),
OFDM_RATE(11, 60),
OFDM_RATE(15, 90),
OFDM_RATE(10, 120),
OFDM_RATE(14, 180),
OFDM_RATE(9, 240),
OFDM_RATE(13, 360),
OFDM_RATE(8, 480),
OFDM_RATE(12, 540),
};
EXPORT_SYMBOL_GPL(mt76_rates);
static int mt76_led_init(struct mt76_dev *dev) static int mt76_led_init(struct mt76_dev *dev)
{ {
struct device_node *np = dev->dev->of_node; struct device_node *np = dev->dev->of_node;
...@@ -315,17 +331,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw) ...@@ -315,17 +331,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
ieee80211_hw_set(hw, MFP_CAPABLE); ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS); ieee80211_hw_set(hw, AP_LINK_PS);
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_ADHOC);
} }
struct mt76_phy * struct mt76_phy *
...@@ -346,6 +351,17 @@ mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, ...@@ -346,6 +351,17 @@ mt76_alloc_phy(struct mt76_dev *dev, unsigned int size,
phy->hw = hw; phy->hw = hw;
phy->priv = hw->priv + phy_size; phy->priv = hw->priv + phy_size;
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_ADHOC);
return phy; return phy;
} }
EXPORT_SYMBOL_GPL(mt76_alloc_phy); EXPORT_SYMBOL_GPL(mt76_alloc_phy);
...@@ -428,6 +444,17 @@ mt76_alloc_device(struct device *pdev, unsigned int size, ...@@ -428,6 +444,17 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
mutex_init(&dev->mcu.mutex); mutex_init(&dev->mcu.mutex);
dev->tx_worker.fn = mt76_tx_worker; dev->tx_worker.fn = mt76_tx_worker;
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_ADHOC);
spin_lock_init(&dev->token_lock); spin_lock_init(&dev->token_lock);
idr_init(&dev->token); idr_init(&dev->token);
...@@ -632,20 +659,19 @@ void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time) ...@@ -632,20 +659,19 @@ void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
} }
EXPORT_SYMBOL_GPL(mt76_update_survey_active_time); EXPORT_SYMBOL_GPL(mt76_update_survey_active_time);
void mt76_update_survey(struct mt76_dev *dev) void mt76_update_survey(struct mt76_phy *phy)
{ {
struct mt76_dev *dev = phy->dev;
ktime_t cur_time; ktime_t cur_time;
if (dev->drv->update_survey) if (dev->drv->update_survey)
dev->drv->update_survey(dev); dev->drv->update_survey(phy);
cur_time = ktime_get_boottime(); cur_time = ktime_get_boottime();
mt76_update_survey_active_time(&dev->phy, cur_time); mt76_update_survey_active_time(phy, cur_time);
if (dev->phy2)
mt76_update_survey_active_time(dev->phy2, cur_time);
if (dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME) { if (dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME) {
struct mt76_channel_state *state = dev->phy.chan_state; struct mt76_channel_state *state = phy->chan_state;
spin_lock_bh(&dev->cc_lock); spin_lock_bh(&dev->cc_lock);
state->cc_bss_rx += dev->cur_cc_bss_rx; state->cc_bss_rx += dev->cur_cc_bss_rx;
...@@ -664,7 +690,7 @@ void mt76_set_channel(struct mt76_phy *phy) ...@@ -664,7 +690,7 @@ void mt76_set_channel(struct mt76_phy *phy)
int timeout = HZ / 5; int timeout = HZ / 5;
wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout); wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout);
mt76_update_survey(dev); mt76_update_survey(phy);
phy->chandef = *chandef; phy->chandef = *chandef;
phy->chan_state = mt76_channel_state(phy, chandef->chan); phy->chan_state = mt76_channel_state(phy, chandef->chan);
...@@ -689,7 +715,7 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx, ...@@ -689,7 +715,7 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
mutex_lock(&dev->mutex); mutex_lock(&dev->mutex);
if (idx == 0 && dev->drv->update_survey) if (idx == 0 && dev->drv->update_survey)
mt76_update_survey(dev); mt76_update_survey(phy);
sband = &phy->sband_2g; sband = &phy->sband_2g;
if (idx >= sband->sband.n_channels) { if (idx >= sband->sband.n_channels) {
......
...@@ -87,6 +87,22 @@ enum mt76_rxq_id { ...@@ -87,6 +87,22 @@ enum mt76_rxq_id {
__MT_RXQ_MAX __MT_RXQ_MAX
}; };
enum mt76_cipher_type {
MT_CIPHER_NONE,
MT_CIPHER_WEP40,
MT_CIPHER_TKIP,
MT_CIPHER_TKIP_NO_MIC,
MT_CIPHER_AES_CCMP,
MT_CIPHER_WEP104,
MT_CIPHER_BIP_CMAC_128,
MT_CIPHER_WEP128,
MT_CIPHER_WAPI,
MT_CIPHER_CCMP_CCX,
MT_CIPHER_CCMP_256,
MT_CIPHER_GCMP,
MT_CIPHER_GCMP_256,
};
struct mt76_queue_buf { struct mt76_queue_buf {
dma_addr_t addr; dma_addr_t addr;
u16 len; u16 len;
...@@ -320,6 +336,7 @@ enum { ...@@ -320,6 +336,7 @@ enum {
struct mt76_hw_cap { struct mt76_hw_cap {
bool has_2ghz; bool has_2ghz;
bool has_5ghz; bool has_5ghz;
bool has_6ghz;
}; };
#define MT_DRV_TXWI_NO_FREE BIT(0) #define MT_DRV_TXWI_NO_FREE BIT(0)
...@@ -336,7 +353,7 @@ struct mt76_driver_ops { ...@@ -336,7 +353,7 @@ struct mt76_driver_ops {
u16 token_size; u16 token_size;
u8 mcs_rates; u8 mcs_rates;
void (*update_survey)(struct mt76_dev *dev); void (*update_survey)(struct mt76_phy *phy);
int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr, int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr,
enum mt76_txq_id qid, struct mt76_wcid *wcid, enum mt76_txq_id qid, struct mt76_wcid *wcid,
...@@ -738,6 +755,21 @@ enum mt76_phy_type { ...@@ -738,6 +755,21 @@ enum mt76_phy_type {
MT_PHY_TYPE_HE_MU, MT_PHY_TYPE_HE_MU,
}; };
#define CCK_RATE(_idx, _rate) { \
.bitrate = _rate, \
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \
.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \
}
#define OFDM_RATE(_idx, _rate) { \
.bitrate = _rate, \
.hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
}
extern struct ieee80211_rate mt76_rates[12];
#define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__) #define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__)
#define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__) #define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__)
#define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__) #define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__)
...@@ -1031,7 +1063,7 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw, ...@@ -1031,7 +1063,7 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw,
bool more_data); bool more_data);
bool mt76_has_tx_pending(struct mt76_phy *phy); bool mt76_has_tx_pending(struct mt76_phy *phy);
void mt76_set_channel(struct mt76_phy *phy); void mt76_set_channel(struct mt76_phy *phy);
void mt76_update_survey(struct mt76_dev *dev); void mt76_update_survey(struct mt76_phy *phy);
void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time);
int mt76_get_survey(struct ieee80211_hw *hw, int idx, int mt76_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey); struct survey_info *survey);
...@@ -1056,7 +1088,14 @@ struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev, ...@@ -1056,7 +1088,14 @@ struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev,
struct sk_buff_head *list); struct sk_buff_head *list);
void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb,
struct sk_buff_head *list); struct sk_buff_head *list);
void mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb); void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb,
struct list_head *free_list);
static inline void
mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid, struct sk_buff *skb)
{
__mt76_tx_complete_skb(dev, wcid, skb, NULL);
}
void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid, void mt76_tx_status_check(struct mt76_dev *dev, struct mt76_wcid *wcid,
bool flush); bool flush);
int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
...@@ -1253,4 +1292,15 @@ mt76_token_put(struct mt76_dev *dev, int token) ...@@ -1253,4 +1292,15 @@ mt76_token_put(struct mt76_dev *dev, int token)
return txwi; return txwi;
} }
static inline int
mt76_get_next_pkt_id(struct mt76_wcid *wcid)
{
wcid->packet_id = (wcid->packet_id + 1) & MT_PACKET_ID_MASK;
if (wcid->packet_id == MT_PACKET_ID_NO_ACK ||
wcid->packet_id == MT_PACKET_ID_NO_SKB)
wcid->packet_id = MT_PACKET_ID_FIRST;
return wcid->packet_id;
}
#endif #endif
...@@ -304,34 +304,6 @@ mt7603_init_hardware(struct mt7603_dev *dev) ...@@ -304,34 +304,6 @@ mt7603_init_hardware(struct mt7603_dev *dev)
return 0; return 0;
} }
#define CCK_RATE(_idx, _rate) { \
.bitrate = _rate, \
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \
.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + _idx), \
}
#define OFDM_RATE(_idx, _rate) { \
.bitrate = _rate, \
.hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
}
static struct ieee80211_rate mt7603_rates[] = {
CCK_RATE(0, 10),
CCK_RATE(1, 20),
CCK_RATE(2, 55),
CCK_RATE(3, 110),
OFDM_RATE(11, 60),
OFDM_RATE(15, 90),
OFDM_RATE(10, 120),
OFDM_RATE(14, 180),
OFDM_RATE(9, 240),
OFDM_RATE(13, 360),
OFDM_RATE(8, 480),
OFDM_RATE(12, 540),
};
static const struct ieee80211_iface_limit if_limits[] = { static const struct ieee80211_iface_limit if_limits[] = {
{ {
.max = 1, .max = 1,
...@@ -569,8 +541,8 @@ int mt7603_register_device(struct mt7603_dev *dev) ...@@ -569,8 +541,8 @@ int mt7603_register_device(struct mt7603_dev *dev)
wiphy->reg_notifier = mt7603_regd_notifier; wiphy->reg_notifier = mt7603_regd_notifier;
ret = mt76_register_device(&dev->mt76, true, mt7603_rates, ret = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt7603_rates)); ARRAY_SIZE(mt76_rates));
if (ret) if (ret)
return ret; return ret;
......
...@@ -550,14 +550,27 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) ...@@ -550,14 +550,27 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
u8 *data = (u8 *)rxd; u8 *data = (u8 *)rxd;
if (status->flag & RX_FLAG_DECRYPTED) { if (status->flag & RX_FLAG_DECRYPTED) {
status->iv[0] = data[5]; switch (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2)) {
status->iv[1] = data[4]; case MT_CIPHER_AES_CCMP:
status->iv[2] = data[3]; case MT_CIPHER_CCMP_CCX:
status->iv[3] = data[2]; case MT_CIPHER_CCMP_256:
status->iv[4] = data[1]; insert_ccmp_hdr =
status->iv[5] = data[0]; FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
fallthrough;
insert_ccmp_hdr = FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2); case MT_CIPHER_TKIP:
case MT_CIPHER_TKIP_NO_MIC:
case MT_CIPHER_GCMP:
case MT_CIPHER_GCMP_256:
status->iv[0] = data[5];
status->iv[1] = data[4];
status->iv[2] = data[3];
status->iv[3] = data[2];
status->iv[4] = data[1];
status->iv[5] = data[0];
break;
default:
break;
}
} }
rxd += 4; rxd += 4;
...@@ -831,7 +844,7 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta, ...@@ -831,7 +844,7 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta,
sta->wcid.tx_info |= MT_WCID_TX_INFO_SET; sta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
} }
static enum mt7603_cipher_type static enum mt76_cipher_type
mt7603_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) mt7603_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
{ {
memset(key_data, 0, 32); memset(key_data, 0, 32);
...@@ -863,7 +876,7 @@ mt7603_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) ...@@ -863,7 +876,7 @@ mt7603_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
int mt7603_wtbl_set_key(struct mt7603_dev *dev, int wcid, int mt7603_wtbl_set_key(struct mt7603_dev *dev, int wcid,
struct ieee80211_key_conf *key) struct ieee80211_key_conf *key)
{ {
enum mt7603_cipher_type cipher; enum mt76_cipher_type cipher;
u32 addr = mt7603_wtbl3_addr(wcid); u32 addr = mt7603_wtbl3_addr(wcid);
u8 key_data[32]; u8 key_data[32];
int key_len = sizeof(key_data); int key_len = sizeof(key_data);
...@@ -1213,7 +1226,7 @@ mt7603_mac_add_txs_skb(struct mt7603_dev *dev, struct mt7603_sta *sta, int pid, ...@@ -1213,7 +1226,7 @@ mt7603_mac_add_txs_skb(struct mt7603_dev *dev, struct mt7603_sta *sta, int pid,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (!mt7603_fill_txs(dev, sta, info, txs_data)) { if (!mt7603_fill_txs(dev, sta, info, txs_data)) {
ieee80211_tx_info_clear_status(info); info->status.rates[0].count = 0;
info->status.rates[0].idx = -1; info->status.rates[0].idx = -1;
} }
...@@ -1584,12 +1597,12 @@ mt7603_watchdog_check(struct mt7603_dev *dev, u8 *counter, ...@@ -1584,12 +1597,12 @@ mt7603_watchdog_check(struct mt7603_dev *dev, u8 *counter,
return true; return true;
} }
void mt7603_update_channel(struct mt76_dev *mdev) void mt7603_update_channel(struct mt76_phy *mphy)
{ {
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); struct mt7603_dev *dev = container_of(mphy->dev, struct mt7603_dev, mt76);
struct mt76_channel_state *state; struct mt76_channel_state *state;
state = mdev->phy.chan_state; state = mphy->chan_state;
state->cc_busy += mt76_rr(dev, MT_MIB_STAT_CCA); state->cc_busy += mt76_rr(dev, MT_MIB_STAT_CCA);
} }
...@@ -1806,7 +1819,7 @@ void mt7603_mac_work(struct work_struct *work) ...@@ -1806,7 +1819,7 @@ void mt7603_mac_work(struct work_struct *work)
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
dev->mphy.mac_work_count++; dev->mphy.mac_work_count++;
mt76_update_survey(&dev->mt76); mt76_update_survey(&dev->mphy);
mt7603_edcca_check(dev); mt7603_edcca_check(dev);
for (i = 0, idx = 0; i < 2; i++) { for (i = 0, idx = 0; i < 2; i++) {
......
...@@ -256,7 +256,7 @@ void mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, ...@@ -256,7 +256,7 @@ void mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t); void mt7603_pre_tbtt_tasklet(struct tasklet_struct *t);
void mt7603_update_channel(struct mt76_dev *mdev); void mt7603_update_channel(struct mt76_phy *mphy);
void mt7603_edcca_set_strict(struct mt7603_dev *dev, bool val); void mt7603_edcca_set_strict(struct mt7603_dev *dev, bool val);
void mt7603_cca_stats_reset(struct mt7603_dev *dev); void mt7603_cca_stats_reset(struct mt7603_dev *dev);
......
...@@ -765,16 +765,4 @@ enum { ...@@ -765,16 +765,4 @@ enum {
#define MT_WTBL1_OR (MT_WTBL1_BASE + 0x2300) #define MT_WTBL1_OR (MT_WTBL1_BASE + 0x2300)
#define MT_WTBL1_OR_PSM_WRITE BIT(31) #define MT_WTBL1_OR_PSM_WRITE BIT(31)
enum mt7603_cipher_type {
MT_CIPHER_NONE,
MT_CIPHER_WEP40,
MT_CIPHER_TKIP,
MT_CIPHER_TKIP_NO_MIC,
MT_CIPHER_AES_CCMP,
MT_CIPHER_WEP104,
MT_CIPHER_BIP_CMAC_128,
MT_CIPHER_WEP128,
MT_CIPHER_WAPI,
};
#endif #endif
#SPDX-License-Identifier: ISC # SPDX-License-Identifier: ISC
obj-$(CONFIG_MT7615_COMMON) += mt7615-common.o obj-$(CONFIG_MT7615_COMMON) += mt7615-common.o
obj-$(CONFIG_MT7615E) += mt7615e.o obj-$(CONFIG_MT7615E) += mt7615e.o
......
...@@ -75,7 +75,7 @@ mt7615_pm_set(void *data, u64 val) ...@@ -75,7 +75,7 @@ mt7615_pm_set(void *data, u64 val)
if (!mt7615_wait_for_mcu_init(dev)) if (!mt7615_wait_for_mcu_init(dev))
return 0; return 0;
if (!mt7615_firmware_offload(dev) || !mt76_is_mmio(&dev->mt76)) if (!mt7615_firmware_offload(dev) || mt76_is_usb(&dev->mt76))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (val == pm->enable) if (val == pm->enable)
...@@ -319,24 +319,6 @@ mt7615_radio_read(struct seq_file *s, void *data) ...@@ -319,24 +319,6 @@ mt7615_radio_read(struct seq_file *s, void *data)
return 0; return 0;
} }
static int mt7615_read_temperature(struct seq_file *s, void *data)
{
struct mt7615_dev *dev = dev_get_drvdata(s->private);
int temp;
if (!mt7615_wait_for_mcu_init(dev))
return 0;
/* cpu */
mt7615_mutex_acquire(dev);
temp = mt7615_mcu_get_temperature(dev, 0);
mt7615_mutex_release(dev);
seq_printf(s, "Temperature: %d\n", temp);
return 0;
}
static int static int
mt7615_queues_acq(struct seq_file *s, void *data) mt7615_queues_acq(struct seq_file *s, void *data)
{ {
...@@ -566,8 +548,6 @@ int mt7615_init_debugfs(struct mt7615_dev *dev) ...@@ -566,8 +548,6 @@ int mt7615_init_debugfs(struct mt7615_dev *dev)
debugfs_create_file("reset_test", 0200, dir, dev, debugfs_create_file("reset_test", 0200, dir, dev,
&fops_reset_test); &fops_reset_test);
debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
mt7615_read_temperature);
debugfs_create_file("ext_mac_addr", 0600, dir, dev, &fops_ext_mac_addr); debugfs_create_file("ext_mac_addr", 0600, dir, dev, &fops_ext_mac_addr);
debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf); debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
......
...@@ -81,7 +81,7 @@ static int mt7615_poll_tx(struct napi_struct *napi, int budget) ...@@ -81,7 +81,7 @@ static int mt7615_poll_tx(struct napi_struct *napi, int budget)
if (napi_complete(napi)) if (napi_complete(napi))
mt7615_irq_enable(dev, mt7615_tx_mcu_int_mask(dev)); mt7615_irq_enable(dev, mt7615_tx_mcu_int_mask(dev));
mt76_connac_pm_unref(&dev->pm); mt76_connac_pm_unref(&dev->mphy, &dev->pm);
return 0; return 0;
} }
...@@ -99,7 +99,7 @@ static int mt7615_poll_rx(struct napi_struct *napi, int budget) ...@@ -99,7 +99,7 @@ static int mt7615_poll_rx(struct napi_struct *napi, int budget)
return 0; return 0;
} }
done = mt76_dma_rx_poll(napi, budget); done = mt76_dma_rx_poll(napi, budget);
mt76_connac_pm_unref(&dev->pm); mt76_connac_pm_unref(&dev->mphy, &dev->pm);
return done; return done;
} }
...@@ -222,14 +222,9 @@ void mt7615_dma_start(struct mt7615_dev *dev) ...@@ -222,14 +222,9 @@ void mt7615_dma_start(struct mt7615_dev *dev)
int mt7615_dma_init(struct mt7615_dev *dev) int mt7615_dma_init(struct mt7615_dev *dev)
{ {
int rx_ring_size = MT7615_RX_RING_SIZE; int rx_ring_size = MT7615_RX_RING_SIZE;
int rx_buf_size = MT_RX_BUF_SIZE;
u32 mask; u32 mask;
int ret; int ret;
/* Increase buffer size to receive large VHT MPDUs */
if (dev->mphy.cap.has_5ghz)
rx_buf_size *= 2;
mt76_dma_attach(&dev->mt76); mt76_dma_attach(&dev->mt76);
mt76_wr(dev, MT_WPDMA_GLO_CFG, mt76_wr(dev, MT_WPDMA_GLO_CFG,
...@@ -270,7 +265,7 @@ int mt7615_dma_init(struct mt7615_dev *dev) ...@@ -270,7 +265,7 @@ int mt7615_dma_init(struct mt7615_dev *dev)
/* init rx queues */ /* init rx queues */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1, ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1,
MT7615_RX_MCU_RING_SIZE, rx_buf_size, MT7615_RX_MCU_RING_SIZE, MT_RX_BUF_SIZE,
MT_RX_RING_BASE); MT_RX_RING_BASE);
if (ret) if (ret)
return ret; return ret;
...@@ -279,7 +274,7 @@ int mt7615_dma_init(struct mt7615_dev *dev) ...@@ -279,7 +274,7 @@ int mt7615_dma_init(struct mt7615_dev *dev)
rx_ring_size /= 2; rx_ring_size /= 2;
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 0, ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 0,
rx_ring_size, rx_buf_size, MT_RX_RING_BASE); rx_ring_size, MT_RX_BUF_SIZE, MT_RX_RING_BASE);
if (ret) if (ret)
return ret; return ret;
......
...@@ -8,11 +8,61 @@ ...@@ -8,11 +8,61 @@
*/ */
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include "mt7615.h" #include "mt7615.h"
#include "mac.h" #include "mac.h"
#include "mcu.h" #include "mcu.h"
#include "eeprom.h" #include "eeprom.h"
static ssize_t mt7615_thermal_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct mt7615_dev *mdev = dev_get_drvdata(dev);
int temperature;
if (!mt7615_wait_for_mcu_init(mdev))
return 0;
mt7615_mutex_acquire(mdev);
temperature = mt7615_mcu_get_temperature(mdev);
mt7615_mutex_release(mdev);
if (temperature < 0)
return temperature;
/* display in millidegree celcius */
return sprintf(buf, "%u\n", temperature * 1000);
}
static SENSOR_DEVICE_ATTR(temp1_input, 0444, mt7615_thermal_show_temp,
NULL, 0);
static struct attribute *mt7615_hwmon_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(mt7615_hwmon);
int mt7615_thermal_init(struct mt7615_dev *dev)
{
struct wiphy *wiphy = mt76_hw(dev)->wiphy;
struct device *hwmon;
if (!IS_REACHABLE(CONFIG_HWMON))
return 0;
hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev,
wiphy_name(wiphy), dev,
mt7615_hwmon_groups);
if (IS_ERR(hwmon))
return PTR_ERR(hwmon);
return 0;
}
EXPORT_SYMBOL_GPL(mt7615_thermal_init);
static void static void
mt7615_phy_init(struct mt7615_dev *dev) mt7615_phy_init(struct mt7615_dev *dev)
{ {
...@@ -174,35 +224,6 @@ bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev) ...@@ -174,35 +224,6 @@ bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev)
} }
EXPORT_SYMBOL_GPL(mt7615_wait_for_mcu_init); EXPORT_SYMBOL_GPL(mt7615_wait_for_mcu_init);
#define CCK_RATE(_idx, _rate) { \
.bitrate = _rate, \
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \
.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + (_idx)), \
}
#define OFDM_RATE(_idx, _rate) { \
.bitrate = _rate, \
.hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
}
struct ieee80211_rate mt7615_rates[] = {
CCK_RATE(0, 10),
CCK_RATE(1, 20),
CCK_RATE(2, 55),
CCK_RATE(3, 110),
OFDM_RATE(11, 60),
OFDM_RATE(15, 90),
OFDM_RATE(10, 120),
OFDM_RATE(14, 180),
OFDM_RATE(9, 240),
OFDM_RATE(13, 360),
OFDM_RATE(8, 480),
OFDM_RATE(12, 540),
};
EXPORT_SYMBOL_GPL(mt7615_rates);
static const struct ieee80211_iface_limit if_limits[] = { static const struct ieee80211_iface_limit if_limits[] = {
{ {
.max = 1, .max = 1,
...@@ -362,7 +383,7 @@ mt7615_init_wiphy(struct ieee80211_hw *hw) ...@@ -362,7 +383,7 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
wiphy->reg_notifier = mt7615_regd_notifier; wiphy->reg_notifier = mt7615_regd_notifier;
wiphy->max_sched_scan_plan_interval = wiphy->max_sched_scan_plan_interval =
MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL; MT76_CONNAC_MAX_TIME_SCHED_SCAN_INTERVAL;
wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN; wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN; wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID; wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
...@@ -472,8 +493,8 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev) ...@@ -472,8 +493,8 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
for (i = 0; i <= MT_TXQ_PSD ; i++) for (i = 0; i <= MT_TXQ_PSD ; i++)
mphy->q_tx[i] = dev->mphy.q_tx[i]; mphy->q_tx[i] = dev->mphy.q_tx[i];
ret = mt76_register_phy(mphy, true, mt7615_rates, ret = mt76_register_phy(mphy, true, mt76_rates,
ARRAY_SIZE(mt7615_rates)); ARRAY_SIZE(mt76_rates));
if (ret) if (ret)
ieee80211_free_hw(mphy->hw); ieee80211_free_hw(mphy->hw);
......
...@@ -383,48 +383,6 @@ struct mt7615_dfs_radar_spec { ...@@ -383,48 +383,6 @@ struct mt7615_dfs_radar_spec {
struct mt7615_dfs_pattern radar_pattern[16]; struct mt7615_dfs_pattern radar_pattern[16];
}; };
enum mt7615_cipher_type {
MT_CIPHER_NONE,
MT_CIPHER_WEP40,
MT_CIPHER_TKIP,
MT_CIPHER_TKIP_NO_MIC,
MT_CIPHER_AES_CCMP,
MT_CIPHER_WEP104,
MT_CIPHER_BIP_CMAC_128,
MT_CIPHER_WEP128,
MT_CIPHER_WAPI,
MT_CIPHER_CCMP_256 = 10,
MT_CIPHER_GCMP,
MT_CIPHER_GCMP_256,
};
static inline enum mt7615_cipher_type
mt7615_mac_get_cipher(int cipher)
{
switch (cipher) {
case WLAN_CIPHER_SUITE_WEP40:
return MT_CIPHER_WEP40;
case WLAN_CIPHER_SUITE_WEP104:
return MT_CIPHER_WEP104;
case WLAN_CIPHER_SUITE_TKIP:
return MT_CIPHER_TKIP;
case WLAN_CIPHER_SUITE_AES_CMAC:
return MT_CIPHER_BIP_CMAC_128;
case WLAN_CIPHER_SUITE_CCMP:
return MT_CIPHER_AES_CCMP;
case WLAN_CIPHER_SUITE_CCMP_256:
return MT_CIPHER_CCMP_256;
case WLAN_CIPHER_SUITE_GCMP:
return MT_CIPHER_GCMP;
case WLAN_CIPHER_SUITE_GCMP_256:
return MT_CIPHER_GCMP_256;
case WLAN_CIPHER_SUITE_SMS4:
return MT_CIPHER_WAPI;
default:
return MT_CIPHER_NONE;
}
}
static inline struct mt7615_txp_common * static inline struct mt7615_txp_common *
mt7615_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t) mt7615_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t)
{ {
......
...@@ -28,6 +28,7 @@ static int mt7615_start(struct ieee80211_hw *hw) ...@@ -28,6 +28,7 @@ static int mt7615_start(struct ieee80211_hw *hw)
{ {
struct mt7615_dev *dev = mt7615_hw_dev(hw); struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt7615_phy *phy = mt7615_hw_phy(hw); struct mt7615_phy *phy = mt7615_hw_phy(hw);
unsigned long timeout;
bool running; bool running;
int ret; int ret;
...@@ -78,8 +79,8 @@ static int mt7615_start(struct ieee80211_hw *hw) ...@@ -78,8 +79,8 @@ static int mt7615_start(struct ieee80211_hw *hw)
set_bit(MT76_STATE_RUNNING, &phy->mt76->state); set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, timeout = mt7615_get_macwork_timeout(dev);
MT7615_WATCHDOG_TIME); ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, timeout);
if (!running) if (!running)
mt7615_mac_reset_counters(dev); mt7615_mac_reset_counters(dev);
...@@ -240,8 +241,6 @@ static int mt7615_add_interface(struct ieee80211_hw *hw, ...@@ -240,8 +241,6 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
} }
ret = mt7615_mcu_add_dev_info(phy, vif, true); ret = mt7615_mcu_add_dev_info(phy, vif, true);
if (ret)
goto out;
out: out:
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
...@@ -352,10 +351,12 @@ int mt7615_set_channel(struct mt7615_phy *phy) ...@@ -352,10 +351,12 @@ int mt7615_set_channel(struct mt7615_phy *phy)
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
mt76_worker_schedule(&dev->mt76.tx_worker); mt76_worker_schedule(&dev->mt76.tx_worker);
if (!mt76_testmode_enabled(phy->mt76)) if (!mt76_testmode_enabled(phy->mt76)) {
unsigned long timeout = mt7615_get_macwork_timeout(dev);
ieee80211_queue_delayed_work(phy->mt76->hw, ieee80211_queue_delayed_work(phy->mt76->hw,
&phy->mt76->mac_work, &phy->mt76->mac_work, timeout);
MT7615_WATCHDOG_TIME); }
return ret; return ret;
} }
...@@ -695,7 +696,7 @@ static void mt7615_sta_rate_tbl_update(struct ieee80211_hw *hw, ...@@ -695,7 +696,7 @@ static void mt7615_sta_rate_tbl_update(struct ieee80211_hw *hw,
msta->n_rates = i; msta->n_rates = i;
if (mt76_connac_pm_ref(phy->mt76, &dev->pm)) { if (mt76_connac_pm_ref(phy->mt76, &dev->pm)) {
mt7615_mac_set_rates(phy, msta, NULL, msta->rates); mt7615_mac_set_rates(phy, msta, NULL, msta->rates);
mt76_connac_pm_unref(&dev->pm); mt76_connac_pm_unref(phy->mt76, &dev->pm);
} }
spin_unlock_bh(&dev->mt76.lock); spin_unlock_bh(&dev->mt76.lock);
} }
...@@ -711,7 +712,7 @@ void mt7615_tx_worker(struct mt76_worker *w) ...@@ -711,7 +712,7 @@ void mt7615_tx_worker(struct mt76_worker *w)
} }
mt76_tx_worker_run(&dev->mt76); mt76_tx_worker_run(&dev->mt76);
mt76_connac_pm_unref(&dev->pm); mt76_connac_pm_unref(&dev->mphy, &dev->pm);
} }
static void mt7615_tx(struct ieee80211_hw *hw, static void mt7615_tx(struct ieee80211_hw *hw,
...@@ -741,7 +742,7 @@ static void mt7615_tx(struct ieee80211_hw *hw, ...@@ -741,7 +742,7 @@ static void mt7615_tx(struct ieee80211_hw *hw,
if (mt76_connac_pm_ref(mphy, &dev->pm)) { if (mt76_connac_pm_ref(mphy, &dev->pm)) {
mt76_tx(mphy, control->sta, wcid, skb); mt76_tx(mphy, control->sta, wcid, skb);
mt76_connac_pm_unref(&dev->pm); mt76_connac_pm_unref(mphy, &dev->pm);
return; return;
} }
...@@ -881,7 +882,8 @@ mt7615_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -881,7 +882,8 @@ mt7615_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
mt7615_mutex_acquire(dev); mt7615_mutex_acquire(dev);
mt76_set(dev, reg, MT_LPON_TCR_MODE); /* TSF read */ /* TSF read */
mt76_rmw(dev, reg, MT_LPON_TCR_MODE, MT_LPON_TCR_READ);
tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0); tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0);
tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1); tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1);
...@@ -911,7 +913,33 @@ mt7615_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -911,7 +913,33 @@ mt7615_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mt76_wr(dev, MT_LPON_UTTR0, tsf.t32[0]); mt76_wr(dev, MT_LPON_UTTR0, tsf.t32[0]);
mt76_wr(dev, MT_LPON_UTTR1, tsf.t32[1]); mt76_wr(dev, MT_LPON_UTTR1, tsf.t32[1]);
/* TSF software overwrite */ /* TSF software overwrite */
mt76_set(dev, reg, MT_LPON_TCR_WRITE); mt76_rmw(dev, reg, MT_LPON_TCR_MODE, MT_LPON_TCR_WRITE);
mt7615_mutex_release(dev);
}
static void
mt7615_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
s64 timestamp)
{
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
struct mt7615_dev *dev = mt7615_hw_dev(hw);
union {
u64 t64;
u32 t32[2];
} tsf = { .t64 = timestamp, };
u16 idx = mvif->mt76.omac_idx;
u32 reg;
idx = idx > HW_BSSID_MAX ? HW_BSSID_0 : idx;
reg = idx > 1 ? MT_LPON_TCR2(idx): MT_LPON_TCR0(idx);
mt7615_mutex_acquire(dev);
mt76_wr(dev, MT_LPON_UTTR0, tsf.t32[0]);
mt76_wr(dev, MT_LPON_UTTR1, tsf.t32[1]);
/* TSF software adjust*/
mt76_rmw(dev, reg, MT_LPON_TCR_MODE, MT_LPON_TCR_ADJUST);
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
} }
...@@ -1162,7 +1190,7 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw, ...@@ -1162,7 +1190,7 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw,
else else
clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags); clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
mt7615_mcu_sta_update_hdr_trans(dev, vif, sta); mt7615_mcu_set_sta_decap_offload(dev, vif, sta);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -1200,6 +1228,7 @@ static int mt7615_resume(struct ieee80211_hw *hw) ...@@ -1200,6 +1228,7 @@ static int mt7615_resume(struct ieee80211_hw *hw)
{ {
struct mt7615_phy *phy = mt7615_hw_phy(hw); struct mt7615_phy *phy = mt7615_hw_phy(hw);
struct mt7615_dev *dev = mt7615_hw_dev(hw); struct mt7615_dev *dev = mt7615_hw_dev(hw);
unsigned long timeout;
bool running; bool running;
mt7615_mutex_acquire(dev); mt7615_mutex_acquire(dev);
...@@ -1223,8 +1252,8 @@ static int mt7615_resume(struct ieee80211_hw *hw) ...@@ -1223,8 +1252,8 @@ static int mt7615_resume(struct ieee80211_hw *hw)
mt76_connac_mcu_set_suspend_iter, mt76_connac_mcu_set_suspend_iter,
phy->mt76); phy->mt76);
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, timeout = mt7615_get_macwork_timeout(dev);
MT7615_WATCHDOG_TIME); ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, timeout);
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
...@@ -1278,6 +1307,7 @@ const struct ieee80211_ops mt7615_ops = { ...@@ -1278,6 +1307,7 @@ const struct ieee80211_ops mt7615_ops = {
.get_stats = mt7615_get_stats, .get_stats = mt7615_get_stats,
.get_tsf = mt7615_get_tsf, .get_tsf = mt7615_get_tsf,
.set_tsf = mt7615_set_tsf, .set_tsf = mt7615_set_tsf,
.offset_tsf = mt7615_offset_tsf,
.get_survey = mt76_get_survey, .get_survey = mt76_get_survey,
.get_antenna = mt76_get_antenna, .get_antenna = mt76_get_antenna,
.set_antenna = mt7615_set_antenna, .set_antenna = mt7615_set_antenna,
......
...@@ -411,6 +411,9 @@ mt7615_mcu_rx_csa_notify(struct mt7615_dev *dev, struct sk_buff *skb) ...@@ -411,6 +411,9 @@ mt7615_mcu_rx_csa_notify(struct mt7615_dev *dev, struct sk_buff *skb)
c = (struct mt7615_mcu_csa_notify *)skb->data; c = (struct mt7615_mcu_csa_notify *)skb->data;
if (c->omac_idx > EXT_BSSID_MAX)
return;
if (ext_phy && ext_phy->omac_mask & BIT_ULL(c->omac_idx)) if (ext_phy && ext_phy->omac_mask & BIT_ULL(c->omac_idx))
mphy = dev->mt76.phy2; mphy = dev->mt76.phy2;
...@@ -427,6 +430,10 @@ mt7615_mcu_rx_radar_detected(struct mt7615_dev *dev, struct sk_buff *skb) ...@@ -427,6 +430,10 @@ mt7615_mcu_rx_radar_detected(struct mt7615_dev *dev, struct sk_buff *skb)
r = (struct mt7615_mcu_rdd_report *)skb->data; r = (struct mt7615_mcu_rdd_report *)skb->data;
if (!dev->radar_pattern.n_pulses && !r->long_detected &&
!r->constant_prf_detected && !r->staggered_prf_detected)
return;
if (r->band_idx && dev->mt76.phy2) if (r->band_idx && dev->mt76.phy2)
mphy = dev->mt76.phy2; mphy = dev->mt76.phy2;
...@@ -1021,9 +1028,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, ...@@ -1021,9 +1028,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
if (IS_ERR(sskb)) if (IS_ERR(sskb))
return PTR_ERR(sskb); return PTR_ERR(sskb);
mt76_connac_mcu_sta_basic_tlv(sskb, vif, sta, enable); mt76_connac_mcu_sta_basic_tlv(sskb, vif, sta, enable, true);
if (enable && sta) if (enable && sta)
mt76_connac_mcu_sta_tlv(phy->mt76, sskb, sta, vif, 0); mt76_connac_mcu_sta_tlv(phy->mt76, sskb, sta, vif, 0,
MT76_STA_INFO_STATE_ASSOC);
wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,
WTBL_RESET_AND_SET, NULL, WTBL_RESET_AND_SET, NULL,
...@@ -1037,8 +1045,8 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, ...@@ -1037,8 +1045,8 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
if (sta) if (sta)
mt76_connac_mcu_wtbl_ht_tlv(&dev->mt76, wskb, sta, mt76_connac_mcu_wtbl_ht_tlv(&dev->mt76, wskb, sta,
NULL, wtbl_hdr); NULL, wtbl_hdr);
mt76_connac_mcu_wtbl_hdr_trans_tlv(wskb, &msta->wcid, NULL, mt76_connac_mcu_wtbl_hdr_trans_tlv(wskb, vif, &msta->wcid,
wtbl_hdr); NULL, wtbl_hdr);
} }
cmd = enable ? MCU_EXT_CMD_WTBL_UPDATE : MCU_EXT_CMD_STA_REC_UPDATE; cmd = enable ? MCU_EXT_CMD_WTBL_UPDATE : MCU_EXT_CMD_STA_REC_UPDATE;
...@@ -1058,6 +1066,26 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, ...@@ -1058,6 +1066,26 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
return mt76_mcu_skb_send_msg(&dev->mt76, skb, cmd, true); return mt76_mcu_skb_send_msg(&dev->mt76, skb, cmd, true);
} }
static int
mt7615_mcu_wtbl_update_hdr_trans(struct mt7615_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
struct wtbl_req_hdr *wtbl_hdr;
struct sk_buff *skb = NULL;
wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,
WTBL_SET, NULL, &skb);
if (IS_ERR(wtbl_hdr))
return PTR_ERR(wtbl_hdr);
mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, &msta->wcid, NULL,
wtbl_hdr);
return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_WTBL_UPDATE,
true);
}
static const struct mt7615_mcu_ops wtbl_update_ops = { static const struct mt7615_mcu_ops wtbl_update_ops = {
.add_beacon_offload = mt7615_mcu_add_beacon_offload, .add_beacon_offload = mt7615_mcu_add_beacon_offload,
.set_pm_state = mt7615_mcu_ctrl_pm_state, .set_pm_state = mt7615_mcu_ctrl_pm_state,
...@@ -1068,6 +1096,7 @@ static const struct mt7615_mcu_ops wtbl_update_ops = { ...@@ -1068,6 +1096,7 @@ static const struct mt7615_mcu_ops wtbl_update_ops = {
.sta_add = mt7615_mcu_wtbl_sta_add, .sta_add = mt7615_mcu_wtbl_sta_add,
.set_drv_ctrl = mt7615_mcu_drv_pmctrl, .set_drv_ctrl = mt7615_mcu_drv_pmctrl,
.set_fw_ctrl = mt7615_mcu_fw_pmctrl, .set_fw_ctrl = mt7615_mcu_fw_pmctrl,
.set_sta_decap_offload = mt7615_mcu_wtbl_update_hdr_trans,
}; };
static int static int
...@@ -1120,18 +1149,21 @@ mt7615_mcu_sta_rx_ba(struct mt7615_dev *dev, ...@@ -1120,18 +1149,21 @@ mt7615_mcu_sta_rx_ba(struct mt7615_dev *dev,
static int static int
__mt7615_mcu_add_sta(struct mt76_phy *phy, struct ieee80211_vif *vif, __mt7615_mcu_add_sta(struct mt76_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable, int cmd) struct ieee80211_sta *sta, bool enable, int cmd,
bool offload_fw)
{ {
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
struct mt76_sta_cmd_info info = { struct mt76_sta_cmd_info info = {
.sta = sta, .sta = sta,
.vif = vif, .vif = vif,
.offload_fw = offload_fw,
.enable = enable, .enable = enable,
.newly = true,
.cmd = cmd, .cmd = cmd,
}; };
info.wcid = sta ? (struct mt76_wcid *)sta->drv_priv : &mvif->sta.wcid; info.wcid = sta ? (struct mt76_wcid *)sta->drv_priv : &mvif->sta.wcid;
return mt76_connac_mcu_add_sta_cmd(phy, &info); return mt76_connac_mcu_sta_cmd(phy, &info);
} }
static int static int
...@@ -1139,7 +1171,19 @@ mt7615_mcu_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif, ...@@ -1139,7 +1171,19 @@ mt7615_mcu_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable) struct ieee80211_sta *sta, bool enable)
{ {
return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable, return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,
MCU_EXT_CMD_STA_REC_UPDATE); MCU_EXT_CMD_STA_REC_UPDATE, false);
}
static int
mt7615_mcu_sta_update_hdr_trans(struct mt7615_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
return mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76,
vif, &msta->wcid,
MCU_EXT_CMD_STA_REC_UPDATE);
} }
static const struct mt7615_mcu_ops sta_update_ops = { static const struct mt7615_mcu_ops sta_update_ops = {
...@@ -1152,27 +1196,9 @@ static const struct mt7615_mcu_ops sta_update_ops = { ...@@ -1152,27 +1196,9 @@ static const struct mt7615_mcu_ops sta_update_ops = {
.sta_add = mt7615_mcu_add_sta, .sta_add = mt7615_mcu_add_sta,
.set_drv_ctrl = mt7615_mcu_drv_pmctrl, .set_drv_ctrl = mt7615_mcu_drv_pmctrl,
.set_fw_ctrl = mt7615_mcu_fw_pmctrl, .set_fw_ctrl = mt7615_mcu_fw_pmctrl,
.set_sta_decap_offload = mt7615_mcu_sta_update_hdr_trans,
}; };
int mt7615_mcu_sta_update_hdr_trans(struct mt7615_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
struct wtbl_req_hdr *wtbl_hdr;
struct sk_buff *skb = NULL;
wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,
WTBL_SET, NULL, &skb);
if (IS_ERR(wtbl_hdr))
return PTR_ERR(wtbl_hdr);
mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, &msta->wcid, NULL, wtbl_hdr);
return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_WTBL_UPDATE,
true);
}
static int static int
mt7615_mcu_uni_ctrl_pm_state(struct mt7615_dev *dev, int band, int state) mt7615_mcu_uni_ctrl_pm_state(struct mt7615_dev *dev, int band, int state)
{ {
...@@ -1280,7 +1306,7 @@ mt7615_mcu_uni_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif, ...@@ -1280,7 +1306,7 @@ mt7615_mcu_uni_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable) struct ieee80211_sta *sta, bool enable)
{ {
return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable, return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,
MCU_UNI_CMD_STA_REC_UPDATE); MCU_UNI_CMD_STA_REC_UPDATE, true);
} }
static int static int
...@@ -1338,6 +1364,18 @@ mt7615_mcu_uni_rx_ba(struct mt7615_dev *dev, ...@@ -1338,6 +1364,18 @@ mt7615_mcu_uni_rx_ba(struct mt7615_dev *dev,
MCU_UNI_CMD_STA_REC_UPDATE, true); MCU_UNI_CMD_STA_REC_UPDATE, true);
} }
static int
mt7615_mcu_sta_uni_update_hdr_trans(struct mt7615_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
return mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76,
vif, &msta->wcid,
MCU_UNI_CMD_STA_REC_UPDATE);
}
static const struct mt7615_mcu_ops uni_update_ops = { static const struct mt7615_mcu_ops uni_update_ops = {
.add_beacon_offload = mt7615_mcu_uni_add_beacon_offload, .add_beacon_offload = mt7615_mcu_uni_add_beacon_offload,
.set_pm_state = mt7615_mcu_uni_ctrl_pm_state, .set_pm_state = mt7615_mcu_uni_ctrl_pm_state,
...@@ -1348,6 +1386,7 @@ static const struct mt7615_mcu_ops uni_update_ops = { ...@@ -1348,6 +1386,7 @@ static const struct mt7615_mcu_ops uni_update_ops = {
.sta_add = mt7615_mcu_uni_add_sta, .sta_add = mt7615_mcu_uni_add_sta,
.set_drv_ctrl = mt7615_mcu_lp_drv_pmctrl, .set_drv_ctrl = mt7615_mcu_lp_drv_pmctrl,
.set_fw_ctrl = mt7615_mcu_fw_pmctrl, .set_fw_ctrl = mt7615_mcu_fw_pmctrl,
.set_sta_decap_offload = mt7615_mcu_sta_uni_update_hdr_trans,
}; };
int mt7615_mcu_restart(struct mt76_dev *dev) int mt7615_mcu_restart(struct mt76_dev *dev)
...@@ -2322,14 +2361,12 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd) ...@@ -2322,14 +2361,12 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true); return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
} }
int mt7615_mcu_get_temperature(struct mt7615_dev *dev, int index) int mt7615_mcu_get_temperature(struct mt7615_dev *dev)
{ {
struct { struct {
u8 action; u8 action;
u8 rsv[3]; u8 rsv[3];
} req = { } req = {};
.action = index,
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_GET_TEMP, &req, return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_GET_TEMP, &req,
sizeof(req), true); sizeof(req), true);
......
...@@ -229,7 +229,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base, ...@@ -229,7 +229,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
GFP_KERNEL); GFP_KERNEL);
if (!bus_ops) { if (!bus_ops) {
ret = -ENOMEM; ret = -ENOMEM;
goto error; goto err_free_dev;
} }
bus_ops->rr = mt7615_rr; bus_ops->rr = mt7615_rr;
...@@ -242,17 +242,20 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base, ...@@ -242,17 +242,20 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
ret = devm_request_irq(mdev->dev, irq, mt7615_irq_handler, ret = devm_request_irq(mdev->dev, irq, mt7615_irq_handler,
IRQF_SHARED, KBUILD_MODNAME, dev); IRQF_SHARED, KBUILD_MODNAME, dev);
if (ret) if (ret)
goto error; goto err_free_dev;
if (is_mt7663(mdev)) if (is_mt7663(mdev))
mt76_wr(dev, MT_PCIE_IRQ_ENABLE, 1); mt76_wr(dev, MT_PCIE_IRQ_ENABLE, 1);
ret = mt7615_register_device(dev); ret = mt7615_register_device(dev);
if (ret) if (ret)
goto error; goto err_free_irq;
return 0; return 0;
error:
err_free_irq:
devm_free_irq(pdev, irq, dev);
err_free_dev:
mt76_free_device(&dev->mt76); mt76_free_device(&dev->mt76);
return ret; return ret;
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
MT7615_MAX_INTERFACES) MT7615_MAX_INTERFACES)
#define MT7615_PM_TIMEOUT (HZ / 12) #define MT7615_PM_TIMEOUT (HZ / 12)
#define MT7615_WATCHDOG_TIME (HZ / 10)
#define MT7615_HW_SCAN_TIMEOUT (HZ / 10) #define MT7615_HW_SCAN_TIMEOUT (HZ / 10)
#define MT7615_RESET_TIMEOUT (30 * HZ) #define MT7615_RESET_TIMEOUT (30 * HZ)
#define MT7615_RATE_RETRY 2 #define MT7615_RATE_RETRY 2
...@@ -202,6 +201,7 @@ struct mt7615_phy { ...@@ -202,6 +201,7 @@ struct mt7615_phy {
#define mt7615_mcu_set_pm(dev, ...) (dev)->mcu_ops->set_pm_state((dev), __VA_ARGS__) #define mt7615_mcu_set_pm(dev, ...) (dev)->mcu_ops->set_pm_state((dev), __VA_ARGS__)
#define mt7615_mcu_set_drv_ctrl(dev) (dev)->mcu_ops->set_drv_ctrl((dev)) #define mt7615_mcu_set_drv_ctrl(dev) (dev)->mcu_ops->set_drv_ctrl((dev))
#define mt7615_mcu_set_fw_ctrl(dev) (dev)->mcu_ops->set_fw_ctrl((dev)) #define mt7615_mcu_set_fw_ctrl(dev) (dev)->mcu_ops->set_fw_ctrl((dev))
#define mt7615_mcu_set_sta_decap_offload(dev, ...) (dev)->mcu_ops->set_sta_decap_offload((dev), __VA_ARGS__)
struct mt7615_mcu_ops { struct mt7615_mcu_ops {
int (*add_tx_ba)(struct mt7615_dev *dev, int (*add_tx_ba)(struct mt7615_dev *dev,
struct ieee80211_ampdu_params *params, struct ieee80211_ampdu_params *params,
...@@ -221,6 +221,9 @@ struct mt7615_mcu_ops { ...@@ -221,6 +221,9 @@ struct mt7615_mcu_ops {
int (*set_pm_state)(struct mt7615_dev *dev, int band, int state); int (*set_pm_state)(struct mt7615_dev *dev, int band, int state);
int (*set_drv_ctrl)(struct mt7615_dev *dev); int (*set_drv_ctrl)(struct mt7615_dev *dev);
int (*set_fw_ctrl)(struct mt7615_dev *dev); int (*set_fw_ctrl)(struct mt7615_dev *dev);
int (*set_sta_decap_offload)(struct mt7615_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
}; };
struct mt7615_dev { struct mt7615_dev {
...@@ -356,6 +359,7 @@ static inline int mt7622_wmac_init(struct mt7615_dev *dev) ...@@ -356,6 +359,7 @@ static inline int mt7622_wmac_init(struct mt7615_dev *dev)
} }
#endif #endif
int mt7615_thermal_init(struct mt7615_dev *dev);
int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base, int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
int irq, const u32 *map); int irq, const u32 *map);
u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr); u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr);
...@@ -456,6 +460,12 @@ static inline u32 mt7615_tx_mcu_int_mask(struct mt7615_dev *dev) ...@@ -456,6 +460,12 @@ static inline u32 mt7615_tx_mcu_int_mask(struct mt7615_dev *dev)
return MT_INT_TX_DONE(dev->mt76.q_mcu[MT_MCUQ_WM]->hw_idx); return MT_INT_TX_DONE(dev->mt76.q_mcu[MT_MCUQ_WM]->hw_idx);
} }
static inline unsigned long
mt7615_get_macwork_timeout(struct mt7615_dev *dev)
{
return dev->pm.enable ? HZ / 3 : HZ / 10;
}
void mt7615_dma_reset(struct mt7615_dev *dev); void mt7615_dma_reset(struct mt7615_dev *dev);
void mt7615_scan_work(struct work_struct *work); void mt7615_scan_work(struct work_struct *work);
void mt7615_roc_work(struct work_struct *work); void mt7615_roc_work(struct work_struct *work);
...@@ -466,7 +476,7 @@ int mt7615_set_channel(struct mt7615_phy *phy); ...@@ -466,7 +476,7 @@ int mt7615_set_channel(struct mt7615_phy *phy);
void mt7615_init_work(struct mt7615_dev *dev); void mt7615_init_work(struct mt7615_dev *dev);
int mt7615_mcu_restart(struct mt76_dev *dev); int mt7615_mcu_restart(struct mt76_dev *dev);
void mt7615_update_channel(struct mt76_dev *mdev); void mt7615_update_channel(struct mt76_phy *mphy);
bool mt7615_mac_wtbl_update(struct mt7615_dev *dev, int idx, u32 mask); bool mt7615_mac_wtbl_update(struct mt7615_dev *dev, int idx, u32 mask);
void mt7615_mac_reset_counters(struct mt7615_dev *dev); void mt7615_mac_reset_counters(struct mt7615_dev *dev);
void mt7615_mac_cca_stats_reset(struct mt7615_phy *phy); void mt7615_mac_cca_stats_reset(struct mt7615_phy *phy);
...@@ -494,7 +504,7 @@ u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg); ...@@ -494,7 +504,7 @@ u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg);
int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val); int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val);
int mt7615_mcu_set_dbdc(struct mt7615_dev *dev); int mt7615_mcu_set_dbdc(struct mt7615_dev *dev);
int mt7615_mcu_set_eeprom(struct mt7615_dev *dev); int mt7615_mcu_set_eeprom(struct mt7615_dev *dev);
int mt7615_mcu_get_temperature(struct mt7615_dev *dev, int index); int mt7615_mcu_get_temperature(struct mt7615_dev *dev);
int mt7615_mcu_set_tx_power(struct mt7615_phy *phy); int mt7615_mcu_set_tx_power(struct mt7615_phy *phy);
void mt7615_mcu_exit(struct mt7615_dev *dev); void mt7615_mcu_exit(struct mt7615_dev *dev);
void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb, void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
...@@ -518,9 +528,6 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, ...@@ -518,9 +528,6 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
void mt7615_mac_work(struct work_struct *work); void mt7615_mac_work(struct work_struct *work);
void mt7615_txp_skb_unmap(struct mt76_dev *dev, void mt7615_txp_skb_unmap(struct mt76_dev *dev,
struct mt76_txwi_cache *txwi); struct mt76_txwi_cache *txwi);
int mt7615_mcu_sta_update_hdr_trans(struct mt7615_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int mt7615_mcu_set_rx_hdr_trans_blacklist(struct mt7615_dev *dev); int mt7615_mcu_set_rx_hdr_trans_blacklist(struct mt7615_dev *dev);
int mt7615_mcu_set_fcc5_lpn(struct mt7615_dev *dev, int val); int mt7615_mcu_set_fcc5_lpn(struct mt7615_dev *dev, int val);
int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev, int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev,
......
...@@ -98,7 +98,7 @@ mt7615_led_set_config(struct led_classdev *led_cdev, ...@@ -98,7 +98,7 @@ mt7615_led_set_config(struct led_classdev *led_cdev,
addr = mt7615_reg_map(dev, MT_LED_CTRL); addr = mt7615_reg_map(dev, MT_LED_CTRL);
mt76_wr(dev, addr, val); mt76_wr(dev, addr, val);
mt76_connac_pm_unref(&dev->pm); mt76_connac_pm_unref(&dev->mphy, &dev->pm);
} }
static int static int
...@@ -147,8 +147,12 @@ int mt7615_register_device(struct mt7615_dev *dev) ...@@ -147,8 +147,12 @@ int mt7615_register_device(struct mt7615_dev *dev)
if (ret) if (ret)
return ret; return ret;
ret = mt76_register_device(&dev->mt76, true, mt7615_rates, ret = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt7615_rates)); ARRAY_SIZE(mt76_rates));
if (ret)
return ret;
ret = mt7615_thermal_init(dev);
if (ret) if (ret)
return ret; return ret;
......
...@@ -131,20 +131,21 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, ...@@ -131,20 +131,21 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct mt76_tx_info *tx_info) struct mt76_tx_info *tx_info)
{ {
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
struct ieee80211_key_conf *key = info->control.hw_key; struct ieee80211_key_conf *key = info->control.hw_key;
int pid, id; int pid, id;
u8 *txwi = (u8 *)txwi_ptr; u8 *txwi = (u8 *)txwi_ptr;
struct mt76_txwi_cache *t; struct mt76_txwi_cache *t;
struct mt7615_sta *msta;
void *txp; void *txp;
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
if (!wcid) if (!wcid)
wcid = &dev->mt76.global_wcid; wcid = &dev->mt76.global_wcid;
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) {
struct mt7615_phy *phy = &dev->phy; struct mt7615_phy *phy = &dev->phy;
if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && mdev->phy2) if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && mdev->phy2)
...@@ -267,6 +268,7 @@ void mt7615_mac_reset_work(struct work_struct *work) ...@@ -267,6 +268,7 @@ void mt7615_mac_reset_work(struct work_struct *work)
struct mt7615_phy *phy2; struct mt7615_phy *phy2;
struct mt76_phy *ext_phy; struct mt76_phy *ext_phy;
struct mt7615_dev *dev; struct mt7615_dev *dev;
unsigned long timeout;
dev = container_of(work, struct mt7615_dev, reset_work); dev = container_of(work, struct mt7615_dev, reset_work);
ext_phy = dev->mt76.phy2; ext_phy = dev->mt76.phy2;
...@@ -344,11 +346,11 @@ void mt7615_mac_reset_work(struct work_struct *work) ...@@ -344,11 +346,11 @@ void mt7615_mac_reset_work(struct work_struct *work)
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
timeout = mt7615_get_macwork_timeout(dev);
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work, ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
MT7615_WATCHDOG_TIME); timeout);
if (phy2) if (phy2)
ieee80211_queue_delayed_work(ext_phy->hw, ieee80211_queue_delayed_work(ext_phy->hw,
&phy2->mt76->mac_work, &phy2->mt76->mac_work, timeout);
MT7615_WATCHDOG_TIME);
} }
...@@ -463,7 +463,9 @@ enum mt7615_reg_base { ...@@ -463,7 +463,9 @@ enum mt7615_reg_base {
#define MT_LPON_TCR0(_n) MT_LPON(0x010 + ((_n) * 4)) #define MT_LPON_TCR0(_n) MT_LPON(0x010 + ((_n) * 4))
#define MT_LPON_TCR2(_n) MT_LPON(0x0f8 + ((_n) - 2) * 4) #define MT_LPON_TCR2(_n) MT_LPON(0x0f8 + ((_n) - 2) * 4)
#define MT_LPON_TCR_MODE GENMASK(1, 0) #define MT_LPON_TCR_MODE GENMASK(1, 0)
#define MT_LPON_TCR_READ GENMASK(1, 0)
#define MT_LPON_TCR_WRITE BIT(0) #define MT_LPON_TCR_WRITE BIT(0)
#define MT_LPON_TCR_ADJUST BIT(1)
#define MT_LPON_UTTR0 MT_LPON(0x018) #define MT_LPON_UTTR0 MT_LPON(0x018)
#define MT_LPON_UTTR1 MT_LPON(0x01c) #define MT_LPON_UTTR1 MT_LPON(0x01c)
......
// SPDX-License-Identifier: ISC /* SPDX-License-Identifier: ISC */
/* Copyright (C) 2020 MediaTek Inc. /* Copyright (C) 2020 MediaTek Inc.
* *
* Author: Sean Wang <sean.wang@mediatek.com> * Author: Sean Wang <sean.wang@mediatek.com>
......
...@@ -55,6 +55,7 @@ static int __mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev) ...@@ -55,6 +55,7 @@ static int __mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev)
{ {
struct sdio_func *func = dev->mt76.sdio.func; struct sdio_func *func = dev->mt76.sdio.func;
struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_phy *mphy = &dev->mt76.phy;
struct mt76_connac_pm *pm = &dev->pm;
u32 status; u32 status;
int ret; int ret;
...@@ -66,37 +67,45 @@ static int __mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev) ...@@ -66,37 +67,45 @@ static int __mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev)
status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000); status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000);
if (ret < 0) { if (ret < 0) {
dev_err(dev->mt76.dev, "Cannot get ownership from device"); dev_err(dev->mt76.dev, "Cannot get ownership from device");
set_bit(MT76_STATE_PM, &mphy->state); } else {
sdio_release_host(func); clear_bit(MT76_STATE_PM, &mphy->state);
return ret; pm->stats.last_wake_event = jiffies;
pm->stats.doze_time += pm->stats.last_wake_event -
pm->stats.last_doze_event;
} }
sdio_release_host(func); sdio_release_host(func);
dev->pm.last_activity = jiffies;
return 0; return ret;
} }
static int mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev) static int mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev)
{ {
struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_phy *mphy = &dev->mt76.phy;
int ret = 0;
if (test_and_clear_bit(MT76_STATE_PM, &mphy->state)) mutex_lock(&dev->pm.mutex);
return __mt7663s_mcu_drv_pmctrl(dev);
return 0; if (test_bit(MT76_STATE_PM, &mphy->state))
ret = __mt7663s_mcu_drv_pmctrl(dev);
mutex_unlock(&dev->pm.mutex);
return ret;
} }
static int mt7663s_mcu_fw_pmctrl(struct mt7615_dev *dev) static int mt7663s_mcu_fw_pmctrl(struct mt7615_dev *dev)
{ {
struct sdio_func *func = dev->mt76.sdio.func; struct sdio_func *func = dev->mt76.sdio.func;
struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_phy *mphy = &dev->mt76.phy;
struct mt76_connac_pm *pm = &dev->pm;
int ret = 0;
u32 status; u32 status;
int ret;
if (test_and_set_bit(MT76_STATE_PM, &mphy->state)) mutex_lock(&pm->mutex);
return 0;
if (mt76_connac_skip_fw_pmctrl(mphy, pm))
goto out;
sdio_claim_host(func); sdio_claim_host(func);
...@@ -107,9 +116,15 @@ static int mt7663s_mcu_fw_pmctrl(struct mt7615_dev *dev) ...@@ -107,9 +116,15 @@ static int mt7663s_mcu_fw_pmctrl(struct mt7615_dev *dev)
if (ret < 0) { if (ret < 0) {
dev_err(dev->mt76.dev, "Cannot set ownership to device"); dev_err(dev->mt76.dev, "Cannot set ownership to device");
clear_bit(MT76_STATE_PM, &mphy->state); clear_bit(MT76_STATE_PM, &mphy->state);
} else {
pm->stats.last_doze_event = jiffies;
pm->stats.awake_time += pm->stats.last_doze_event -
pm->stats.last_wake_event;
} }
sdio_release_host(func); sdio_release_host(func);
out:
mutex_unlock(&pm->mutex);
return ret; return ret;
} }
......
...@@ -283,9 +283,15 @@ void mt7663s_txrx_worker(struct mt76_worker *w) ...@@ -283,9 +283,15 @@ void mt7663s_txrx_worker(struct mt76_worker *w)
{ {
struct mt76_sdio *sdio = container_of(w, struct mt76_sdio, struct mt76_sdio *sdio = container_of(w, struct mt76_sdio,
txrx_worker); txrx_worker);
struct mt76_dev *dev = container_of(sdio, struct mt76_dev, sdio); struct mt76_dev *mdev = container_of(sdio, struct mt76_dev, sdio);
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
int i, nframes, ret; int i, nframes, ret;
if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
queue_work(mdev->wq, &dev->pm.wake_work);
return;
}
/* disable interrupt */ /* disable interrupt */
sdio_claim_host(sdio->func); sdio_claim_host(sdio->func);
sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL); sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
...@@ -295,16 +301,16 @@ void mt7663s_txrx_worker(struct mt76_worker *w) ...@@ -295,16 +301,16 @@ void mt7663s_txrx_worker(struct mt76_worker *w)
/* tx */ /* tx */
for (i = 0; i <= MT_TXQ_PSD; i++) { for (i = 0; i <= MT_TXQ_PSD; i++) {
ret = mt7663s_tx_run_queue(dev, dev->phy.q_tx[i]); ret = mt7663s_tx_run_queue(mdev, mdev->phy.q_tx[i]);
if (ret > 0) if (ret > 0)
nframes += ret; nframes += ret;
} }
ret = mt7663s_tx_run_queue(dev, dev->q_mcu[MT_MCUQ_WM]); ret = mt7663s_tx_run_queue(mdev, mdev->q_mcu[MT_MCUQ_WM]);
if (ret > 0) if (ret > 0)
nframes += ret; nframes += ret;
/* rx */ /* rx */
ret = mt7663s_rx_handler(dev); ret = mt7663s_rx_handler(mdev);
if (ret > 0) if (ret > 0)
nframes += ret; nframes += ret;
} while (nframes > 0); } while (nframes > 0);
...@@ -312,6 +318,8 @@ void mt7663s_txrx_worker(struct mt76_worker *w) ...@@ -312,6 +318,8 @@ void mt7663s_txrx_worker(struct mt76_worker *w)
/* enable interrupt */ /* enable interrupt */
sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL); sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
sdio_release_host(sdio->func); sdio_release_host(sdio->func);
mt76_connac_pm_unref(&dev->mphy, &dev->pm);
} }
void mt7663s_sdio_irq(struct sdio_func *func) void mt7663s_sdio_irq(struct sdio_func *func)
......
...@@ -123,7 +123,7 @@ static int mt7663_usb_sdio_set_rates(struct mt7615_dev *dev, ...@@ -123,7 +123,7 @@ static int mt7663_usb_sdio_set_rates(struct mt7615_dev *dev,
idx = idx > HW_BSSID_MAX ? HW_BSSID_0 : idx; idx = idx > HW_BSSID_MAX ? HW_BSSID_0 : idx;
addr = idx > 1 ? MT_LPON_TCR2(idx): MT_LPON_TCR0(idx); addr = idx > 1 ? MT_LPON_TCR2(idx): MT_LPON_TCR0(idx);
mt76_set(dev, addr, MT_LPON_TCR_MODE); /* TSF read */ mt76_rmw(dev, addr, MT_LPON_TCR_MODE, MT_LPON_TCR_READ); /* TSF read */
val = mt76_rr(dev, MT_LPON_UTTR0); val = mt76_rr(dev, MT_LPON_UTTR0);
sta->rate_set_tsf = (val & ~BIT(0)) | rate->rateset; sta->rate_set_tsf = (val & ~BIT(0)) | rate->rateset;
...@@ -191,14 +191,15 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, ...@@ -191,14 +191,15 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct mt76_tx_info *tx_info) struct mt76_tx_info *tx_info)
{ {
struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid);
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
struct sk_buff *skb = tx_info->skb; struct sk_buff *skb = tx_info->skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct mt7615_sta *msta;
int pad; int pad;
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
!msta->rate_probe) { msta && !msta->rate_probe) {
/* request to configure sampling rate */ /* request to configure sampling rate */
spin_lock_bh(&dev->mt76.lock); spin_lock_bh(&dev->mt76.lock);
mt7615_mac_set_rates(&dev->phy, msta, &info->control.rates[0], mt7615_mac_set_rates(&dev->phy, msta, &info->control.rates[0],
...@@ -323,8 +324,8 @@ int mt7663_usb_sdio_register_device(struct mt7615_dev *dev) ...@@ -323,8 +324,8 @@ int mt7663_usb_sdio_register_device(struct mt7615_dev *dev)
hw->max_tx_fragments = 1; hw->max_tx_fragments = 1;
} }
err = mt76_register_device(&dev->mt76, true, mt7615_rates, err = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt7615_rates)); ARRAY_SIZE(mt76_rates));
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -7,12 +7,13 @@ ...@@ -7,12 +7,13 @@
#include "mt76.h" #include "mt76.h"
#define MT76_CONNAC_SCAN_IE_LEN 600 #define MT76_CONNAC_SCAN_IE_LEN 600
#define MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL 10 #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_SCHED_SCAN_SSID 10
#define MT76_CONNAC_MAX_SCAN_MATCH 16 #define MT76_CONNAC_MAX_SCAN_MATCH 16
#define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20) #define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20)
#define MT76_CONNAC_COREDUMP_SZ (128 * 1024) #define MT76_CONNAC_COREDUMP_SZ (1300 * 1024)
enum { enum {
CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20, CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20,
...@@ -45,6 +46,8 @@ enum { ...@@ -45,6 +46,8 @@ enum {
struct mt76_connac_pm { struct mt76_connac_pm {
bool enable; bool enable;
bool ds_enable;
bool suspended;
spinlock_t txq_lock; spinlock_t txq_lock;
struct { struct {
...@@ -116,19 +119,27 @@ mt76_connac_pm_ref(struct mt76_phy *phy, struct mt76_connac_pm *pm) ...@@ -116,19 +119,27 @@ mt76_connac_pm_ref(struct mt76_phy *phy, struct mt76_connac_pm *pm)
} }
static inline void static inline void
mt76_connac_pm_unref(struct mt76_connac_pm *pm) mt76_connac_pm_unref(struct mt76_phy *phy, struct mt76_connac_pm *pm)
{ {
spin_lock_bh(&pm->wake.lock); spin_lock_bh(&pm->wake.lock);
pm->wake.count--;
pm->last_activity = jiffies; 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); spin_unlock_bh(&pm->wake.lock);
} }
static inline bool static inline bool
mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm) mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm)
{ {
struct mt76_dev *dev = phy->dev;
bool ret; bool ret;
if (dev->token_count)
return true;
spin_lock_bh(&pm->wake.lock); spin_lock_bh(&pm->wake.lock);
ret = pm->wake.count || test_and_set_bit(MT76_STATE_PM, &phy->state); ret = pm->wake.count || test_and_set_bit(MT76_STATE_PM, &phy->state);
spin_unlock_bh(&pm->wake.lock); spin_unlock_bh(&pm->wake.lock);
......
...@@ -10,13 +10,16 @@ int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm) ...@@ -10,13 +10,16 @@ int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)
if (!pm->enable) if (!pm->enable)
return 0; return 0;
if (!mt76_is_mmio(dev)) if (mt76_is_usb(dev))
return 0; return 0;
cancel_delayed_work_sync(&pm->ps_work); cancel_delayed_work_sync(&pm->ps_work);
if (!test_bit(MT76_STATE_PM, &phy->state)) if (!test_bit(MT76_STATE_PM, &phy->state))
return 0; return 0;
if (pm->suspended)
return 0;
queue_work(dev->wq, &pm->wake_work); queue_work(dev->wq, &pm->wake_work);
if (!wait_event_timeout(pm->wait, if (!wait_event_timeout(pm->wait,
!test_bit(MT76_STATE_PM, &phy->state), !test_bit(MT76_STATE_PM, &phy->state),
...@@ -34,12 +37,15 @@ void mt76_connac_power_save_sched(struct mt76_phy *phy, ...@@ -34,12 +37,15 @@ void mt76_connac_power_save_sched(struct mt76_phy *phy,
{ {
struct mt76_dev *dev = phy->dev; struct mt76_dev *dev = phy->dev;
if (!mt76_is_mmio(dev)) if (mt76_is_usb(dev))
return; return;
if (!pm->enable) if (!pm->enable)
return; return;
if (pm->suspended)
return;
pm->last_activity = jiffies; pm->last_activity = jiffies;
if (!test_bit(MT76_STATE_PM, &phy->state)) { if (!test_bit(MT76_STATE_PM, &phy->state)) {
......
...@@ -559,6 +559,7 @@ enum { ...@@ -559,6 +559,7 @@ enum {
MCU_CMD_SET_RATE_TX_POWER = MCU_CE_PREFIX | 0x5d, MCU_CMD_SET_RATE_TX_POWER = MCU_CE_PREFIX | 0x5d,
MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61, MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61,
MCU_CMD_SCHED_SCAN_REQ = MCU_CE_PREFIX | 0x62, MCU_CMD_SCHED_SCAN_REQ = MCU_CE_PREFIX | 0x62,
MCU_CMD_GET_NIC_CAPAB = MCU_CE_PREFIX | 0x8a,
MCU_CMD_REG_WRITE = MCU_CE_PREFIX | 0xc0, MCU_CMD_REG_WRITE = MCU_CE_PREFIX | 0xc0,
MCU_CMD_REG_READ = MCU_CE_PREFIX | MCU_QUERY_MASK | 0xc0, MCU_CMD_REG_READ = MCU_CE_PREFIX | MCU_QUERY_MASK | 0xc0,
MCU_CMD_CHIP_CONFIG = MCU_CE_PREFIX | 0xca, MCU_CMD_CHIP_CONFIG = MCU_CE_PREFIX | 0xca,
...@@ -575,6 +576,7 @@ enum { ...@@ -575,6 +576,7 @@ enum {
enum { enum {
UNI_BSS_INFO_BASIC = 0, UNI_BSS_INFO_BASIC = 0,
UNI_BSS_INFO_RLM = 2, UNI_BSS_INFO_RLM = 2,
UNI_BSS_INFO_BSS_COLOR = 4,
UNI_BSS_INFO_HE_BASIC = 5, UNI_BSS_INFO_HE_BASIC = 5,
UNI_BSS_INFO_BCN_CONTENT = 7, UNI_BSS_INFO_BCN_CONTENT = 7,
UNI_BSS_INFO_QBSS = 15, UNI_BSS_INFO_QBSS = 15,
...@@ -590,6 +592,36 @@ enum { ...@@ -590,6 +592,36 @@ enum {
UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT, UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
}; };
enum {
MT_NIC_CAP_TX_RESOURCE,
MT_NIC_CAP_TX_EFUSE_ADDR,
MT_NIC_CAP_COEX,
MT_NIC_CAP_SINGLE_SKU,
MT_NIC_CAP_CSUM_OFFLOAD,
MT_NIC_CAP_HW_VER,
MT_NIC_CAP_SW_VER,
MT_NIC_CAP_MAC_ADDR,
MT_NIC_CAP_PHY,
MT_NIC_CAP_MAC,
MT_NIC_CAP_FRAME_BUF,
MT_NIC_CAP_BEAM_FORM,
MT_NIC_CAP_LOCATION,
MT_NIC_CAP_MUMIMO,
MT_NIC_CAP_BUFFER_MODE_INFO,
MT_NIC_CAP_HW_ADIE_VERSION = 0x14,
MT_NIC_CAP_ANTSWP = 0x16,
MT_NIC_CAP_WFDMA_REALLOC,
MT_NIC_CAP_6G,
};
#define UNI_WOW_DETECT_TYPE_MAGIC BIT(0)
#define UNI_WOW_DETECT_TYPE_ANY BIT(1)
#define UNI_WOW_DETECT_TYPE_DISCONNECT BIT(2)
#define UNI_WOW_DETECT_TYPE_GTK_REKEY_FAIL BIT(3)
#define UNI_WOW_DETECT_TYPE_BCN_LOST BIT(4)
#define UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT BIT(5)
#define UNI_WOW_DETECT_TYPE_BITMAP BIT(6)
enum { enum {
UNI_SUSPEND_MODE_SETTING, UNI_SUSPEND_MODE_SETTING,
UNI_SUSPEND_WOW_CTRL, UNI_SUSPEND_WOW_CTRL,
...@@ -762,7 +794,7 @@ struct mt76_connac_sched_scan_req { ...@@ -762,7 +794,7 @@ struct mt76_connac_sched_scan_req {
u8 intervals_num; u8 intervals_num;
u8 scan_func; /* MT7663: BIT(0) eable random mac address */ u8 scan_func; /* MT7663: BIT(0) eable random mac address */
struct mt76_connac_mcu_scan_channel channels[64]; struct mt76_connac_mcu_scan_channel channels[64];
__le16 intervals[MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL]; __le16 intervals[MT76_CONNAC_MAX_NUM_SCHED_SCAN_INTERVAL];
union { union {
struct { struct {
u8 random_mac[ETH_ALEN]; u8 random_mac[ETH_ALEN];
...@@ -770,7 +802,9 @@ struct mt76_connac_sched_scan_req { ...@@ -770,7 +802,9 @@ struct mt76_connac_sched_scan_req {
} mt7663; } mt7663;
struct { struct {
u8 bss_idx; u8 bss_idx;
u8 pad2[63]; u8 pad2[19];
u8 random_mac[ETH_ALEN];
u8 pad3[38];
} mt7921; } mt7921;
}; };
} __packed; } __packed;
...@@ -781,6 +815,14 @@ struct mt76_connac_sched_scan_done { ...@@ -781,6 +815,14 @@ struct mt76_connac_sched_scan_done {
__le16 pad; __le16 pad;
} __packed; } __packed;
struct bss_info_uni_bss_color {
__le16 tag;
__le16 len;
u8 enable;
u8 bss_color;
u8 rsv[2];
} __packed;
struct bss_info_uni_he { struct bss_info_uni_he {
__le16 tag; __le16 tag;
__le16 len; __le16 len;
...@@ -885,15 +927,24 @@ struct mt76_connac_suspend_tlv { ...@@ -885,15 +927,24 @@ struct mt76_connac_suspend_tlv {
u8 pad[5]; u8 pad[5];
} __packed; } __packed;
enum mt76_sta_info_state {
MT76_STA_INFO_STATE_NONE,
MT76_STA_INFO_STATE_AUTH,
MT76_STA_INFO_STATE_ASSOC
};
struct mt76_sta_cmd_info { struct mt76_sta_cmd_info {
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
struct mt76_wcid *wcid; struct mt76_wcid *wcid;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
bool offload_fw;
bool enable; bool enable;
bool newly;
int cmd; int cmd;
u8 rcpi; u8 rcpi;
u8 state;
}; };
#define MT_SKU_POWER_LIMIT 161 #define MT_SKU_POWER_LIMIT 161
...@@ -963,18 +1014,23 @@ int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy); ...@@ -963,18 +1014,23 @@ int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy);
int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif); int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif);
void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb, void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable); struct ieee80211_sta *sta, bool enable,
bool newly);
void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev, struct sk_buff *skb, void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, void *sta_wtbl, struct ieee80211_sta *sta, void *sta_wtbl,
void *wtbl_tlv); void *wtbl_tlv);
void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb, void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb,
struct ieee80211_vif *vif,
struct mt76_wcid *wcid, struct mt76_wcid *wcid,
void *sta_wtbl, void *wtbl_tlv); void *sta_wtbl, void *wtbl_tlv);
int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev,
struct ieee80211_vif *vif,
struct mt76_wcid *wcid, int cmd);
void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
u8 rcpi); u8 rcpi, u8 state);
void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb, void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
struct ieee80211_sta *sta, void *sta_wtbl, struct ieee80211_sta *sta, void *sta_wtbl,
void *wtbl_tlv); void *wtbl_tlv);
...@@ -996,8 +1052,8 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, ...@@ -996,8 +1052,8 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct mt76_wcid *wcid, struct mt76_wcid *wcid,
bool enable); bool enable);
int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy, int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
struct mt76_sta_cmd_info *info); struct mt76_sta_cmd_info *info);
void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac, void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
struct ieee80211_vif *vif); struct ieee80211_vif *vif);
int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band); int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band);
...@@ -1008,6 +1064,7 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len, ...@@ -1008,6 +1064,7 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
int mt76_connac_mcu_start_patch(struct mt76_dev *dev); int mt76_connac_mcu_start_patch(struct mt76_dev *dev);
int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get); int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get);
int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option); int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option);
int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy);
int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif, int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_scan_request *scan_req); struct ieee80211_scan_request *scan_req);
...@@ -1028,6 +1085,9 @@ int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw, ...@@ -1028,6 +1085,9 @@ int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend); int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend);
void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac, void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
struct ieee80211_vif *vif); struct ieee80211_vif *vif);
int mt76_connac_sta_state_dp(struct mt76_dev *dev,
enum ieee80211_sta_state old_state,
enum ieee80211_sta_state new_state);
int mt76_connac_mcu_chip_config(struct mt76_dev *dev); int mt76_connac_mcu_chip_config(struct mt76_dev *dev);
int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable); int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable);
void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb, void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
......
...@@ -68,7 +68,7 @@ static void mt76x0_set_chip_cap(struct mt76x02_dev *dev) ...@@ -68,7 +68,7 @@ static void mt76x0_set_chip_cap(struct mt76x02_dev *dev)
nic_conf1 &= 0xff00; nic_conf1 &= 0xff00;
if (nic_conf1 & MT_EE_NIC_CONF_1_HW_RF_CTRL) if (nic_conf1 & MT_EE_NIC_CONF_1_HW_RF_CTRL)
dev_err(dev->mt76.dev, dev_dbg(dev->mt76.dev,
"driver does not support HW RF ctrl\n"); "driver does not support HW RF ctrl\n");
if (!mt76x02_field_valid(nic_conf0 >> 8)) if (!mt76x02_field_valid(nic_conf0 >> 8))
......
...@@ -34,24 +34,24 @@ mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data) ...@@ -34,24 +34,24 @@ mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
{ {
memset(key_data, 0, 32); memset(key_data, 0, 32);
if (!key) if (!key)
return MT_CIPHER_NONE; return MT76X02_CIPHER_NONE;
if (key->keylen > 32) if (key->keylen > 32)
return MT_CIPHER_NONE; return MT76X02_CIPHER_NONE;
memcpy(key_data, key->key, key->keylen); memcpy(key_data, key->key, key->keylen);
switch (key->cipher) { switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP40:
return MT_CIPHER_WEP40; return MT76X02_CIPHER_WEP40;
case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_WEP104:
return MT_CIPHER_WEP104; return MT76X02_CIPHER_WEP104;
case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_TKIP:
return MT_CIPHER_TKIP; return MT76X02_CIPHER_TKIP;
case WLAN_CIPHER_SUITE_CCMP: case WLAN_CIPHER_SUITE_CCMP:
return MT_CIPHER_AES_CCMP; return MT76X02_CIPHER_AES_CCMP;
default: default:
return MT_CIPHER_NONE; return MT76X02_CIPHER_NONE;
} }
} }
...@@ -63,7 +63,7 @@ int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx, ...@@ -63,7 +63,7 @@ int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx,
u32 val; u32 val;
cipher = mt76x02_mac_get_key_info(key, key_data); cipher = mt76x02_mac_get_key_info(key, key_data);
if (cipher == MT_CIPHER_NONE && key) if (cipher == MT76X02_CIPHER_NONE && key)
return -EOPNOTSUPP; return -EOPNOTSUPP;
val = mt76_rr(dev, MT_SKEY_MODE(vif_idx)); val = mt76_rr(dev, MT_SKEY_MODE(vif_idx));
...@@ -91,10 +91,10 @@ void mt76x02_mac_wcid_sync_pn(struct mt76x02_dev *dev, u8 idx, ...@@ -91,10 +91,10 @@ void mt76x02_mac_wcid_sync_pn(struct mt76x02_dev *dev, u8 idx,
eiv = mt76_rr(dev, MT_WCID_IV(idx) + 4); eiv = mt76_rr(dev, MT_WCID_IV(idx) + 4);
pn = (u64)eiv << 16; pn = (u64)eiv << 16;
if (cipher == MT_CIPHER_TKIP) { if (cipher == MT76X02_CIPHER_TKIP) {
pn |= (iv >> 16) & 0xff; pn |= (iv >> 16) & 0xff;
pn |= (iv & 0xff) << 8; pn |= (iv & 0xff) << 8;
} else if (cipher >= MT_CIPHER_AES_CCMP) { } else if (cipher >= MT76X02_CIPHER_AES_CCMP) {
pn |= iv & 0xffff; pn |= iv & 0xffff;
} else { } else {
return; return;
...@@ -112,7 +112,7 @@ int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx, ...@@ -112,7 +112,7 @@ int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
u64 pn; u64 pn;
cipher = mt76x02_mac_get_key_info(key, key_data); cipher = mt76x02_mac_get_key_info(key, key_data);
if (cipher == MT_CIPHER_NONE && key) if (cipher == MT76X02_CIPHER_NONE && key)
return -EOPNOTSUPP; return -EOPNOTSUPP;
mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data)); mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data));
...@@ -126,16 +126,16 @@ int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx, ...@@ -126,16 +126,16 @@ int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
pn = atomic64_read(&key->tx_pn); pn = atomic64_read(&key->tx_pn);
iv_data[3] = key->keyidx << 6; iv_data[3] = key->keyidx << 6;
if (cipher >= MT_CIPHER_TKIP) { if (cipher >= MT76X02_CIPHER_TKIP) {
iv_data[3] |= 0x20; iv_data[3] |= 0x20;
put_unaligned_le32(pn >> 16, &iv_data[4]); put_unaligned_le32(pn >> 16, &iv_data[4]);
} }
if (cipher == MT_CIPHER_TKIP) { if (cipher == MT76X02_CIPHER_TKIP) {
iv_data[0] = (pn >> 8) & 0xff; iv_data[0] = (pn >> 8) & 0xff;
iv_data[1] = (iv_data[0] | 0x20) & 0x7f; iv_data[1] = (iv_data[0] | 0x20) & 0x7f;
iv_data[2] = pn & 0xff; iv_data[2] = pn & 0xff;
} else if (cipher >= MT_CIPHER_AES_CCMP) { } else if (cipher >= MT76X02_CIPHER_AES_CCMP) {
put_unaligned_le16((pn & 0xffff), &iv_data[0]); put_unaligned_le16((pn & 0xffff), &iv_data[0]);
} }
} }
...@@ -1022,12 +1022,12 @@ void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot, ...@@ -1022,12 +1022,12 @@ void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot,
mt76_wr(dev, MT_TX_PROT_CFG6 + i * 4, vht_prot[i]); mt76_wr(dev, MT_TX_PROT_CFG6 + i * 4, vht_prot[i]);
} }
void mt76x02_update_channel(struct mt76_dev *mdev) void mt76x02_update_channel(struct mt76_phy *mphy)
{ {
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); struct mt76x02_dev *dev = container_of(mphy->dev, struct mt76x02_dev, mt76);
struct mt76_channel_state *state; struct mt76_channel_state *state;
state = mdev->phy.chan_state; state = mphy->chan_state;
state->cc_busy += mt76_rr(dev, MT_CH_BUSY); state->cc_busy += mt76_rr(dev, MT_CH_BUSY);
spin_lock_bh(&dev->mt76.cc_lock); spin_lock_bh(&dev->mt76.cc_lock);
...@@ -1169,7 +1169,7 @@ void mt76x02_mac_work(struct work_struct *work) ...@@ -1169,7 +1169,7 @@ void mt76x02_mac_work(struct work_struct *work)
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
mt76_update_survey(&dev->mt76); mt76_update_survey(&dev->mphy);
for (i = 0, idx = 0; i < 16; i++) { for (i = 0, idx = 0; i < 16; i++) {
u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i)); u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
......
...@@ -195,7 +195,7 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi, ...@@ -195,7 +195,7 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
struct ieee80211_sta *sta, int len); struct ieee80211_sta *sta, int len);
void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq); void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq);
void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e); void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
void mt76x02_update_channel(struct mt76_dev *mdev); void mt76x02_update_channel(struct mt76_phy *mphy);
void mt76x02_mac_work(struct work_struct *work); void mt76x02_mac_work(struct work_struct *work);
void mt76x02_mac_cc_reset(struct mt76x02_dev *dev); void mt76x02_mac_cc_reset(struct mt76x02_dev *dev);
......
...@@ -692,15 +692,15 @@ struct mt76_wcid_key { ...@@ -692,15 +692,15 @@ struct mt76_wcid_key {
} __packed __aligned(4); } __packed __aligned(4);
enum mt76x02_cipher_type { enum mt76x02_cipher_type {
MT_CIPHER_NONE, MT76X02_CIPHER_NONE,
MT_CIPHER_WEP40, MT76X02_CIPHER_WEP40,
MT_CIPHER_WEP104, MT76X02_CIPHER_WEP104,
MT_CIPHER_TKIP, MT76X02_CIPHER_TKIP,
MT_CIPHER_AES_CCMP, MT76X02_CIPHER_AES_CCMP,
MT_CIPHER_CKIP40, MT76X02_CIPHER_CKIP40,
MT_CIPHER_CKIP104, MT76X02_CIPHER_CKIP104,
MT_CIPHER_CKIP128, MT76X02_CIPHER_CKIP128,
MT_CIPHER_WAPI, MT76X02_CIPHER_WAPI,
}; };
#endif #endif
...@@ -7,24 +7,18 @@ ...@@ -7,24 +7,18 @@
#include <linux/module.h> #include <linux/module.h>
#include "mt76x02.h" #include "mt76x02.h"
#define CCK_RATE(_idx, _rate) { \ #define MT76x02_CCK_RATE(_idx, _rate) { \
.bitrate = _rate, \ .bitrate = _rate, \
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \ .flags = IEEE80211_RATE_SHORT_PREAMBLE, \
.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + (_idx)), \ .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + (_idx)), \
} }
#define OFDM_RATE(_idx, _rate) { \
.bitrate = _rate, \
.hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
}
struct ieee80211_rate mt76x02_rates[] = { struct ieee80211_rate mt76x02_rates[] = {
CCK_RATE(0, 10), MT76x02_CCK_RATE(0, 10),
CCK_RATE(1, 20), MT76x02_CCK_RATE(1, 20),
CCK_RATE(2, 55), MT76x02_CCK_RATE(2, 55),
CCK_RATE(3, 110), MT76x02_CCK_RATE(3, 110),
OFDM_RATE(0, 60), OFDM_RATE(0, 60),
OFDM_RATE(1, 90), OFDM_RATE(1, 90),
OFDM_RATE(2, 120), OFDM_RATE(2, 120),
......
#SPDX-License-Identifier: ISC # SPDX-License-Identifier: ISC
obj-$(CONFIG_MT7915E) += mt7915e.o obj-$(CONFIG_MT7915E) += mt7915e.o
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "mt7915.h" #include "mt7915.h"
#include "eeprom.h" #include "eeprom.h"
#include "mcu.h"
/** global debugfs **/ /** global debugfs **/
...@@ -16,7 +17,7 @@ mt7915_implicit_txbf_set(void *data, u64 val) ...@@ -16,7 +17,7 @@ mt7915_implicit_txbf_set(void *data, u64 val)
dev->ibf = !!val; dev->ibf = !!val;
return mt7915_mcu_set_txbf_type(dev); return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);
} }
static int static int
...@@ -147,6 +148,9 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s) ...@@ -147,6 +148,9 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
{ {
struct mt7915_dev *dev = s->private; struct mt7915_dev *dev = s->private;
bool ext_phy = phy != &dev->phy; bool ext_phy = phy != &dev->phy;
static const char * const bw[] = {
"BW20", "BW40", "BW80", "BW160"
};
int cnt; int cnt;
if (!phy) if (!phy)
...@@ -164,11 +168,16 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s) ...@@ -164,11 +168,16 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
seq_puts(s, "Tx Beamformer Rx feedback statistics: "); seq_puts(s, "Tx Beamformer Rx feedback statistics: ");
cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy)); cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
seq_printf(s, "All: %ld, HE: %ld, VHT: %ld, HT: %ld\n", seq_printf(s, "All: %ld, HE: %ld, VHT: %ld, HT: %ld, ",
FIELD_GET(MT_ETBF_RX_FB_ALL, cnt), FIELD_GET(MT_ETBF_RX_FB_ALL, cnt),
FIELD_GET(MT_ETBF_RX_FB_HE, cnt), FIELD_GET(MT_ETBF_RX_FB_HE, cnt),
FIELD_GET(MT_ETBF_RX_FB_VHT, cnt), FIELD_GET(MT_ETBF_RX_FB_VHT, cnt),
FIELD_GET(MT_ETBF_RX_FB_HT, cnt)); FIELD_GET(MT_ETBF_RX_FB_HT, cnt));
cnt = mt76_rr(dev, MT_ETBF_RX_FB_CONT(ext_phy));
seq_printf(s, "%s, NC: %ld, NR: %ld\n",
bw[FIELD_GET(MT_ETBF_RX_FB_BW, cnt)],
FIELD_GET(MT_ETBF_RX_FB_NC, cnt),
FIELD_GET(MT_ETBF_RX_FB_NR, cnt));
/* Tx Beamformee Rx NDPA & Tx feedback report */ /* Tx Beamformee Rx NDPA & Tx feedback report */
cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy)); cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
...@@ -204,7 +213,7 @@ mt7915_tx_stats_show(struct seq_file *file, void *data) ...@@ -204,7 +213,7 @@ mt7915_tx_stats_show(struct seq_file *file, void *data)
mt7915_txbf_stat_read_phy(mt7915_ext_phy(dev), file); mt7915_txbf_stat_read_phy(mt7915_ext_phy(dev), file);
/* Tx amsdu info */ /* Tx amsdu info */
seq_puts(file, "Tx MSDU stat:\n"); seq_puts(file, "Tx MSDU statistics:\n");
for (i = 0, n = 0; i < ARRAY_SIZE(stat); i++) { for (i = 0, n = 0; i < ARRAY_SIZE(stat); i++) {
stat[i] = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i)); stat[i] = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i));
n += stat[i]; n += stat[i];
...@@ -224,18 +233,6 @@ mt7915_tx_stats_show(struct seq_file *file, void *data) ...@@ -224,18 +233,6 @@ mt7915_tx_stats_show(struct seq_file *file, void *data)
DEFINE_SHOW_ATTRIBUTE(mt7915_tx_stats); DEFINE_SHOW_ATTRIBUTE(mt7915_tx_stats);
static int mt7915_read_temperature(struct seq_file *s, void *data)
{
struct mt7915_dev *dev = dev_get_drvdata(s->private);
int temp;
/* cpu */
temp = mt7915_mcu_get_temperature(dev, 0);
seq_printf(s, "Temperature: %d\n", temp);
return 0;
}
static int static int
mt7915_queues_acq(struct seq_file *s, void *data) mt7915_queues_acq(struct seq_file *s, void *data)
{ {
...@@ -307,54 +304,23 @@ mt7915_puts_rate_txpower(struct seq_file *s, struct mt7915_phy *phy) ...@@ -307,54 +304,23 @@ mt7915_puts_rate_txpower(struct seq_file *s, struct mt7915_phy *phy)
"RU26", "RU52", "RU106", "RU242/SU20", "RU26", "RU52", "RU106", "RU242/SU20",
"RU484/SU40", "RU996/SU80", "RU2x996/SU160" "RU484/SU40", "RU996/SU80", "RU2x996/SU160"
}; };
struct mt7915_dev *dev = dev_get_drvdata(s->private); s8 txpower[MT7915_SKU_RATE_NUM], *buf;
bool ext_phy = phy != &dev->phy; int i;
u32 reg_base;
int i, idx = 0;
if (!phy) if (!phy)
return; return;
reg_base = MT_TMAC_FP0R0(ext_phy); seq_printf(s, "\nBand %d\n", phy != &phy->dev->phy);
seq_printf(s, "\nBand %d\n", ext_phy);
for (i = 0; i < ARRAY_SIZE(mt7915_sku_group_len); i++) { mt7915_mcu_get_txpower_sku(phy, txpower, sizeof(txpower));
u8 cnt, mcs_num = mt7915_sku_group_len[i]; for (i = 0, buf = txpower; i < ARRAY_SIZE(mt7915_sku_group_len); i++) {
s8 txpower[12]; u8 mcs_num = mt7915_sku_group_len[i];
int j;
if (i == SKU_HT_BW20 || i == SKU_HT_BW40) { if (i >= SKU_VHT_BW20 && i <= SKU_VHT_BW160)
mcs_num = 8;
} else if (i >= SKU_VHT_BW20 && i <= SKU_VHT_BW160) {
mcs_num = 10; mcs_num = 10;
} else if (i == SKU_HE_RU26) {
reg_base = MT_TMAC_FP0R18(ext_phy);
idx = 0;
}
for (j = 0, cnt = 0; j < DIV_ROUND_UP(mcs_num, 4); j++) {
u32 val;
if (i == SKU_VHT_BW160 && idx == 60) {
reg_base = MT_TMAC_FP0R15(ext_phy);
idx = 0;
}
val = mt76_rr(dev, reg_base + (idx / 4) * 4);
if (idx && idx % 4)
val >>= (idx % 4) * 8;
while (val > 0 && cnt < mcs_num) {
s8 pwr = FIELD_GET(MT_TMAC_FP_MASK, val);
txpower[cnt++] = pwr;
val >>= 8;
idx++;
}
}
mt76_seq_puts_array(s, sku_group_name[i], txpower, mcs_num); mt76_seq_puts_array(s, sku_group_name[i], buf, mcs_num);
buf += mt7915_sku_group_len[i];
} }
} }
...@@ -390,8 +356,6 @@ int mt7915_init_debugfs(struct mt7915_dev *dev) ...@@ -390,8 +356,6 @@ int mt7915_init_debugfs(struct mt7915_dev *dev)
debugfs_create_file("radar_trigger", 0200, dir, dev, debugfs_create_file("radar_trigger", 0200, dir, dev,
&fops_radar_trigger); &fops_radar_trigger);
debugfs_create_file("ser_trigger", 0200, dir, dev, &fops_ser_trigger); debugfs_create_file("ser_trigger", 0200, dir, dev, &fops_ser_trigger);
debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
mt7915_read_temperature);
debugfs_create_devm_seqfile(dev->mt76.dev, "txpower_sku", dir, debugfs_create_devm_seqfile(dev->mt76.dev, "txpower_sku", dir,
mt7915_read_rate_txpower); mt7915_read_rate_txpower);
......
...@@ -19,39 +19,6 @@ int mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc) ...@@ -19,39 +19,6 @@ int mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc)
return 0; return 0;
} }
void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb)
{
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
__le32 *rxd = (__le32 *)skb->data;
enum rx_pkt_type type;
type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0]));
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
mt7915_mac_tx_free(dev, skb);
break;
case PKT_TYPE_RX_EVENT:
mt7915_mcu_rx_event(dev, skb);
break;
#ifdef CONFIG_NL80211_TESTMODE
case PKT_TYPE_TXRXV:
mt7915_mac_fill_rx_vector(dev, skb);
break;
#endif
case PKT_TYPE_NORMAL:
if (!mt7915_mac_fill_rx(dev, skb)) {
mt76_rx(&dev->mt76, q, skb);
return;
}
fallthrough;
default:
dev_kfree_skb(skb);
break;
}
}
static void static void
mt7915_tx_cleanup(struct mt7915_dev *dev) mt7915_tx_cleanup(struct mt7915_dev *dev)
{ {
...@@ -112,8 +79,6 @@ void mt7915_dma_prefetch(struct mt7915_dev *dev) ...@@ -112,8 +79,6 @@ void mt7915_dma_prefetch(struct mt7915_dev *dev)
int mt7915_dma_init(struct mt7915_dev *dev) int mt7915_dma_init(struct mt7915_dev *dev)
{ {
/* Increase buffer size to receive large VHT/HE MPDUs */
int rx_buf_size = MT_RX_BUF_SIZE * 2;
u32 hif1_ofs = 0; u32 hif1_ofs = 0;
int ret; int ret;
...@@ -177,28 +142,28 @@ int mt7915_dma_init(struct mt7915_dev *dev) ...@@ -177,28 +142,28 @@ int mt7915_dma_init(struct mt7915_dev *dev)
/* event from WM */ /* event from WM */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
MT7915_RXQ_MCU_WM, MT7915_RX_MCU_RING_SIZE, MT7915_RXQ_MCU_WM, MT7915_RX_MCU_RING_SIZE,
rx_buf_size, MT_RX_EVENT_RING_BASE); MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE);
if (ret) if (ret)
return ret; return ret;
/* event from WA */ /* event from WA */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
MT7915_RXQ_MCU_WA, MT7915_RX_MCU_RING_SIZE, MT7915_RXQ_MCU_WA, MT7915_RX_MCU_RING_SIZE,
rx_buf_size, MT_RX_EVENT_RING_BASE); MT_RX_BUF_SIZE, MT_RX_EVENT_RING_BASE);
if (ret) if (ret)
return ret; return ret;
/* rx data queue */ /* rx data queue */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
MT7915_RXQ_BAND0, MT7915_RX_RING_SIZE, MT7915_RXQ_BAND0, MT7915_RX_RING_SIZE,
rx_buf_size, MT_RX_DATA_RING_BASE); MT_RX_BUF_SIZE, MT_RX_DATA_RING_BASE);
if (ret) if (ret)
return ret; return ret;
if (dev->dbdc_support) { if (dev->dbdc_support) {
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT], ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT],
MT7915_RXQ_BAND1, MT7915_RX_RING_SIZE, MT7915_RXQ_BAND1, MT7915_RX_RING_SIZE,
rx_buf_size, MT_RX_BUF_SIZE,
MT_RX_DATA_RING_BASE + hif1_ofs); MT_RX_DATA_RING_BASE + hif1_ofs);
if (ret) if (ret)
return ret; return ret;
...@@ -207,7 +172,7 @@ int mt7915_dma_init(struct mt7915_dev *dev) ...@@ -207,7 +172,7 @@ int mt7915_dma_init(struct mt7915_dev *dev)
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT_WA], ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT_WA],
MT7915_RXQ_MCU_WA_EXT, MT7915_RXQ_MCU_WA_EXT,
MT7915_RX_MCU_RING_SIZE, MT7915_RX_MCU_RING_SIZE,
rx_buf_size, MT_RX_BUF_SIZE,
MT_RX_EVENT_RING_BASE + hif1_ofs); MT_RX_EVENT_RING_BASE + hif1_ofs);
if (ret) if (ret)
return ret; return ret;
......
...@@ -4,22 +4,12 @@ ...@@ -4,22 +4,12 @@
#include "mt7915.h" #include "mt7915.h"
#include "eeprom.h" #include "eeprom.h"
static u32 mt7915_eeprom_read(struct mt7915_dev *dev, u32 offset)
{
u8 *data = dev->mt76.eeprom.data;
if (data[offset] == 0xff && !dev->flash_mode)
mt7915_mcu_get_eeprom(dev, offset);
return data[offset];
}
static int mt7915_eeprom_load_precal(struct mt7915_dev *dev) static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
{ {
struct mt76_dev *mdev = &dev->mt76; struct mt76_dev *mdev = &dev->mt76;
u32 val; u8 *eeprom = mdev->eeprom.data;
u32 val = eeprom[MT_EE_DO_PRE_CAL];
val = mt7915_eeprom_read(dev, MT_EE_DO_PRE_CAL);
if (val != (MT_EE_WIFI_CAL_DPD | MT_EE_WIFI_CAL_GROUP)) if (val != (MT_EE_WIFI_CAL_DPD | MT_EE_WIFI_CAL_GROUP))
return 0; return 0;
...@@ -43,7 +33,13 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev) ...@@ -43,7 +33,13 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
dev->flash_mode = true; dev->flash_mode = true;
ret = mt7915_eeprom_load_precal(dev); ret = mt7915_eeprom_load_precal(dev);
} else { } else {
memset(dev->mt76.eeprom.data, -1, MT7915_EEPROM_SIZE); u32 block_num, i;
block_num = DIV_ROUND_UP(MT7915_EEPROM_SIZE,
MT7915_EEPROM_BLOCK_SIZE);
for (i = 0; i < block_num; i++)
mt7915_mcu_get_eeprom(dev,
i * MT7915_EEPROM_BLOCK_SIZE);
} }
return ret; return ret;
...@@ -52,10 +48,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev) ...@@ -52,10 +48,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
static int mt7915_check_eeprom(struct mt7915_dev *dev) static int mt7915_check_eeprom(struct mt7915_dev *dev)
{ {
u8 *eeprom = dev->mt76.eeprom.data; u8 *eeprom = dev->mt76.eeprom.data;
u16 val; u16 val = get_unaligned_le16(eeprom);
mt7915_eeprom_read(dev, MT_EE_CHIP_ID);
val = get_unaligned_le16(eeprom);
switch (val) { switch (val) {
case 0x7915: case 0x7915:
...@@ -69,9 +62,10 @@ void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) ...@@ -69,9 +62,10 @@ void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
{ {
struct mt7915_dev *dev = phy->dev; struct mt7915_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy; bool ext_phy = phy != &dev->phy;
u8 *eeprom = dev->mt76.eeprom.data;
u32 val; u32 val;
val = mt7915_eeprom_read(dev, MT_EE_WIFI_CONF + ext_phy); val = eeprom[MT_EE_WIFI_CONF + ext_phy];
val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val); val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support)
val = ext_phy ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ; val = ext_phy ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
...@@ -143,6 +137,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev, ...@@ -143,6 +137,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
u8 chain_idx) u8 chain_idx)
{ {
u8 *eeprom = dev->mt76.eeprom.data;
int index, target_power; int index, target_power;
bool tssi_on; bool tssi_on;
...@@ -153,18 +148,18 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev, ...@@ -153,18 +148,18 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
if (chan->band == NL80211_BAND_2GHZ) { if (chan->band == NL80211_BAND_2GHZ) {
index = MT_EE_TX0_POWER_2G + chain_idx * 3; index = MT_EE_TX0_POWER_2G + chain_idx * 3;
target_power = mt7915_eeprom_read(dev, index); target_power = eeprom[index];
if (!tssi_on) if (!tssi_on)
target_power += mt7915_eeprom_read(dev, index + 1); target_power += eeprom[index + 1];
} else { } else {
int group = mt7915_get_channel_group(chan->hw_value); int group = mt7915_get_channel_group(chan->hw_value);
index = MT_EE_TX0_POWER_5G + chain_idx * 12; index = MT_EE_TX0_POWER_5G + chain_idx * 12;
target_power = mt7915_eeprom_read(dev, index + group); target_power = eeprom[index + group];
if (!tssi_on) if (!tssi_on)
target_power += mt7915_eeprom_read(dev, index + 8); target_power += eeprom[index + 8];
} }
return target_power; return target_power;
...@@ -172,13 +167,14 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev, ...@@ -172,13 +167,14 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band) s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band)
{ {
u8 *eeprom = dev->mt76.eeprom.data;
u32 val; u32 val;
s8 delta; s8 delta;
if (band == NL80211_BAND_2GHZ) if (band == NL80211_BAND_2GHZ)
val = mt7915_eeprom_read(dev, MT_EE_RATE_DELTA_2G); val = eeprom[MT_EE_RATE_DELTA_2G];
else else
val = mt7915_eeprom_read(dev, MT_EE_RATE_DELTA_5G); val = eeprom[MT_EE_RATE_DELTA_5G];
if (!(val & MT_EE_RATE_DELTA_EN)) if (!(val & MT_EE_RATE_DELTA_EN))
return 0; return 0;
......
...@@ -33,7 +33,7 @@ enum mt7915_eeprom_field { ...@@ -33,7 +33,7 @@ enum mt7915_eeprom_field {
#define MT_EE_WIFI_CAL_GROUP BIT(0) #define MT_EE_WIFI_CAL_GROUP BIT(0)
#define MT_EE_WIFI_CAL_DPD GENMASK(2, 1) #define MT_EE_WIFI_CAL_DPD GENMASK(2, 1)
#define MT_EE_CAL_UNIT 1024 #define MT_EE_CAL_UNIT 1024
#define MT_EE_CAL_GROUP_SIZE (44 * MT_EE_CAL_UNIT) #define MT_EE_CAL_GROUP_SIZE (49 * MT_EE_CAL_UNIT + 16)
#define MT_EE_CAL_DPD_SIZE (54 * MT_EE_CAL_UNIT) #define MT_EE_CAL_DPD_SIZE (54 * MT_EE_CAL_UNIT)
#define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0) #define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0)
...@@ -99,12 +99,15 @@ static inline bool ...@@ -99,12 +99,15 @@ static inline bool
mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band) mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
{ {
u8 *eep = dev->mt76.eeprom.data; u8 *eep = dev->mt76.eeprom.data;
u8 val = eep[MT_EE_WIFI_CONF + 7];
/* TODO: DBDC */ if (band == NL80211_BAND_2GHZ)
if (band == NL80211_BAND_5GHZ) return val & MT_EE_WIFI_CONF7_TSSI0_2G;
return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF7_TSSI0_5G;
if (dev->dbdc_support)
return val & MT_EE_WIFI_CONF7_TSSI1_5G;
else else
return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF7_TSSI0_2G; return val & MT_EE_WIFI_CONF7_TSSI0_5G;
} }
extern const u8 mt7915_sku_group_len[MAX_SKU_RATE_GROUP_NUM]; extern const u8 mt7915_sku_group_len[MAX_SKU_RATE_GROUP_NUM];
......
...@@ -2,39 +2,14 @@ ...@@ -2,39 +2,14 @@
/* Copyright (C) 2020 MediaTek Inc. */ /* Copyright (C) 2020 MediaTek Inc. */
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/thermal.h>
#include "mt7915.h" #include "mt7915.h"
#include "mac.h" #include "mac.h"
#include "mcu.h" #include "mcu.h"
#include "eeprom.h" #include "eeprom.h"
#define CCK_RATE(_idx, _rate) { \
.bitrate = _rate, \
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \
.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + (_idx)), \
}
#define OFDM_RATE(_idx, _rate) { \
.bitrate = _rate, \
.hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
}
static struct ieee80211_rate mt7915_rates[] = {
CCK_RATE(0, 10),
CCK_RATE(1, 20),
CCK_RATE(2, 55),
CCK_RATE(3, 110),
OFDM_RATE(11, 60),
OFDM_RATE(15, 90),
OFDM_RATE(10, 120),
OFDM_RATE(14, 180),
OFDM_RATE(9, 240),
OFDM_RATE(13, 360),
OFDM_RATE(8, 480),
OFDM_RATE(12, 540),
};
static const struct ieee80211_iface_limit if_limits[] = { static const struct ieee80211_iface_limit if_limits[] = {
{ {
.max = 1, .max = 1,
...@@ -67,6 +42,117 @@ static const struct ieee80211_iface_combination if_comb[] = { ...@@ -67,6 +42,117 @@ static const struct ieee80211_iface_combination if_comb[] = {
} }
}; };
static ssize_t mt7915_thermal_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct mt7915_phy *phy = dev_get_drvdata(dev);
int temperature;
temperature = mt7915_mcu_get_temperature(phy);
if (temperature < 0)
return temperature;
/* display in millidegree celcius */
return sprintf(buf, "%u\n", temperature * 1000);
}
static SENSOR_DEVICE_ATTR(temp1_input, 0444, mt7915_thermal_show_temp,
NULL, 0);
static struct attribute *mt7915_hwmon_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(mt7915_hwmon);
static int
mt7915_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
*state = MT7915_THERMAL_THROTTLE_MAX;
return 0;
}
static int
mt7915_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct mt7915_phy *phy = cdev->devdata;
*state = phy->throttle_state;
return 0;
}
static int
mt7915_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,
unsigned long state)
{
struct mt7915_phy *phy = cdev->devdata;
int ret;
if (state > MT7915_THERMAL_THROTTLE_MAX)
return -EINVAL;
if (state == phy->throttle_state)
return 0;
ret = mt7915_mcu_set_thermal_throttling(phy, state);
if (ret)
return ret;
phy->throttle_state = state;
return 0;
}
static const struct thermal_cooling_device_ops mt7915_thermal_ops = {
.get_max_state = mt7915_thermal_get_max_throttle_state,
.get_cur_state = mt7915_thermal_get_cur_throttle_state,
.set_cur_state = mt7915_thermal_set_cur_throttle_state,
};
static void mt7915_unregister_thermal(struct mt7915_phy *phy)
{
struct wiphy *wiphy = phy->mt76->hw->wiphy;
if (!phy->cdev)
return;
sysfs_remove_link(&wiphy->dev.kobj, "cooling_device");
thermal_cooling_device_unregister(phy->cdev);
}
static int mt7915_thermal_init(struct mt7915_phy *phy)
{
struct wiphy *wiphy = phy->mt76->hw->wiphy;
struct thermal_cooling_device *cdev;
struct device *hwmon;
cdev = thermal_cooling_device_register(wiphy_name(wiphy), phy,
&mt7915_thermal_ops);
if (!IS_ERR(cdev)) {
if (sysfs_create_link(&wiphy->dev.kobj, &cdev->device.kobj,
"cooling_device") < 0)
thermal_cooling_device_unregister(cdev);
else
phy->cdev = cdev;
}
if (!IS_REACHABLE(CONFIG_HWMON))
return 0;
hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev,
wiphy_name(wiphy), phy,
mt7915_hwmon_groups);
if (IS_ERR(hwmon))
return PTR_ERR(hwmon);
return 0;
}
static void static void
mt7915_init_txpower(struct mt7915_dev *dev, mt7915_init_txpower(struct mt7915_dev *dev,
struct ieee80211_supported_band *sband) struct ieee80211_supported_band *sband)
...@@ -201,7 +287,6 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band) ...@@ -201,7 +287,6 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF); FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF);
mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set); mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set);
mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN); mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 1536); mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 1536);
...@@ -228,20 +313,19 @@ static int mt7915_txbf_init(struct mt7915_dev *dev) ...@@ -228,20 +313,19 @@ static int mt7915_txbf_init(struct mt7915_dev *dev)
{ {
int ret; int ret;
if (dev->dbdc_support) { if (dev->dbdc_support) {
ret = mt7915_mcu_set_txbf_module(dev); ret = mt7915_mcu_set_txbf(dev, MT_BF_MODULE_UPDATE);
if (ret) if (ret)
return ret; return ret;
} }
/* trigger sounding packets */ /* trigger sounding packets */
ret = mt7915_mcu_set_txbf_sounding(dev); ret = mt7915_mcu_set_txbf(dev, MT_BF_SOUNDING_ON);
if (ret) if (ret)
return ret; return ret;
/* enable eBF */ /* enable eBF */
return mt7915_mcu_set_txbf_type(dev); return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);
} }
static int mt7915_register_ext_phy(struct mt7915_dev *dev) static int mt7915_register_ext_phy(struct mt7915_dev *dev)
...@@ -281,8 +365,12 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev) ...@@ -281,8 +365,12 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev)
if (ret) if (ret)
goto error; goto error;
ret = mt76_register_phy(mphy, true, mt7915_rates, ret = mt76_register_phy(mphy, true, mt76_rates,
ARRAY_SIZE(mt7915_rates)); ARRAY_SIZE(mt76_rates));
if (ret)
goto error;
ret = mt7915_thermal_init(phy);
if (ret) if (ret)
goto error; goto error;
...@@ -480,6 +568,9 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap, ...@@ -480,6 +568,9 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap,
if (nss < 2) if (nss < 2)
return; return;
/* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */
elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3;
if (vif != NL80211_IFTYPE_AP) if (vif != NL80211_IFTYPE_AP)
return; return;
...@@ -493,9 +584,6 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap, ...@@ -493,9 +584,6 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap,
c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB; IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
elem->phy_cap_info[6] |= c; elem->phy_cap_info[6] |= c;
/* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */
elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3;
} }
static void static void
...@@ -579,8 +667,6 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, ...@@ -579,8 +667,6 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
switch (i) { switch (i) {
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
he_cap_elem->mac_cap_info[0] |=
IEEE80211_HE_MAC_CAP0_TWT_RES;
he_cap_elem->mac_cap_info[2] |= he_cap_elem->mac_cap_info[2] |=
IEEE80211_HE_MAC_CAP2_BSR; IEEE80211_HE_MAC_CAP2_BSR;
he_cap_elem->mac_cap_info[4] |= he_cap_elem->mac_cap_info[4] |=
...@@ -594,8 +680,6 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, ...@@ -594,8 +680,6 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT; IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
he_cap_elem->mac_cap_info[0] |=
IEEE80211_HE_MAC_CAP0_TWT_REQ;
he_cap_elem->mac_cap_info[1] |= he_cap_elem->mac_cap_info[1] |=
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US; IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
...@@ -690,6 +774,7 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev) ...@@ -690,6 +774,7 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
if (!phy) if (!phy)
return; return;
mt7915_unregister_thermal(phy);
mt76_unregister_phy(mphy); mt76_unregister_phy(mphy);
ieee80211_free_hw(mphy->hw); ieee80211_free_hw(mphy->hw);
} }
...@@ -731,8 +816,12 @@ int mt7915_register_device(struct mt7915_dev *dev) ...@@ -731,8 +816,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
dev->mt76.test_ops = &mt7915_testmode_ops; dev->mt76.test_ops = &mt7915_testmode_ops;
#endif #endif
ret = mt76_register_device(&dev->mt76, true, mt7915_rates, ret = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt7915_rates)); ARRAY_SIZE(mt76_rates));
if (ret)
return ret;
ret = mt7915_thermal_init(&dev->phy);
if (ret) if (ret)
return ret; return ret;
...@@ -748,10 +837,12 @@ int mt7915_register_device(struct mt7915_dev *dev) ...@@ -748,10 +837,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
void mt7915_unregister_device(struct mt7915_dev *dev) void mt7915_unregister_device(struct mt7915_dev *dev)
{ {
mt7915_unregister_ext_phy(dev); mt7915_unregister_ext_phy(dev);
mt7915_unregister_thermal(&dev->phy);
mt76_unregister_device(&dev->mt76); mt76_unregister_device(&dev->mt76);
mt7915_mcu_exit(dev); mt7915_mcu_exit(dev);
mt7915_tx_token_put(dev); mt7915_tx_token_put(dev);
mt7915_dma_cleanup(dev); mt7915_dma_cleanup(dev);
tasklet_disable(&dev->irq_tasklet);
mt76_free_device(&dev->mt76); mt76_free_device(&dev->mt76);
} }
...@@ -304,6 +304,62 @@ struct mt7915_tx_free { ...@@ -304,6 +304,62 @@ struct mt7915_tx_free {
/* will support this field in further revision */ /* will support this field in further revision */
#define MT_TX_FREE_RATE GENMASK(13, 0) #define MT_TX_FREE_RATE GENMASK(13, 0)
#define MT_TXS0_FIXED_RATE BIT(31)
#define MT_TXS0_BW GENMASK(30, 29)
#define MT_TXS0_TID GENMASK(28, 26)
#define MT_TXS0_AMPDU BIT(25)
#define MT_TXS0_TXS_FORMAT GENMASK(24, 23)
#define MT_TXS0_BA_ERROR BIT(22)
#define MT_TXS0_PS_FLAG BIT(21)
#define MT_TXS0_TXOP_TIMEOUT BIT(20)
#define MT_TXS0_BIP_ERROR BIT(19)
#define MT_TXS0_QUEUE_TIMEOUT BIT(18)
#define MT_TXS0_RTS_TIMEOUT BIT(17)
#define MT_TXS0_ACK_TIMEOUT BIT(16)
#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16)
#define MT_TXS0_TX_STATUS_HOST BIT(15)
#define MT_TXS0_TX_STATUS_MCU BIT(14)
#define MT_TXS0_TX_RATE GENMASK(13, 0)
#define MT_TXS1_SEQNO GENMASK(31, 20)
#define MT_TXS1_RESP_RATE GENMASK(19, 16)
#define MT_TXS1_RXV_SEQNO GENMASK(15, 8)
#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0)
#define MT_TXS2_BF_STATUS GENMASK(31, 30)
#define MT_TXS2_LAST_TX_RATE GENMASK(29, 27)
#define MT_TXS2_SHARED_ANTENNA BIT(26)
#define MT_TXS2_WCID GENMASK(25, 16)
#define MT_TXS2_TX_DELAY GENMASK(15, 0)
#define MT_TXS3_PID GENMASK(31, 24)
#define MT_TXS3_ANT_ID GENMASK(23, 0)
#define MT_TXS4_TIMESTAMP GENMASK(31, 0)
#define MT_TXS5_F0_FINAL_MPDU BIT(31)
#define MT_TXS5_F0_QOS BIT(30)
#define MT_TXS5_F0_TX_COUNT GENMASK(29, 25)
#define MT_TXS5_F0_FRONT_TIME GENMASK(24, 0)
#define MT_TXS5_F1_MPDU_TX_COUNT GENMASK(31, 24)
#define MT_TXS5_F1_MPDU_TX_BYTES GENMASK(23, 0)
#define MT_TXS6_F0_NOISE_3 GENMASK(31, 24)
#define MT_TXS6_F0_NOISE_2 GENMASK(23, 16)
#define MT_TXS6_F0_NOISE_1 GENMASK(15, 8)
#define MT_TXS6_F0_NOISE_0 GENMASK(7, 0)
#define MT_TXS6_F1_MPDU_FAIL_COUNT GENMASK(31, 24)
#define MT_TXS6_F1_MPDU_FAIL_BYTES GENMASK(23, 0)
#define MT_TXS7_F0_RCPI_3 GENMASK(31, 24)
#define MT_TXS7_F0_RCPI_2 GENMASK(23, 16)
#define MT_TXS7_F0_RCPI_1 GENMASK(15, 8)
#define MT_TXS7_F0_RCPI_0 GENMASK(7, 0)
#define MT_TXS7_F1_MPDU_RETRY_COUNT GENMASK(31, 24)
#define MT_TXS7_F1_MPDU_RETRY_BYTES GENMASK(23, 0)
struct mt7915_dfs_pulse { struct mt7915_dfs_pulse {
u32 max_width; /* us */ u32 max_width; /* us */
int max_pwr; /* dbm */ int max_pwr; /* dbm */
......
...@@ -139,12 +139,6 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask) ...@@ -139,12 +139,6 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask)
if (type != NL80211_IFTYPE_STATION) if (type != NL80211_IFTYPE_STATION)
break; break;
/* next, try to find a free repeater entry for the sta */
i = get_free_idx(mask >> REPEATER_BSSID_START, 0,
REPEATER_BSSID_MAX - REPEATER_BSSID_START);
if (i)
return i + 32 - 1;
i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX); i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);
if (i) if (i)
return i - 1; return i - 1;
...@@ -172,6 +166,22 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask) ...@@ -172,6 +166,22 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask)
return -1; return -1;
} }
static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
int i;
for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) {
mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0);
memset(mvif->bitrate_mask.control[i].ht_mcs, GENMASK(7, 0),
sizeof(mvif->bitrate_mask.control[i].ht_mcs));
memset(mvif->bitrate_mask.control[i].vht_mcs, GENMASK(15, 0),
sizeof(mvif->bitrate_mask.control[i].vht_mcs));
memset(mvif->bitrate_mask.control[i].he_mcs, GENMASK(15, 0),
sizeof(mvif->bitrate_mask.control[i].he_mcs));
}
}
static int mt7915_add_interface(struct ieee80211_hw *hw, static int mt7915_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
...@@ -241,6 +251,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, ...@@ -241,6 +251,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
vif->offload_flags = 0; vif->offload_flags = 0;
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
mt7915_init_bitrate_mask(vif);
out: out:
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
...@@ -798,7 +810,8 @@ mt7915_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -798,7 +810,8 @@ mt7915_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
n = mvif->omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : mvif->omac_idx; n = mvif->omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : mvif->omac_idx;
/* TSF software read */ /* TSF software read */
mt76_set(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE); mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,
MT_LPON_TCR_SW_READ);
tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(band)); tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(band));
tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(band)); tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(band));
...@@ -827,7 +840,34 @@ mt7915_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -827,7 +840,34 @@ mt7915_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]); mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]);
mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]); mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]);
/* TSF software overwrite */ /* TSF software overwrite */
mt76_set(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_WRITE); mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,
MT_LPON_TCR_SW_WRITE);
mutex_unlock(&dev->mt76.mutex);
}
static void
mt7915_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
s64 timestamp)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_dev *dev = mt7915_hw_dev(hw);
struct mt7915_phy *phy = mt7915_hw_phy(hw);
bool band = phy != &dev->phy;
union {
u64 t64;
u32 t32[2];
} tsf = { .t64 = timestamp, };
u16 n;
mutex_lock(&dev->mt76.mutex);
n = mvif->omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : mvif->omac_idx;
mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]);
mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]);
/* TSF software adjust*/
mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,
MT_LPON_TCR_SW_ADJUST);
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
} }
...@@ -911,17 +951,15 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, ...@@ -911,17 +951,15 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
} }
static void static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
mt7915_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
u32 changed)
{ {
struct mt7915_dev *dev = mt7915_hw_dev(hw);
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct mt7915_dev *dev = msta->vif->phy->dev;
struct ieee80211_hw *hw = msta->vif->phy->mt76->hw;
u32 *changed = data;
spin_lock_bh(&dev->sta_poll_lock); spin_lock_bh(&dev->sta_poll_lock);
msta->stats.changed |= changed; msta->stats.changed |= *changed;
if (list_empty(&msta->rc_list)) if (list_empty(&msta->rc_list))
list_add_tail(&msta->rc_list, &dev->sta_rc_list); list_add_tail(&msta->rc_list, &dev->sta_rc_list);
spin_unlock_bh(&dev->sta_poll_lock); spin_unlock_bh(&dev->sta_poll_lock);
...@@ -929,6 +967,39 @@ mt7915_sta_rc_update(struct ieee80211_hw *hw, ...@@ -929,6 +967,39 @@ mt7915_sta_rc_update(struct ieee80211_hw *hw,
ieee80211_queue_work(hw, &dev->rc_work); ieee80211_queue_work(hw, &dev->rc_work);
} }
static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
u32 changed)
{
mt7915_sta_rc_work(&changed, sta);
}
static int
mt7915_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
enum nl80211_band band = mvif->phy->mt76->chandef.chan->band;
u32 changed;
if (mask->control[band].gi == NL80211_TXRATE_FORCE_LGI)
return -EINVAL;
changed = IEEE80211_RC_SUPP_RATES_CHANGED;
mvif->bitrate_mask = *mask;
/* Update firmware rate control to add a boundary on top of table
* to limit the rate selection for each peer, so when set bitrates
* vht-mcs-5 1:9, which actually means nss = 1 mcs = 0~9. This only
* applies to data frames as for the other mgmt, mcast, bcast still
* use legacy rates as it is.
*/
ieee80211_iterate_stations_atomic(hw, mt7915_sta_rc_work, &changed);
return 0;
}
static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
...@@ -987,9 +1058,11 @@ const struct ieee80211_ops mt7915_ops = { ...@@ -987,9 +1058,11 @@ const struct ieee80211_ops mt7915_ops = {
.get_stats = mt7915_get_stats, .get_stats = mt7915_get_stats,
.get_tsf = mt7915_get_tsf, .get_tsf = mt7915_get_tsf,
.set_tsf = mt7915_set_tsf, .set_tsf = mt7915_set_tsf,
.offset_tsf = mt7915_offset_tsf,
.get_survey = mt76_get_survey, .get_survey = mt76_get_survey,
.get_antenna = mt76_get_antenna, .get_antenna = mt76_get_antenna,
.set_antenna = mt7915_set_antenna, .set_antenna = mt7915_set_antenna,
.set_bitrate_mask = mt7915_set_bitrate_mask,
.set_coverage_class = mt7915_set_coverage_class, .set_coverage_class = mt7915_set_coverage_class,
.sta_statistics = mt7915_sta_statistics, .sta_statistics = mt7915_sta_statistics,
.sta_set_4addr = mt7915_sta_set_4addr, .sta_set_4addr = mt7915_sta_set_4addr,
......
...@@ -68,6 +68,29 @@ struct mt7915_mcu_rxd { ...@@ -68,6 +68,29 @@ struct mt7915_mcu_rxd {
u8 s2d_index; u8 s2d_index;
}; };
struct mt7915_mcu_thermal_ctrl {
u8 ctrl_id;
u8 band_idx;
union {
struct {
u8 protect_type; /* 1: duty admit, 2: radio off */
u8 trigger_type; /* 0: low, 1: high */
} __packed type;
struct {
u8 duty_level; /* level 0~3 */
u8 duty_cycle;
} __packed duty;
};
} __packed;
struct mt7915_mcu_thermal_notify {
struct mt7915_mcu_rxd rxd;
struct mt7915_mcu_thermal_ctrl ctrl;
__le32 temperature;
u8 rsv[8];
} __packed;
struct mt7915_mcu_csa_notify { struct mt7915_mcu_csa_notify {
struct mt7915_mcu_rxd rxd; struct mt7915_mcu_rxd rxd;
...@@ -193,6 +216,19 @@ struct mt7915_mcu_phy_rx_info { ...@@ -193,6 +216,19 @@ struct mt7915_mcu_phy_rx_info {
#define MT_RA_RATE_DCM_EN BIT(4) #define MT_RA_RATE_DCM_EN BIT(4)
#define MT_RA_RATE_BW GENMASK(14, 13) #define MT_RA_RATE_BW GENMASK(14, 13)
struct mt7915_mcu_mib {
__le32 band;
__le32 offs;
__le64 data;
} __packed;
enum mt7915_chan_mib_offs {
MIB_BUSY_TIME = 14,
MIB_TX_TIME = 81,
MIB_RX_TIME,
MIB_OBSS_AIRTIME = 86
};
struct edca { struct edca {
u8 queue; u8 queue;
u8 set; u8 set;
...@@ -262,6 +298,7 @@ enum { ...@@ -262,6 +298,7 @@ enum {
MCU_EXT_CMD_FW_LOG_2_HOST = 0x13, MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
MCU_EXT_CMD_TXBF_ACTION = 0x1e, MCU_EXT_CMD_TXBF_ACTION = 0x1e,
MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21, MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
MCU_EXT_CMD_THERMAL_PROT = 0x23,
MCU_EXT_CMD_STA_REC_UPDATE = 0x25, MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26, MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
MCU_EXT_CMD_EDCA_UPDATE = 0x27, MCU_EXT_CMD_EDCA_UPDATE = 0x27,
...@@ -277,6 +314,7 @@ enum { ...@@ -277,6 +314,7 @@ enum {
MCU_EXT_CMD_MUAR_UPDATE = 0x48, MCU_EXT_CMD_MUAR_UPDATE = 0x48,
MCU_EXT_CMD_SET_RX_PATH = 0x4e, MCU_EXT_CMD_SET_RX_PATH = 0x4e,
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58, MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
MCU_EXT_CMD_GET_MIB_INFO = 0x5a,
MCU_EXT_CMD_MWDS_SUPPORT = 0x80, MCU_EXT_CMD_MWDS_SUPPORT = 0x80,
MCU_EXT_CMD_SET_SER_TRIGGER = 0x81, MCU_EXT_CMD_SET_SER_TRIGGER = 0x81,
MCU_EXT_CMD_SCS_CTRL = 0x82, MCU_EXT_CMD_SCS_CTRL = 0x82,
...@@ -919,7 +957,7 @@ struct sta_rec_ra { ...@@ -919,7 +957,7 @@ struct sta_rec_ra {
u8 op_vht_rx_nss; u8 op_vht_rx_nss;
u8 op_vht_rx_nss_type; u8 op_vht_rx_nss_type;
__le32 sta_status; __le32 sta_cap;
struct ra_phy phy; struct ra_phy phy;
} __packed; } __packed;
...@@ -1034,18 +1072,17 @@ enum { ...@@ -1034,18 +1072,17 @@ enum {
STA_REC_MAX_NUM STA_REC_MAX_NUM
}; };
enum mt7915_cipher_type { enum mcu_cipher_type {
MT_CIPHER_NONE, MCU_CIPHER_WEP40 = 1,
MT_CIPHER_WEP40, MCU_CIPHER_WEP104,
MT_CIPHER_WEP104, MCU_CIPHER_WEP128,
MT_CIPHER_WEP128, MCU_CIPHER_TKIP,
MT_CIPHER_TKIP, MCU_CIPHER_AES_CCMP,
MT_CIPHER_AES_CCMP, MCU_CIPHER_CCMP_256,
MT_CIPHER_CCMP_256, MCU_CIPHER_GCMP,
MT_CIPHER_GCMP, MCU_CIPHER_GCMP_256,
MT_CIPHER_GCMP_256, MCU_CIPHER_WAPI,
MT_CIPHER_WAPI, MCU_CIPHER_BIP_CMAC_128,
MT_CIPHER_BIP_CMAC_128,
}; };
enum { enum {
...@@ -1066,11 +1103,28 @@ enum { ...@@ -1066,11 +1103,28 @@ enum {
THERMAL_SENSOR_TASK_CTRL, THERMAL_SENSOR_TASK_CTRL,
}; };
enum {
THERMAL_PROTECT_PARAMETER_CTRL,
THERMAL_PROTECT_BASIC_INFO,
THERMAL_PROTECT_ENABLE,
THERMAL_PROTECT_DISABLE,
THERMAL_PROTECT_DUTY_CONFIG,
THERMAL_PROTECT_MECH_INFO,
THERMAL_PROTECT_DUTY_INFO,
THERMAL_PROTECT_STATE_ACT,
};
enum { enum {
MT_EBF = BIT(0), /* explicit beamforming */ MT_EBF = BIT(0), /* explicit beamforming */
MT_IBF = BIT(1) /* implicit beamforming */ MT_IBF = BIT(1) /* implicit beamforming */
}; };
enum {
MT_BF_SOUNDING_ON = 1,
MT_BF_TYPE_UPDATE = 20,
MT_BF_MODULE_UPDATE = 25
};
#define MT7915_WTBL_UPDATE_MAX_SIZE (sizeof(struct wtbl_req_hdr) + \ #define MT7915_WTBL_UPDATE_MAX_SIZE (sizeof(struct wtbl_req_hdr) + \
sizeof(struct wtbl_generic) + \ sizeof(struct wtbl_generic) + \
sizeof(struct wtbl_rx) + \ sizeof(struct wtbl_rx) + \
......
...@@ -464,10 +464,17 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en) ...@@ -464,10 +464,17 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
static void static void
mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en) mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
{ {
if (en) mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
if (en) {
struct mt7915_dev *dev = phy->dev;
mt7915_tm_update_channel(phy); mt7915_tm_update_channel(phy);
mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en); /* read-clear */
mt76_rr(dev, MT_MIB_SDR3(phy != &dev->phy));
mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
}
} }
static int static int
...@@ -690,7 +697,11 @@ static int ...@@ -690,7 +697,11 @@ static int
mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
{ {
struct mt7915_phy *phy = mphy->priv; struct mt7915_phy *phy = mphy->priv;
struct mt7915_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
enum mt76_rxq_id q;
void *rx, *rssi; void *rx, *rssi;
u16 fcs_err;
int i; int i;
rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX); rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX);
...@@ -735,6 +746,12 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) ...@@ -735,6 +746,12 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
nla_nest_end(msg, rx); nla_nest_end(msg, rx);
fcs_err = mt76_get_field(dev, MT_MIB_SDR3(ext_phy),
MT_MIB_SDR3_FCS_ERR_MASK);
q = ext_phy ? MT_RXQ_EXT : MT_RXQ_MAIN;
mphy->test.rx_stats.packets[q] += fcs_err;
mphy->test.rx_stats.fcs_error[q] += fcs_err;
return 0; return 0;
} }
......
// SPDX-License-Identifier: ISC /* SPDX-License-Identifier: ISC */
/* Copyright (C) 2020 MediaTek Inc. */ /* Copyright (C) 2020 MediaTek Inc. */
#ifndef __MT7915_TESTMODE_H #ifndef __MT7915_TESTMODE_H
......
#SPDX-License-Identifier: ISC # SPDX-License-Identifier: ISC
obj-$(CONFIG_MT7921E) += mt7921e.o obj-$(CONFIG_MT7921E) += mt7921e.o
......
This diff is collapsed.
This diff is collapsed.
...@@ -925,6 +925,7 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, ...@@ -925,6 +925,7 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
q->head = (q->head + 1) % q->ndesc; q->head = (q->head + 1) % q->ndesc;
q->entry[idx].skb = tx_info.skb; q->entry[idx].skb = tx_info.skb;
q->entry[idx].wcid = 0xffff;
q->queued++; q->queued++;
return idx; return idx;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment