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,
q->entry[idx].txwi = txwi;
q->entry[idx].skb = skb;
q->entry[idx].wcid = 0xffff;
return idx;
}
......@@ -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 ieee80211_sta *sta)
{
struct ieee80211_tx_status status = {
.sta = sta,
};
struct mt76_tx_info tx_info = {
.skb = skb,
};
......@@ -360,11 +364,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
u8 *txwi;
t = mt76_get_txwi(dev);
if (!t) {
hw = mt76_tx_status_get_hw(dev, skb);
ieee80211_free_txskb(hw, skb);
return -ENOMEM;
}
if (!t)
goto free_skb;
txwi = mt76_get_txwi_ptr(dev, t);
skb->prev = skb->next = NULL;
......@@ -427,8 +429,13 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
}
#endif
dev_kfree_skb(tx_info.skb);
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;
}
......
......@@ -83,6 +83,22 @@ static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
{ .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)
{
struct device_node *np = dev->dev->of_node;
......@@ -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, AP_LINK_PS);
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 *
......@@ -346,6 +351,17 @@ mt76_alloc_phy(struct mt76_dev *dev, unsigned int size,
phy->hw = hw;
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;
}
EXPORT_SYMBOL_GPL(mt76_alloc_phy);
......@@ -428,6 +444,17 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
mutex_init(&dev->mcu.mutex);
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);
idr_init(&dev->token);
......@@ -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);
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;
if (dev->drv->update_survey)
dev->drv->update_survey(dev);
dev->drv->update_survey(phy);
cur_time = ktime_get_boottime();
mt76_update_survey_active_time(&dev->phy, cur_time);
if (dev->phy2)
mt76_update_survey_active_time(dev->phy2, cur_time);
mt76_update_survey_active_time(phy, cur_time);
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);
state->cc_bss_rx += dev->cur_cc_bss_rx;
......@@ -664,7 +690,7 @@ void mt76_set_channel(struct mt76_phy *phy)
int timeout = HZ / 5;
wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout);
mt76_update_survey(dev);
mt76_update_survey(phy);
phy->chandef = *chandef;
phy->chan_state = mt76_channel_state(phy, chandef->chan);
......@@ -689,7 +715,7 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx,
mutex_lock(&dev->mutex);
if (idx == 0 && dev->drv->update_survey)
mt76_update_survey(dev);
mt76_update_survey(phy);
sband = &phy->sband_2g;
if (idx >= sband->sband.n_channels) {
......
......@@ -87,6 +87,22 @@ enum mt76_rxq_id {
__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 {
dma_addr_t addr;
u16 len;
......@@ -320,6 +336,7 @@ enum {
struct mt76_hw_cap {
bool has_2ghz;
bool has_5ghz;
bool has_6ghz;
};
#define MT_DRV_TXWI_NO_FREE BIT(0)
......@@ -336,7 +353,7 @@ struct mt76_driver_ops {
u16 token_size;
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,
enum mt76_txq_id qid, struct mt76_wcid *wcid,
......@@ -738,6 +755,21 @@ enum mt76_phy_type {
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_wr(dev, ...) (dev)->bus->wr((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,
bool more_data);
bool mt76_has_tx_pending(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);
int mt76_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey);
......@@ -1056,7 +1088,14 @@ struct sk_buff *mt76_tx_status_skb_get(struct mt76_dev *dev,
struct sk_buff_head *list);
void mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb,
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,
bool flush);
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)
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
......@@ -304,34 +304,6 @@ mt7603_init_hardware(struct mt7603_dev *dev)
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[] = {
{
.max = 1,
......@@ -569,8 +541,8 @@ int mt7603_register_device(struct mt7603_dev *dev)
wiphy->reg_notifier = mt7603_regd_notifier;
ret = mt76_register_device(&dev->mt76, true, mt7603_rates,
ARRAY_SIZE(mt7603_rates));
ret = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (ret)
return ret;
......
......@@ -550,14 +550,27 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
u8 *data = (u8 *)rxd;
if (status->flag & RX_FLAG_DECRYPTED) {
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];
insert_ccmp_hdr = FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
switch (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2)) {
case MT_CIPHER_AES_CCMP:
case MT_CIPHER_CCMP_CCX:
case MT_CIPHER_CCMP_256:
insert_ccmp_hdr =
FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
fallthrough;
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;
......@@ -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;
}
static enum mt7603_cipher_type
static enum mt76_cipher_type
mt7603_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
{
memset(key_data, 0, 32);
......@@ -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,
struct ieee80211_key_conf *key)
{
enum mt7603_cipher_type cipher;
enum mt76_cipher_type cipher;
u32 addr = mt7603_wtbl3_addr(wcid);
u8 key_data[32];
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,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
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;
}
......@@ -1584,12 +1597,12 @@ mt7603_watchdog_check(struct mt7603_dev *dev, u8 *counter,
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;
state = mdev->phy.chan_state;
state = mphy->chan_state;
state->cc_busy += mt76_rr(dev, MT_MIB_STAT_CCA);
}
......@@ -1806,7 +1819,7 @@ void mt7603_mac_work(struct work_struct *work)
mutex_lock(&dev->mt76.mutex);
dev->mphy.mac_work_count++;
mt76_update_survey(&dev->mt76);
mt76_update_survey(&dev->mphy);
mt7603_edcca_check(dev);
for (i = 0, idx = 0; i < 2; i++) {
......
......@@ -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_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_cca_stats_reset(struct mt7603_dev *dev);
......
......@@ -765,16 +765,4 @@ enum {
#define MT_WTBL1_OR (MT_WTBL1_BASE + 0x2300)
#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
#SPDX-License-Identifier: ISC
# SPDX-License-Identifier: ISC
obj-$(CONFIG_MT7615_COMMON) += mt7615-common.o
obj-$(CONFIG_MT7615E) += mt7615e.o
......
......@@ -75,7 +75,7 @@ mt7615_pm_set(void *data, u64 val)
if (!mt7615_wait_for_mcu_init(dev))
return 0;
if (!mt7615_firmware_offload(dev) || !mt76_is_mmio(&dev->mt76))
if (!mt7615_firmware_offload(dev) || mt76_is_usb(&dev->mt76))
return -EOPNOTSUPP;
if (val == pm->enable)
......@@ -319,24 +319,6 @@ mt7615_radio_read(struct seq_file *s, void *data)
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
mt7615_queues_acq(struct seq_file *s, void *data)
{
......@@ -566,8 +548,6 @@ int mt7615_init_debugfs(struct mt7615_dev *dev)
debugfs_create_file("reset_test", 0200, dir, dev,
&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_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
......
......@@ -81,7 +81,7 @@ static int mt7615_poll_tx(struct napi_struct *napi, int budget)
if (napi_complete(napi))
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;
}
......@@ -99,7 +99,7 @@ static int mt7615_poll_rx(struct napi_struct *napi, int budget)
return 0;
}
done = mt76_dma_rx_poll(napi, budget);
mt76_connac_pm_unref(&dev->pm);
mt76_connac_pm_unref(&dev->mphy, &dev->pm);
return done;
}
......@@ -222,14 +222,9 @@ void mt7615_dma_start(struct mt7615_dev *dev)
int mt7615_dma_init(struct mt7615_dev *dev)
{
int rx_ring_size = MT7615_RX_RING_SIZE;
int rx_buf_size = MT_RX_BUF_SIZE;
u32 mask;
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_wr(dev, MT_WPDMA_GLO_CFG,
......@@ -270,7 +265,7 @@ int mt7615_dma_init(struct mt7615_dev *dev)
/* init rx queues */
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);
if (ret)
return ret;
......@@ -279,7 +274,7 @@ int mt7615_dma_init(struct mt7615_dev *dev)
rx_ring_size /= 2;
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)
return ret;
......
......@@ -8,11 +8,61 @@
*/
#include <linux/etherdevice.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include "mt7615.h"
#include "mac.h"
#include "mcu.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
mt7615_phy_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);
#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[] = {
{
.max = 1,
......@@ -362,7 +383,7 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
wiphy->reg_notifier = mt7615_regd_notifier;
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_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
......@@ -472,8 +493,8 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
for (i = 0; i <= MT_TXQ_PSD ; i++)
mphy->q_tx[i] = dev->mphy.q_tx[i];
ret = mt76_register_phy(mphy, true, mt7615_rates,
ARRAY_SIZE(mt7615_rates));
ret = mt76_register_phy(mphy, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (ret)
ieee80211_free_hw(mphy->hw);
......
......@@ -383,48 +383,6 @@ struct mt7615_dfs_radar_spec {
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 *
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)
{
struct mt7615_dev *dev = mt7615_hw_dev(hw);
struct mt7615_phy *phy = mt7615_hw_phy(hw);
unsigned long timeout;
bool running;
int ret;
......@@ -78,8 +79,8 @@ static int mt7615_start(struct ieee80211_hw *hw)
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
MT7615_WATCHDOG_TIME);
timeout = mt7615_get_macwork_timeout(dev);
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, timeout);
if (!running)
mt7615_mac_reset_counters(dev);
......@@ -240,8 +241,6 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
}
ret = mt7615_mcu_add_dev_info(phy, vif, true);
if (ret)
goto out;
out:
mt7615_mutex_release(dev);
......@@ -352,10 +351,12 @@ int mt7615_set_channel(struct mt7615_phy *phy)
mt7615_mutex_release(dev);
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,
&phy->mt76->mac_work,
MT7615_WATCHDOG_TIME);
&phy->mt76->mac_work, timeout);
}
return ret;
}
......@@ -695,7 +696,7 @@ static void mt7615_sta_rate_tbl_update(struct ieee80211_hw *hw,
msta->n_rates = i;
if (mt76_connac_pm_ref(phy->mt76, &dev->pm)) {
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);
}
......@@ -711,7 +712,7 @@ void mt7615_tx_worker(struct mt76_worker *w)
}
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,
......@@ -741,7 +742,7 @@ static void mt7615_tx(struct ieee80211_hw *hw,
if (mt76_connac_pm_ref(mphy, &dev->pm)) {
mt76_tx(mphy, control->sta, wcid, skb);
mt76_connac_pm_unref(&dev->pm);
mt76_connac_pm_unref(mphy, &dev->pm);
return;
}
......@@ -881,7 +882,8 @@ mt7615_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
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[1] = mt76_rr(dev, MT_LPON_UTTR1);
......@@ -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_UTTR1, tsf.t32[1]);
/* 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);
}
......@@ -1162,7 +1190,7 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw,
else
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
......@@ -1200,6 +1228,7 @@ static int mt7615_resume(struct ieee80211_hw *hw)
{
struct mt7615_phy *phy = mt7615_hw_phy(hw);
struct mt7615_dev *dev = mt7615_hw_dev(hw);
unsigned long timeout;
bool running;
mt7615_mutex_acquire(dev);
......@@ -1223,8 +1252,8 @@ static int mt7615_resume(struct ieee80211_hw *hw)
mt76_connac_mcu_set_suspend_iter,
phy->mt76);
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
MT7615_WATCHDOG_TIME);
timeout = mt7615_get_macwork_timeout(dev);
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, timeout);
mt7615_mutex_release(dev);
......@@ -1278,6 +1307,7 @@ const struct ieee80211_ops mt7615_ops = {
.get_stats = mt7615_get_stats,
.get_tsf = mt7615_get_tsf,
.set_tsf = mt7615_set_tsf,
.offset_tsf = mt7615_offset_tsf,
.get_survey = mt76_get_survey,
.get_antenna = mt76_get_antenna,
.set_antenna = mt7615_set_antenna,
......
......@@ -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;
if (c->omac_idx > EXT_BSSID_MAX)
return;
if (ext_phy && ext_phy->omac_mask & BIT_ULL(c->omac_idx))
mphy = dev->mt76.phy2;
......@@ -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;
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)
mphy = dev->mt76.phy2;
......@@ -1021,9 +1028,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
if (IS_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)
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_RESET_AND_SET, NULL,
......@@ -1037,8 +1045,8 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
if (sta)
mt76_connac_mcu_wtbl_ht_tlv(&dev->mt76, wskb, sta,
NULL, wtbl_hdr);
mt76_connac_mcu_wtbl_hdr_trans_tlv(wskb, &msta->wcid, NULL,
wtbl_hdr);
mt76_connac_mcu_wtbl_hdr_trans_tlv(wskb, vif, &msta->wcid,
NULL, wtbl_hdr);
}
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,
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 = {
.add_beacon_offload = mt7615_mcu_add_beacon_offload,
.set_pm_state = mt7615_mcu_ctrl_pm_state,
......@@ -1068,6 +1096,7 @@ static const struct mt7615_mcu_ops wtbl_update_ops = {
.sta_add = mt7615_mcu_wtbl_sta_add,
.set_drv_ctrl = mt7615_mcu_drv_pmctrl,
.set_fw_ctrl = mt7615_mcu_fw_pmctrl,
.set_sta_decap_offload = mt7615_mcu_wtbl_update_hdr_trans,
};
static int
......@@ -1120,18 +1149,21 @@ mt7615_mcu_sta_rx_ba(struct mt7615_dev *dev,
static int
__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 mt76_sta_cmd_info info = {
.sta = sta,
.vif = vif,
.offload_fw = offload_fw,
.enable = enable,
.newly = true,
.cmd = cmd,
};
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
......@@ -1139,7 +1171,19 @@ mt7615_mcu_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool 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 = {
......@@ -1152,27 +1196,9 @@ static const struct mt7615_mcu_ops sta_update_ops = {
.sta_add = mt7615_mcu_add_sta,
.set_drv_ctrl = mt7615_mcu_drv_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
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,
struct ieee80211_sta *sta, bool 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
......@@ -1338,6 +1364,18 @@ mt7615_mcu_uni_rx_ba(struct mt7615_dev *dev,
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 = {
.add_beacon_offload = mt7615_mcu_uni_add_beacon_offload,
.set_pm_state = mt7615_mcu_uni_ctrl_pm_state,
......@@ -1348,6 +1386,7 @@ static const struct mt7615_mcu_ops uni_update_ops = {
.sta_add = mt7615_mcu_uni_add_sta,
.set_drv_ctrl = mt7615_mcu_lp_drv_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)
......@@ -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);
}
int mt7615_mcu_get_temperature(struct mt7615_dev *dev, int index)
int mt7615_mcu_get_temperature(struct mt7615_dev *dev)
{
struct {
u8 action;
u8 rsv[3];
} req = {
.action = index,
};
} req = {};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_GET_TEMP, &req,
sizeof(req), true);
......
......@@ -229,7 +229,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
GFP_KERNEL);
if (!bus_ops) {
ret = -ENOMEM;
goto error;
goto err_free_dev;
}
bus_ops->rr = mt7615_rr;
......@@ -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,
IRQF_SHARED, KBUILD_MODNAME, dev);
if (ret)
goto error;
goto err_free_dev;
if (is_mt7663(mdev))
mt76_wr(dev, MT_PCIE_IRQ_ENABLE, 1);
ret = mt7615_register_device(dev);
if (ret)
goto error;
goto err_free_irq;
return 0;
error:
err_free_irq:
devm_free_irq(pdev, irq, dev);
err_free_dev:
mt76_free_device(&dev->mt76);
return ret;
......
......@@ -20,7 +20,6 @@
MT7615_MAX_INTERFACES)
#define MT7615_PM_TIMEOUT (HZ / 12)
#define MT7615_WATCHDOG_TIME (HZ / 10)
#define MT7615_HW_SCAN_TIMEOUT (HZ / 10)
#define MT7615_RESET_TIMEOUT (30 * HZ)
#define MT7615_RATE_RETRY 2
......@@ -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_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_sta_decap_offload(dev, ...) (dev)->mcu_ops->set_sta_decap_offload((dev), __VA_ARGS__)
struct mt7615_mcu_ops {
int (*add_tx_ba)(struct mt7615_dev *dev,
struct ieee80211_ampdu_params *params,
......@@ -221,6 +221,9 @@ struct mt7615_mcu_ops {
int (*set_pm_state)(struct mt7615_dev *dev, int band, int state);
int (*set_drv_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 {
......@@ -356,6 +359,7 @@ static inline int mt7622_wmac_init(struct mt7615_dev *dev)
}
#endif
int mt7615_thermal_init(struct mt7615_dev *dev);
int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
int irq, const u32 *map);
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)
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_scan_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);
void mt7615_init_work(struct mt7615_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);
void mt7615_mac_reset_counters(struct mt7615_dev *dev);
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);
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_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);
void mt7615_mcu_exit(struct mt7615_dev *dev);
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,
void mt7615_mac_work(struct work_struct *work);
void mt7615_txp_skb_unmap(struct mt76_dev *dev,
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_fcc5_lpn(struct mt7615_dev *dev, int val);
int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev,
......
......@@ -98,7 +98,7 @@ mt7615_led_set_config(struct led_classdev *led_cdev,
addr = mt7615_reg_map(dev, MT_LED_CTRL);
mt76_wr(dev, addr, val);
mt76_connac_pm_unref(&dev->pm);
mt76_connac_pm_unref(&dev->mphy, &dev->pm);
}
static int
......@@ -147,8 +147,12 @@ int mt7615_register_device(struct mt7615_dev *dev)
if (ret)
return ret;
ret = mt76_register_device(&dev->mt76, true, mt7615_rates,
ARRAY_SIZE(mt7615_rates));
ret = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (ret)
return ret;
ret = mt7615_thermal_init(dev);
if (ret)
return ret;
......
......@@ -131,20 +131,21 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct mt76_tx_info *tx_info)
{
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_key_conf *key = info->control.hw_key;
int pid, id;
u8 *txwi = (u8 *)txwi_ptr;
struct mt76_txwi_cache *t;
struct mt7615_sta *msta;
void *txp;
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
if (!wcid)
wcid = &dev->mt76.global_wcid;
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;
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)
struct mt7615_phy *phy2;
struct mt76_phy *ext_phy;
struct mt7615_dev *dev;
unsigned long timeout;
dev = container_of(work, struct mt7615_dev, reset_work);
ext_phy = dev->mt76.phy2;
......@@ -344,11 +346,11 @@ void mt7615_mac_reset_work(struct work_struct *work)
mt7615_mutex_release(dev);
timeout = mt7615_get_macwork_timeout(dev);
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
MT7615_WATCHDOG_TIME);
timeout);
if (phy2)
ieee80211_queue_delayed_work(ext_phy->hw,
&phy2->mt76->mac_work,
MT7615_WATCHDOG_TIME);
&phy2->mt76->mac_work, timeout);
}
......@@ -463,7 +463,9 @@ enum mt7615_reg_base {
#define MT_LPON_TCR0(_n) MT_LPON(0x010 + ((_n) * 4))
#define MT_LPON_TCR2(_n) MT_LPON(0x0f8 + ((_n) - 2) * 4)
#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_ADJUST BIT(1)
#define MT_LPON_UTTR0 MT_LPON(0x018)
#define MT_LPON_UTTR1 MT_LPON(0x01c)
......
// SPDX-License-Identifier: ISC
/* SPDX-License-Identifier: ISC */
/* Copyright (C) 2020 MediaTek Inc.
*
* Author: Sean Wang <sean.wang@mediatek.com>
......
......@@ -55,6 +55,7 @@ static int __mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev)
{
struct sdio_func *func = dev->mt76.sdio.func;
struct mt76_phy *mphy = &dev->mt76.phy;
struct mt76_connac_pm *pm = &dev->pm;
u32 status;
int ret;
......@@ -66,37 +67,45 @@ static int __mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev)
status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000);
if (ret < 0) {
dev_err(dev->mt76.dev, "Cannot get ownership from device");
set_bit(MT76_STATE_PM, &mphy->state);
sdio_release_host(func);
} else {
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);
dev->pm.last_activity = jiffies;
return 0;
return ret;
}
static int mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev)
{
struct mt76_phy *mphy = &dev->mt76.phy;
int ret = 0;
if (test_and_clear_bit(MT76_STATE_PM, &mphy->state))
return __mt7663s_mcu_drv_pmctrl(dev);
mutex_lock(&dev->pm.mutex);
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)
{
struct sdio_func *func = dev->mt76.sdio.func;
struct mt76_phy *mphy = &dev->mt76.phy;
struct mt76_connac_pm *pm = &dev->pm;
int ret = 0;
u32 status;
int ret;
if (test_and_set_bit(MT76_STATE_PM, &mphy->state))
return 0;
mutex_lock(&pm->mutex);
if (mt76_connac_skip_fw_pmctrl(mphy, pm))
goto out;
sdio_claim_host(func);
......@@ -107,9 +116,15 @@ static int mt7663s_mcu_fw_pmctrl(struct mt7615_dev *dev)
if (ret < 0) {
dev_err(dev->mt76.dev, "Cannot set ownership to device");
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);
out:
mutex_unlock(&pm->mutex);
return ret;
}
......
......@@ -283,9 +283,15 @@ void mt7663s_txrx_worker(struct mt76_worker *w)
{
struct mt76_sdio *sdio = container_of(w, struct mt76_sdio,
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;
if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) {
queue_work(mdev->wq, &dev->pm.wake_work);
return;
}
/* disable interrupt */
sdio_claim_host(sdio->func);
sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
......@@ -295,16 +301,16 @@ void mt7663s_txrx_worker(struct mt76_worker *w)
/* tx */
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)
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)
nframes += ret;
/* rx */
ret = mt7663s_rx_handler(dev);
ret = mt7663s_rx_handler(mdev);
if (ret > 0)
nframes += ret;
} while (nframes > 0);
......@@ -312,6 +318,8 @@ void mt7663s_txrx_worker(struct mt76_worker *w)
/* enable interrupt */
sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
sdio_release_host(sdio->func);
mt76_connac_pm_unref(&dev->mphy, &dev->pm);
}
void mt7663s_sdio_irq(struct sdio_func *func)
......
......@@ -123,7 +123,7 @@ static int mt7663_usb_sdio_set_rates(struct mt7615_dev *dev,
idx = idx > HW_BSSID_MAX ? HW_BSSID_0 : 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);
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,
struct ieee80211_sta *sta,
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 sk_buff *skb = tx_info->skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct mt7615_sta *msta;
int pad;
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
!msta->rate_probe) {
msta && !msta->rate_probe) {
/* request to configure sampling rate */
spin_lock_bh(&dev->mt76.lock);
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)
hw->max_tx_fragments = 1;
}
err = mt76_register_device(&dev->mt76, true, mt7615_rates,
ARRAY_SIZE(mt7615_rates));
err = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (err < 0)
return err;
......
......@@ -7,12 +7,13 @@
#include "mt76.h"
#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_SCAN_MATCH 16
#define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20)
#define MT76_CONNAC_COREDUMP_SZ (128 * 1024)
#define MT76_CONNAC_COREDUMP_SZ (1300 * 1024)
enum {
CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20,
......@@ -45,6 +46,8 @@ enum {
struct mt76_connac_pm {
bool enable;
bool ds_enable;
bool suspended;
spinlock_t txq_lock;
struct {
......@@ -116,19 +119,27 @@ mt76_connac_pm_ref(struct mt76_phy *phy, struct mt76_connac_pm *pm)
}
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);
pm->wake.count--;
pm->last_activity = jiffies;
if (--pm->wake.count == 0 &&
test_bit(MT76_STATE_MCU_RUNNING, &phy->state))
mt76_connac_power_save_sched(phy, pm);
spin_unlock_bh(&pm->wake.lock);
}
static inline bool
mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm)
{
struct mt76_dev *dev = phy->dev;
bool ret;
if (dev->token_count)
return true;
spin_lock_bh(&pm->wake.lock);
ret = pm->wake.count || test_and_set_bit(MT76_STATE_PM, &phy->state);
spin_unlock_bh(&pm->wake.lock);
......
......@@ -10,13 +10,16 @@ int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)
if (!pm->enable)
return 0;
if (!mt76_is_mmio(dev))
if (mt76_is_usb(dev))
return 0;
cancel_delayed_work_sync(&pm->ps_work);
if (!test_bit(MT76_STATE_PM, &phy->state))
return 0;
if (pm->suspended)
return 0;
queue_work(dev->wq, &pm->wake_work);
if (!wait_event_timeout(pm->wait,
!test_bit(MT76_STATE_PM, &phy->state),
......@@ -34,12 +37,15 @@ void mt76_connac_power_save_sched(struct mt76_phy *phy,
{
struct mt76_dev *dev = phy->dev;
if (!mt76_is_mmio(dev))
if (mt76_is_usb(dev))
return;
if (!pm->enable)
return;
if (pm->suspended)
return;
pm->last_activity = jiffies;
if (!test_bit(MT76_STATE_PM, &phy->state)) {
......
......@@ -559,6 +559,7 @@ enum {
MCU_CMD_SET_RATE_TX_POWER = MCU_CE_PREFIX | 0x5d,
MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61,
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_READ = MCU_CE_PREFIX | MCU_QUERY_MASK | 0xc0,
MCU_CMD_CHIP_CONFIG = MCU_CE_PREFIX | 0xca,
......@@ -575,6 +576,7 @@ enum {
enum {
UNI_BSS_INFO_BASIC = 0,
UNI_BSS_INFO_RLM = 2,
UNI_BSS_INFO_BSS_COLOR = 4,
UNI_BSS_INFO_HE_BASIC = 5,
UNI_BSS_INFO_BCN_CONTENT = 7,
UNI_BSS_INFO_QBSS = 15,
......@@ -590,6 +592,36 @@ enum {
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 {
UNI_SUSPEND_MODE_SETTING,
UNI_SUSPEND_WOW_CTRL,
......@@ -762,7 +794,7 @@ struct mt76_connac_sched_scan_req {
u8 intervals_num;
u8 scan_func; /* MT7663: BIT(0) eable random mac address */
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 {
struct {
u8 random_mac[ETH_ALEN];
......@@ -770,7 +802,9 @@ struct mt76_connac_sched_scan_req {
} mt7663;
struct {
u8 bss_idx;
u8 pad2[63];
u8 pad2[19];
u8 random_mac[ETH_ALEN];
u8 pad3[38];
} mt7921;
};
} __packed;
......@@ -781,6 +815,14 @@ struct mt76_connac_sched_scan_done {
__le16 pad;
} __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 {
__le16 tag;
__le16 len;
......@@ -885,15 +927,24 @@ struct mt76_connac_suspend_tlv {
u8 pad[5];
} __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 ieee80211_sta *sta;
struct mt76_wcid *wcid;
struct ieee80211_vif *vif;
bool offload_fw;
bool enable;
bool newly;
int cmd;
u8 rcpi;
u8 state;
};
#define MT_SKU_POWER_LIMIT 161
......@@ -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);
void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
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,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta, void *sta_wtbl,
void *wtbl_tlv);
void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb,
struct ieee80211_vif *vif,
struct mt76_wcid *wcid,
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,
struct ieee80211_sta *sta,
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,
struct ieee80211_sta *sta, void *sta_wtbl,
void *wtbl_tlv);
......@@ -996,8 +1052,8 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
struct ieee80211_vif *vif,
struct mt76_wcid *wcid,
bool enable);
int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy,
struct mt76_sta_cmd_info *info);
int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
struct mt76_sta_cmd_info *info);
void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
struct ieee80211_vif *vif);
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,
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_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,
struct ieee80211_scan_request *scan_req);
......@@ -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);
void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
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_set_deep_sleep(struct mt76_dev *dev, bool enable);
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)
nic_conf1 &= 0xff00;
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");
if (!mt76x02_field_valid(nic_conf0 >> 8))
......
......@@ -34,24 +34,24 @@ mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
{
memset(key_data, 0, 32);
if (!key)
return MT_CIPHER_NONE;
return MT76X02_CIPHER_NONE;
if (key->keylen > 32)
return MT_CIPHER_NONE;
return MT76X02_CIPHER_NONE;
memcpy(key_data, key->key, key->keylen);
switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
return MT_CIPHER_WEP40;
return MT76X02_CIPHER_WEP40;
case WLAN_CIPHER_SUITE_WEP104:
return MT_CIPHER_WEP104;
return MT76X02_CIPHER_WEP104;
case WLAN_CIPHER_SUITE_TKIP:
return MT_CIPHER_TKIP;
return MT76X02_CIPHER_TKIP;
case WLAN_CIPHER_SUITE_CCMP:
return MT_CIPHER_AES_CCMP;
return MT76X02_CIPHER_AES_CCMP;
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,
u32 val;
cipher = mt76x02_mac_get_key_info(key, key_data);
if (cipher == MT_CIPHER_NONE && key)
if (cipher == MT76X02_CIPHER_NONE && key)
return -EOPNOTSUPP;
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,
eiv = mt76_rr(dev, MT_WCID_IV(idx) + 4);
pn = (u64)eiv << 16;
if (cipher == MT_CIPHER_TKIP) {
if (cipher == MT76X02_CIPHER_TKIP) {
pn |= (iv >> 16) & 0xff;
pn |= (iv & 0xff) << 8;
} else if (cipher >= MT_CIPHER_AES_CCMP) {
} else if (cipher >= MT76X02_CIPHER_AES_CCMP) {
pn |= iv & 0xffff;
} else {
return;
......@@ -112,7 +112,7 @@ int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
u64 pn;
cipher = mt76x02_mac_get_key_info(key, key_data);
if (cipher == MT_CIPHER_NONE && key)
if (cipher == MT76X02_CIPHER_NONE && key)
return -EOPNOTSUPP;
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,
pn = atomic64_read(&key->tx_pn);
iv_data[3] = key->keyidx << 6;
if (cipher >= MT_CIPHER_TKIP) {
if (cipher >= MT76X02_CIPHER_TKIP) {
iv_data[3] |= 0x20;
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[1] = (iv_data[0] | 0x20) & 0x7f;
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]);
}
}
......@@ -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]);
}
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;
state = mdev->phy.chan_state;
state = mphy->chan_state;
state->cc_busy += mt76_rr(dev, MT_CH_BUSY);
spin_lock_bh(&dev->mt76.cc_lock);
......@@ -1169,7 +1169,7 @@ void mt76x02_mac_work(struct work_struct *work)
mutex_lock(&dev->mt76.mutex);
mt76_update_survey(&dev->mt76);
mt76_update_survey(&dev->mphy);
for (i = 0, idx = 0; i < 16; 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,
struct ieee80211_sta *sta, int len);
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_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_cc_reset(struct mt76x02_dev *dev);
......
......@@ -692,15 +692,15 @@ struct mt76_wcid_key {
} __packed __aligned(4);
enum mt76x02_cipher_type {
MT_CIPHER_NONE,
MT_CIPHER_WEP40,
MT_CIPHER_WEP104,
MT_CIPHER_TKIP,
MT_CIPHER_AES_CCMP,
MT_CIPHER_CKIP40,
MT_CIPHER_CKIP104,
MT_CIPHER_CKIP128,
MT_CIPHER_WAPI,
MT76X02_CIPHER_NONE,
MT76X02_CIPHER_WEP40,
MT76X02_CIPHER_WEP104,
MT76X02_CIPHER_TKIP,
MT76X02_CIPHER_AES_CCMP,
MT76X02_CIPHER_CKIP40,
MT76X02_CIPHER_CKIP104,
MT76X02_CIPHER_CKIP128,
MT76X02_CIPHER_WAPI,
};
#endif
......@@ -7,24 +7,18 @@
#include <linux/module.h>
#include "mt76x02.h"
#define CCK_RATE(_idx, _rate) { \
#define MT76x02_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) | (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[] = {
CCK_RATE(0, 10),
CCK_RATE(1, 20),
CCK_RATE(2, 55),
CCK_RATE(3, 110),
MT76x02_CCK_RATE(0, 10),
MT76x02_CCK_RATE(1, 20),
MT76x02_CCK_RATE(2, 55),
MT76x02_CCK_RATE(3, 110),
OFDM_RATE(0, 60),
OFDM_RATE(1, 90),
OFDM_RATE(2, 120),
......
#SPDX-License-Identifier: ISC
# SPDX-License-Identifier: ISC
obj-$(CONFIG_MT7915E) += mt7915e.o
......
......@@ -3,6 +3,7 @@
#include "mt7915.h"
#include "eeprom.h"
#include "mcu.h"
/** global debugfs **/
......@@ -16,7 +17,7 @@ mt7915_implicit_txbf_set(void *data, u64 val)
dev->ibf = !!val;
return mt7915_mcu_set_txbf_type(dev);
return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);
}
static int
......@@ -147,6 +148,9 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
{
struct mt7915_dev *dev = s->private;
bool ext_phy = phy != &dev->phy;
static const char * const bw[] = {
"BW20", "BW40", "BW80", "BW160"
};
int cnt;
if (!phy)
......@@ -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: ");
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_HE, cnt),
FIELD_GET(MT_ETBF_RX_FB_VHT, 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 */
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)
mt7915_txbf_stat_read_phy(mt7915_ext_phy(dev), file);
/* 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++) {
stat[i] = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i));
n += stat[i];
......@@ -224,18 +233,6 @@ mt7915_tx_stats_show(struct seq_file *file, void *data)
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
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)
"RU26", "RU52", "RU106", "RU242/SU20",
"RU484/SU40", "RU996/SU80", "RU2x996/SU160"
};
struct mt7915_dev *dev = dev_get_drvdata(s->private);
bool ext_phy = phy != &dev->phy;
u32 reg_base;
int i, idx = 0;
s8 txpower[MT7915_SKU_RATE_NUM], *buf;
int i;
if (!phy)
return;
reg_base = MT_TMAC_FP0R0(ext_phy);
seq_printf(s, "\nBand %d\n", ext_phy);
seq_printf(s, "\nBand %d\n", phy != &phy->dev->phy);
for (i = 0; i < ARRAY_SIZE(mt7915_sku_group_len); i++) {
u8 cnt, mcs_num = mt7915_sku_group_len[i];
s8 txpower[12];
int j;
mt7915_mcu_get_txpower_sku(phy, txpower, sizeof(txpower));
for (i = 0, buf = txpower; i < ARRAY_SIZE(mt7915_sku_group_len); i++) {
u8 mcs_num = mt7915_sku_group_len[i];
if (i == SKU_HT_BW20 || i == SKU_HT_BW40) {
mcs_num = 8;
} else if (i >= SKU_VHT_BW20 && i <= SKU_VHT_BW160) {
if (i >= SKU_VHT_BW20 && i <= SKU_VHT_BW160)
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)
debugfs_create_file("radar_trigger", 0200, dir, dev,
&fops_radar_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,
mt7915_read_rate_txpower);
......
......@@ -19,39 +19,6 @@ int mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc)
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
mt7915_tx_cleanup(struct mt7915_dev *dev)
{
......@@ -112,8 +79,6 @@ void mt7915_dma_prefetch(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;
int ret;
......@@ -177,28 +142,28 @@ int mt7915_dma_init(struct mt7915_dev *dev)
/* event from WM */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
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)
return ret;
/* event from WA */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
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)
return ret;
/* rx data queue */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
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)
return ret;
if (dev->dbdc_support) {
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT],
MT7915_RXQ_BAND1, MT7915_RX_RING_SIZE,
rx_buf_size,
MT_RX_BUF_SIZE,
MT_RX_DATA_RING_BASE + hif1_ofs);
if (ret)
return ret;
......@@ -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],
MT7915_RXQ_MCU_WA_EXT,
MT7915_RX_MCU_RING_SIZE,
rx_buf_size,
MT_RX_BUF_SIZE,
MT_RX_EVENT_RING_BASE + hif1_ofs);
if (ret)
return ret;
......
......@@ -4,22 +4,12 @@
#include "mt7915.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)
{
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))
return 0;
......@@ -43,7 +33,13 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
dev->flash_mode = true;
ret = mt7915_eeprom_load_precal(dev);
} 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;
......@@ -52,10 +48,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
static int mt7915_check_eeprom(struct mt7915_dev *dev)
{
u8 *eeprom = dev->mt76.eeprom.data;
u16 val;
mt7915_eeprom_read(dev, MT_EE_CHIP_ID);
val = get_unaligned_le16(eeprom);
u16 val = get_unaligned_le16(eeprom);
switch (val) {
case 0x7915:
......@@ -69,9 +62,10 @@ void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
u8 *eeprom = dev->mt76.eeprom.data;
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);
if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support)
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,
struct ieee80211_channel *chan,
u8 chain_idx)
{
u8 *eeprom = dev->mt76.eeprom.data;
int index, target_power;
bool tssi_on;
......@@ -153,18 +148,18 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
if (chan->band == NL80211_BAND_2GHZ) {
index = MT_EE_TX0_POWER_2G + chain_idx * 3;
target_power = mt7915_eeprom_read(dev, index);
target_power = eeprom[index];
if (!tssi_on)
target_power += mt7915_eeprom_read(dev, index + 1);
target_power += eeprom[index + 1];
} else {
int group = mt7915_get_channel_group(chan->hw_value);
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)
target_power += mt7915_eeprom_read(dev, index + 8);
target_power += eeprom[index + 8];
}
return target_power;
......@@ -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)
{
u8 *eeprom = dev->mt76.eeprom.data;
u32 val;
s8 delta;
if (band == NL80211_BAND_2GHZ)
val = mt7915_eeprom_read(dev, MT_EE_RATE_DELTA_2G);
val = eeprom[MT_EE_RATE_DELTA_2G];
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))
return 0;
......
......@@ -33,7 +33,7 @@ enum mt7915_eeprom_field {
#define MT_EE_WIFI_CAL_GROUP BIT(0)
#define MT_EE_WIFI_CAL_DPD GENMASK(2, 1)
#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_WIFI_CONF0_TX_PATH GENMASK(2, 0)
......@@ -99,12 +99,15 @@ static inline bool
mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
{
u8 *eep = dev->mt76.eeprom.data;
u8 val = eep[MT_EE_WIFI_CONF + 7];
/* TODO: DBDC */
if (band == NL80211_BAND_5GHZ)
return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF7_TSSI0_5G;
if (band == NL80211_BAND_2GHZ)
return val & MT_EE_WIFI_CONF7_TSSI0_2G;
if (dev->dbdc_support)
return val & MT_EE_WIFI_CONF7_TSSI1_5G;
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];
......
......@@ -2,39 +2,14 @@
/* Copyright (C) 2020 MediaTek Inc. */
#include <linux/etherdevice.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/thermal.h>
#include "mt7915.h"
#include "mac.h"
#include "mcu.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[] = {
{
.max = 1,
......@@ -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
mt7915_init_txpower(struct mt7915_dev *dev,
struct ieee80211_supported_band *sband)
......@@ -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);
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_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)
{
int ret;
if (dev->dbdc_support) {
ret = mt7915_mcu_set_txbf_module(dev);
ret = mt7915_mcu_set_txbf(dev, MT_BF_MODULE_UPDATE);
if (ret)
return ret;
}
/* trigger sounding packets */
ret = mt7915_mcu_set_txbf_sounding(dev);
ret = mt7915_mcu_set_txbf(dev, MT_BF_SOUNDING_ON);
if (ret)
return ret;
/* 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)
......@@ -281,8 +365,12 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev)
if (ret)
goto error;
ret = mt76_register_phy(mphy, true, mt7915_rates,
ARRAY_SIZE(mt7915_rates));
ret = mt76_register_phy(mphy, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (ret)
goto error;
ret = mt7915_thermal_init(phy);
if (ret)
goto error;
......@@ -480,6 +568,9 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap,
if (nss < 2)
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)
return;
......@@ -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 |
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
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
......@@ -579,8 +667,6 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
switch (i) {
case NL80211_IFTYPE_AP:
he_cap_elem->mac_cap_info[0] |=
IEEE80211_HE_MAC_CAP0_TWT_RES;
he_cap_elem->mac_cap_info[2] |=
IEEE80211_HE_MAC_CAP2_BSR;
he_cap_elem->mac_cap_info[4] |=
......@@ -594,8 +680,6 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
break;
case NL80211_IFTYPE_STATION:
he_cap_elem->mac_cap_info[0] |=
IEEE80211_HE_MAC_CAP0_TWT_REQ;
he_cap_elem->mac_cap_info[1] |=
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
......@@ -690,6 +774,7 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
if (!phy)
return;
mt7915_unregister_thermal(phy);
mt76_unregister_phy(mphy);
ieee80211_free_hw(mphy->hw);
}
......@@ -731,8 +816,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
dev->mt76.test_ops = &mt7915_testmode_ops;
#endif
ret = mt76_register_device(&dev->mt76, true, mt7915_rates,
ARRAY_SIZE(mt7915_rates));
ret = mt76_register_device(&dev->mt76, true, mt76_rates,
ARRAY_SIZE(mt76_rates));
if (ret)
return ret;
ret = mt7915_thermal_init(&dev->phy);
if (ret)
return ret;
......@@ -748,10 +837,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
void mt7915_unregister_device(struct mt7915_dev *dev)
{
mt7915_unregister_ext_phy(dev);
mt7915_unregister_thermal(&dev->phy);
mt76_unregister_device(&dev->mt76);
mt7915_mcu_exit(dev);
mt7915_tx_token_put(dev);
mt7915_dma_cleanup(dev);
tasklet_disable(&dev->irq_tasklet);
mt76_free_device(&dev->mt76);
}
......@@ -304,6 +304,62 @@ struct mt7915_tx_free {
/* will support this field in further revision */
#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 {
u32 max_width; /* us */
int max_pwr; /* dbm */
......
......@@ -139,12 +139,6 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask)
if (type != NL80211_IFTYPE_STATION)
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);
if (i)
return i - 1;
......@@ -172,6 +166,22 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask)
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,
struct ieee80211_vif *vif)
{
......@@ -241,6 +251,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
vif->offload_flags = 0;
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
mt7915_init_bitrate_mask(vif);
out:
mutex_unlock(&dev->mt76.mutex);
......@@ -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;
/* 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[1] = mt76_rr(dev, MT_LPON_UTTR1(band));
......@@ -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_UTTR1(band), tsf.t32[1]);
/* 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);
}
......@@ -911,17 +951,15 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
}
static void
mt7915_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
u32 changed)
static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
{
struct mt7915_dev *dev = mt7915_hw_dev(hw);
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);
msta->stats.changed |= changed;
msta->stats.changed |= *changed;
if (list_empty(&msta->rc_list))
list_add_tail(&msta->rc_list, &dev->sta_rc_list);
spin_unlock_bh(&dev->sta_poll_lock);
......@@ -929,6 +967,39 @@ mt7915_sta_rc_update(struct ieee80211_hw *hw,
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,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
......@@ -987,9 +1058,11 @@ const struct ieee80211_ops mt7915_ops = {
.get_stats = mt7915_get_stats,
.get_tsf = mt7915_get_tsf,
.set_tsf = mt7915_set_tsf,
.offset_tsf = mt7915_offset_tsf,
.get_survey = mt76_get_survey,
.get_antenna = mt76_get_antenna,
.set_antenna = mt7915_set_antenna,
.set_bitrate_mask = mt7915_set_bitrate_mask,
.set_coverage_class = mt7915_set_coverage_class,
.sta_statistics = mt7915_sta_statistics,
.sta_set_4addr = mt7915_sta_set_4addr,
......
......@@ -68,6 +68,29 @@ struct mt7915_mcu_rxd {
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_rxd rxd;
......@@ -193,6 +216,19 @@ struct mt7915_mcu_phy_rx_info {
#define MT_RA_RATE_DCM_EN BIT(4)
#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 {
u8 queue;
u8 set;
......@@ -262,6 +298,7 @@ enum {
MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
MCU_EXT_CMD_TXBF_ACTION = 0x1e,
MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
MCU_EXT_CMD_THERMAL_PROT = 0x23,
MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
......@@ -277,6 +314,7 @@ enum {
MCU_EXT_CMD_MUAR_UPDATE = 0x48,
MCU_EXT_CMD_SET_RX_PATH = 0x4e,
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
MCU_EXT_CMD_GET_MIB_INFO = 0x5a,
MCU_EXT_CMD_MWDS_SUPPORT = 0x80,
MCU_EXT_CMD_SET_SER_TRIGGER = 0x81,
MCU_EXT_CMD_SCS_CTRL = 0x82,
......@@ -919,7 +957,7 @@ struct sta_rec_ra {
u8 op_vht_rx_nss;
u8 op_vht_rx_nss_type;
__le32 sta_status;
__le32 sta_cap;
struct ra_phy phy;
} __packed;
......@@ -1034,18 +1072,17 @@ enum {
STA_REC_MAX_NUM
};
enum mt7915_cipher_type {
MT_CIPHER_NONE,
MT_CIPHER_WEP40,
MT_CIPHER_WEP104,
MT_CIPHER_WEP128,
MT_CIPHER_TKIP,
MT_CIPHER_AES_CCMP,
MT_CIPHER_CCMP_256,
MT_CIPHER_GCMP,
MT_CIPHER_GCMP_256,
MT_CIPHER_WAPI,
MT_CIPHER_BIP_CMAC_128,
enum mcu_cipher_type {
MCU_CIPHER_WEP40 = 1,
MCU_CIPHER_WEP104,
MCU_CIPHER_WEP128,
MCU_CIPHER_TKIP,
MCU_CIPHER_AES_CCMP,
MCU_CIPHER_CCMP_256,
MCU_CIPHER_GCMP,
MCU_CIPHER_GCMP_256,
MCU_CIPHER_WAPI,
MCU_CIPHER_BIP_CMAC_128,
};
enum {
......@@ -1066,11 +1103,28 @@ enum {
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 {
MT_EBF = BIT(0), /* explicit 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) + \
sizeof(struct wtbl_generic) + \
sizeof(struct wtbl_rx) + \
......
......@@ -464,10 +464,17 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
static void
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_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
......@@ -690,7 +697,11 @@ static int
mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
{
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;
u16 fcs_err;
int i;
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)
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;
}
......
// SPDX-License-Identifier: ISC
/* SPDX-License-Identifier: ISC */
/* Copyright (C) 2020 MediaTek Inc. */
#ifndef __MT7915_TESTMODE_H
......
#SPDX-License-Identifier: ISC
# SPDX-License-Identifier: ISC
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,
q->head = (q->head + 1) % q->ndesc;
q->entry[idx].skb = tx_info.skb;
q->entry[idx].wcid = 0xffff;
q->queued++;
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