mt76 patches for 5.8
* fixes for sparse warnings * DBDC fixes * mt7663 remain-on-channel support * mt7915 spatial reuse support * mt7915 radiotap fix * station wcid allocation fix * mt7663 powersave fix * mt7663 scan fix * mt7611n support * cleanup -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iEYEABECAAYFAl7P4I0ACgkQ130UHQKnbvUo6ACeMMZcRYKeggGafRG8Sg56pR26 T8IAn0sXBHshLir4f4WsGBhLlrN6tbjy =cmhD -----END PGP SIGNATURE----- Merge tag 'mt76-for-kvalo-2020-05-28' of https://github.com/nbd168/wireless mt76 patches for 5.8 * fixes for sparse warnings * DBDC fixes * mt7663 remain-on-channel support * mt7915 spatial reuse support * mt7915 radiotap fix * station wcid allocation fix * mt7663 powersave fix * mt7663 scan fix * mt7611n support * cleanup # gpg: Signature made Thu 28 May 2020 07:02:21 PM EEST using DSA key ID 02A76EF5 # gpg: Good signature from "Felix Fietkau <nbd@nbd.name>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 75D1 1A7D 91A7 710F 4900 42EF D77D 141D 02A7 6EF5
This commit is contained in:
commit
5cf2740f1d
@ -51,7 +51,7 @@ static int mt76_rx_queues_read(struct seq_file *s, void *data)
|
||||
struct mt76_dev *dev = dev_get_drvdata(s->private);
|
||||
int i, queued;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) {
|
||||
mt76_for_each_q_rx(dev, i) {
|
||||
struct mt76_queue *q = &dev->q_rx[i];
|
||||
|
||||
if (!q->ndesc)
|
||||
|
@ -576,7 +576,7 @@ mt76_dma_init(struct mt76_dev *dev)
|
||||
|
||||
init_dummy_netdev(&dev->napi_dev);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) {
|
||||
mt76_for_each_q_rx(dev, i) {
|
||||
netif_napi_add(&dev->napi_dev, &dev->napi[i], mt76_dma_rx_poll,
|
||||
64);
|
||||
mt76_dma_rx_fill(dev, &dev->q_rx[i]);
|
||||
@ -610,7 +610,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++)
|
||||
mt76_dma_tx_cleanup(dev, i, true);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) {
|
||||
mt76_for_each_q_rx(dev, i) {
|
||||
netif_napi_del(&dev->napi[i]);
|
||||
mt76_dma_rx_cleanup(dev, &dev->q_rx[i]);
|
||||
}
|
||||
|
@ -288,8 +288,8 @@ enum {
|
||||
MT76_REMOVED,
|
||||
MT76_READING_STATS,
|
||||
MT76_STATE_POWER_OFF,
|
||||
MT76_STATE_PS,
|
||||
MT76_STATE_SUSPEND,
|
||||
MT76_STATE_ROC,
|
||||
};
|
||||
|
||||
struct mt76_hw_cap {
|
||||
@ -537,8 +537,8 @@ struct mt76_dev {
|
||||
wait_queue_head_t tx_wait;
|
||||
struct sk_buff_head status_list;
|
||||
|
||||
unsigned long wcid_mask[MT76_N_WCIDS / BITS_PER_LONG];
|
||||
unsigned long wcid_phy_mask[MT76_N_WCIDS / BITS_PER_LONG];
|
||||
u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)];
|
||||
u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)];
|
||||
|
||||
struct mt76_wcid global_wcid;
|
||||
struct mt76_wcid __rcu *wcid[MT76_N_WCIDS];
|
||||
@ -671,6 +671,10 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
|
||||
#define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__)
|
||||
#define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__)
|
||||
|
||||
#define mt76_for_each_q_rx(dev, i) \
|
||||
for (i = 0; i < ARRAY_SIZE((dev)->q_rx) && \
|
||||
(dev)->q_rx[i].ndesc; i++)
|
||||
|
||||
struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size,
|
||||
const struct ieee80211_ops *ops,
|
||||
const struct mt76_driver_ops *drv_ops);
|
||||
|
@ -473,7 +473,7 @@ mt7603_rx_get_wcid(struct mt7603_dev *dev, u8 idx, bool unicast)
|
||||
struct mt7603_sta *sta;
|
||||
struct mt76_wcid *wcid;
|
||||
|
||||
if (idx >= ARRAY_SIZE(dev->mt76.wcid))
|
||||
if (idx >= MT7603_WTBL_SIZE)
|
||||
return NULL;
|
||||
|
||||
wcid = rcu_dereference(dev->mt76.wcid[idx]);
|
||||
@ -1238,7 +1238,7 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
|
||||
if (pid == MT_PACKET_ID_NO_ACK)
|
||||
return;
|
||||
|
||||
if (wcidx >= ARRAY_SIZE(dev->mt76.wcid))
|
||||
if (wcidx >= MT7603_WTBL_SIZE)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
@ -1438,8 +1438,9 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)
|
||||
for (i = 0; i < __MT_TXQ_MAX; i++)
|
||||
mt76_queue_tx_cleanup(dev, i, true);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->mt76.q_rx); i++)
|
||||
mt76_for_each_q_rx(&dev->mt76, i) {
|
||||
mt76_queue_rx_reset(dev, i);
|
||||
}
|
||||
|
||||
mt7603_dma_sched_reset(dev);
|
||||
|
||||
|
@ -111,6 +111,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_mt7611(&dev->mt76)) {
|
||||
/* 5GHz only */
|
||||
dev->mt76.cap.has_5ghz = true;
|
||||
return;
|
||||
}
|
||||
|
||||
val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
|
||||
eeprom[MT_EE_WIFI_CONF]);
|
||||
switch (val) {
|
||||
@ -310,6 +316,7 @@ static void mt7615_cal_free_data(struct mt7615_dev *dev)
|
||||
mt7622_apply_cal_free_data(dev);
|
||||
break;
|
||||
case 0x7615:
|
||||
case 0x7611:
|
||||
mt7615_apply_cal_free_data(dev);
|
||||
break;
|
||||
}
|
||||
|
@ -139,8 +139,10 @@ void mt7615_check_offload_capability(struct mt7615_dev *dev)
|
||||
ieee80211_hw_set(hw, SUPPORTS_PS);
|
||||
ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
|
||||
|
||||
wiphy->max_remain_on_channel_duration = 5000;
|
||||
wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
|
||||
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
NL80211_FEATURE_P2P_GO_CTWIN |
|
||||
NL80211_FEATURE_P2P_GO_OPPPS;
|
||||
} else {
|
||||
@ -149,6 +151,8 @@ void mt7615_check_offload_capability(struct mt7615_dev *dev)
|
||||
dev->ops->sched_scan_start = NULL;
|
||||
dev->ops->sched_scan_stop = NULL;
|
||||
dev->ops->set_rekey_data = NULL;
|
||||
dev->ops->remain_on_channel = NULL;
|
||||
dev->ops->cancel_remain_on_channel = NULL;
|
||||
|
||||
wiphy->max_sched_scan_plan_interval = 0;
|
||||
wiphy->max_sched_scan_ie_len = 0;
|
||||
@ -368,12 +372,6 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
|
||||
if (phy)
|
||||
return 0;
|
||||
|
||||
INIT_DELAYED_WORK(&phy->mac_work, mt7615_mac_work);
|
||||
INIT_DELAYED_WORK(&phy->scan_work, mt7615_scan_work);
|
||||
skb_queue_head_init(&phy->scan_event_list);
|
||||
|
||||
INIT_WORK(&phy->ps_work, mt7615_ps_work);
|
||||
|
||||
mt7615_cap_dbdc_enable(dev);
|
||||
mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7615_ops);
|
||||
if (!mphy)
|
||||
@ -386,6 +384,14 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
|
||||
mphy->antenna_mask = BIT(hweight8(phy->chainmask)) - 1;
|
||||
mt7615_init_wiphy(mphy->hw);
|
||||
|
||||
INIT_DELAYED_WORK(&phy->mac_work, mt7615_mac_work);
|
||||
INIT_DELAYED_WORK(&phy->scan_work, mt7615_scan_work);
|
||||
skb_queue_head_init(&phy->scan_event_list);
|
||||
|
||||
INIT_WORK(&phy->roc_work, mt7615_roc_work);
|
||||
timer_setup(&phy->roc_timer, mt7615_roc_timer, 0);
|
||||
init_waitqueue_head(&phy->roc_wait);
|
||||
|
||||
mt7615_mac_set_scs(phy, true);
|
||||
|
||||
/*
|
||||
@ -437,9 +443,11 @@ void mt7615_init_device(struct mt7615_dev *dev)
|
||||
INIT_LIST_HEAD(&dev->sta_poll_list);
|
||||
spin_lock_init(&dev->sta_poll_lock);
|
||||
init_waitqueue_head(&dev->reset_wait);
|
||||
init_waitqueue_head(&dev->phy.roc_wait);
|
||||
|
||||
INIT_WORK(&dev->reset_work, mt7615_mac_reset_work);
|
||||
INIT_WORK(&dev->phy.ps_work, mt7615_ps_work);
|
||||
INIT_WORK(&dev->phy.roc_work, mt7615_roc_work);
|
||||
timer_setup(&dev->phy.roc_timer, mt7615_roc_timer, 0);
|
||||
|
||||
mt7615_init_wiphy(hw);
|
||||
dev->mphy.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
|
||||
|
@ -61,7 +61,7 @@ static struct mt76_wcid *mt7615_rx_get_wcid(struct mt7615_dev *dev,
|
||||
struct mt7615_sta *sta;
|
||||
struct mt76_wcid *wcid;
|
||||
|
||||
if (idx >= ARRAY_SIZE(dev->mt76.wcid))
|
||||
if (idx >= MT7615_WTBL_SIZE)
|
||||
return NULL;
|
||||
|
||||
wcid = rcu_dereference(dev->mt76.wcid[idx]);
|
||||
@ -175,7 +175,8 @@ mt7615_get_status_freq_info(struct mt7615_dev *dev, struct mt76_phy *mphy,
|
||||
struct mt76_rx_status *status, u8 chfreq)
|
||||
{
|
||||
if (!test_bit(MT76_HW_SCANNING, &mphy->state) &&
|
||||
!test_bit(MT76_HW_SCHED_SCANNING, &mphy->state)) {
|
||||
!test_bit(MT76_HW_SCHED_SCANNING, &mphy->state) &&
|
||||
!test_bit(MT76_STATE_ROC, &mphy->state)) {
|
||||
status->freq = mphy->chandef.chan->center_freq;
|
||||
status->band = mphy->chandef.chan->band;
|
||||
return;
|
||||
@ -1302,7 +1303,7 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data)
|
||||
if (pid == MT_PACKET_ID_NO_ACK)
|
||||
return;
|
||||
|
||||
if (wcidx >= ARRAY_SIZE(dev->mt76.wcid))
|
||||
if (wcidx >= MT7615_WTBL_SIZE)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
@ -1819,8 +1820,9 @@ void mt7615_dma_reset(struct mt7615_dev *dev)
|
||||
for (i = 0; i < __MT_TXQ_MAX; i++)
|
||||
mt76_queue_tx_cleanup(dev, i, true);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->mt76.q_rx); i++)
|
||||
mt76_for_each_q_rx(&dev->mt76, i) {
|
||||
mt76_queue_rx_reset(dev, i);
|
||||
}
|
||||
|
||||
mt76_set(dev, MT_WPDMA_GLO_CFG,
|
||||
MT_WPDMA_GLO_CFG_RX_DMA_EN | MT_WPDMA_GLO_CFG_TX_DMA_EN |
|
||||
@ -1849,8 +1851,13 @@ void mt7615_mac_reset_work(struct work_struct *work)
|
||||
set_bit(MT76_MCU_RESET, &dev->mphy.state);
|
||||
wake_up(&dev->mt76.mcu.wait);
|
||||
cancel_delayed_work_sync(&dev->phy.mac_work);
|
||||
if (phy2)
|
||||
del_timer_sync(&dev->phy.roc_timer);
|
||||
cancel_work_sync(&dev->phy.roc_work);
|
||||
if (phy2) {
|
||||
cancel_delayed_work_sync(&phy2->mac_work);
|
||||
del_timer_sync(&phy2->roc_timer);
|
||||
cancel_work_sync(&phy2->roc_work);
|
||||
}
|
||||
|
||||
/* lock/unlock all queues to ensure that no tx is pending */
|
||||
mt76_txq_schedule_all(&dev->mphy);
|
||||
|
@ -71,7 +71,8 @@ static void mt7615_stop(struct ieee80211_hw *hw)
|
||||
struct mt7615_phy *phy = mt7615_hw_phy(hw);
|
||||
|
||||
cancel_delayed_work_sync(&phy->mac_work);
|
||||
cancel_work_sync(&phy->ps_work);
|
||||
del_timer_sync(&phy->roc_timer);
|
||||
cancel_work_sync(&phy->roc_work);
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
@ -289,12 +290,11 @@ mt7615_queue_key_update(struct mt7615_dev *dev, enum set_key_cmd cmd,
|
||||
wd->type = MT7615_WTBL_KEY_DESC;
|
||||
wd->sta = msta;
|
||||
|
||||
wd->key.key = kzalloc(key->keylen, GFP_KERNEL);
|
||||
wd->key.key = kmemdup(key->key, key->keylen, GFP_KERNEL);
|
||||
if (!wd->key.key) {
|
||||
kfree(wd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(wd->key.key, key->key, key->keylen);
|
||||
wd->key.cipher = key->cipher;
|
||||
wd->key.keyidx = key->keyidx;
|
||||
wd->key.keylen = key->keylen;
|
||||
@ -360,20 +360,6 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
return mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
|
||||
}
|
||||
|
||||
void mt7615_ps_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7615_phy *phy;
|
||||
|
||||
phy = (struct mt7615_phy *)container_of(work, struct mt7615_phy,
|
||||
ps_work);
|
||||
|
||||
mutex_lock(&phy->dev->mt76.mutex);
|
||||
ieee80211_iterate_active_interfaces(phy->mt76->hw,
|
||||
IEEE80211_IFACE_ITER_RESUME_ALL,
|
||||
m7615_mcu_set_ps_iter, phy);
|
||||
mutex_unlock(&phy->dev->mt76.mutex);
|
||||
}
|
||||
|
||||
static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
|
||||
{
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
@ -399,14 +385,6 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
|
||||
mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_PS) {
|
||||
if (hw->conf.flags & IEEE80211_CONF_PS)
|
||||
set_bit(MT76_STATE_PS, &phy->mt76->state);
|
||||
else
|
||||
clear_bit(MT76_STATE_PS, &phy->mt76->state);
|
||||
ieee80211_queue_work(hw, &phy->ps_work);
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
|
||||
return ret;
|
||||
@ -509,6 +487,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
|
||||
BSS_CHANGED_BEACON_ENABLED))
|
||||
mt7615_mcu_add_beacon(dev, hw, vif, info->enable_beacon);
|
||||
|
||||
if (changed & BSS_CHANGED_PS)
|
||||
mt7615_mcu_set_vif_ps(dev, vif);
|
||||
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
}
|
||||
|
||||
@ -791,6 +772,37 @@ mt7615_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt7615_roc_iter(void *priv, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct mt7615_phy *phy = priv;
|
||||
|
||||
mt7615_mcu_set_roc(phy, vif, NULL, 0);
|
||||
}
|
||||
|
||||
void mt7615_roc_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7615_phy *phy;
|
||||
|
||||
phy = (struct mt7615_phy *)container_of(work, struct mt7615_phy,
|
||||
roc_work);
|
||||
|
||||
if (!test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state))
|
||||
return;
|
||||
|
||||
ieee80211_iterate_active_interfaces(phy->mt76->hw,
|
||||
IEEE80211_IFACE_ITER_RESUME_ALL,
|
||||
mt7615_roc_iter, phy);
|
||||
ieee80211_remain_on_channel_expired(phy->mt76->hw);
|
||||
}
|
||||
|
||||
void mt7615_roc_timer(struct timer_list *timer)
|
||||
{
|
||||
struct mt7615_phy *phy = from_timer(phy, timer, roc_timer);
|
||||
|
||||
ieee80211_queue_work(phy->mt76->hw, &phy->roc_work);
|
||||
}
|
||||
|
||||
void mt7615_scan_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7615_phy *phy;
|
||||
@ -864,6 +876,50 @@ mt7615_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
return mt7615_mcu_sched_scan_enable(mphy->priv, vif, false);
|
||||
}
|
||||
|
||||
static int mt7615_remain_on_channel(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel *chan,
|
||||
int duration,
|
||||
enum ieee80211_roc_type type)
|
||||
{
|
||||
struct mt7615_phy *phy = mt7615_hw_phy(hw);
|
||||
int err;
|
||||
|
||||
if (test_and_set_bit(MT76_STATE_ROC, &phy->mt76->state))
|
||||
return 0;
|
||||
|
||||
err = mt7615_mcu_set_roc(phy, vif, chan, duration);
|
||||
if (err < 0) {
|
||||
clear_bit(MT76_STATE_ROC, &phy->mt76->state);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!wait_event_timeout(phy->roc_wait, phy->roc_grant, HZ)) {
|
||||
mt7615_mcu_set_roc(phy, vif, NULL, 0);
|
||||
clear_bit(MT76_STATE_ROC, &phy->mt76->state);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7615_cancel_remain_on_channel(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct mt7615_phy *phy = mt7615_hw_phy(hw);
|
||||
|
||||
if (!test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state))
|
||||
return 0;
|
||||
|
||||
del_timer_sync(&phy->roc_timer);
|
||||
cancel_work_sync(&phy->roc_work);
|
||||
|
||||
mt7615_mcu_set_roc(phy, vif, NULL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int mt7615_suspend(struct ieee80211_hw *hw,
|
||||
struct cfg80211_wowlan *wowlan)
|
||||
@ -978,6 +1034,8 @@ const struct ieee80211_ops mt7615_ops = {
|
||||
.cancel_hw_scan = mt7615_cancel_hw_scan,
|
||||
.sched_scan_start = mt7615_start_sched_scan,
|
||||
.sched_scan_stop = mt7615_stop_sched_scan,
|
||||
.remain_on_channel = mt7615_remain_on_channel,
|
||||
.cancel_remain_on_channel = mt7615_cancel_remain_on_channel,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mt7615_suspend,
|
||||
.resume = mt7615_resume,
|
||||
|
@ -359,6 +359,33 @@ mt7615_mcu_scan_event(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||
MT7615_HW_SCAN_TIMEOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7615_mcu_roc_event(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||
{
|
||||
struct mt7615_roc_tlv *event;
|
||||
struct mt7615_phy *phy;
|
||||
struct mt76_phy *mphy;
|
||||
int duration;
|
||||
|
||||
skb_pull(skb, sizeof(struct mt7615_mcu_rxd));
|
||||
event = (struct mt7615_roc_tlv *)skb->data;
|
||||
|
||||
if (event->dbdc_band && dev->mt76.phy2)
|
||||
mphy = dev->mt76.phy2;
|
||||
else
|
||||
mphy = &dev->mt76.phy;
|
||||
|
||||
ieee80211_ready_on_channel(mphy->hw);
|
||||
|
||||
phy = (struct mt7615_phy *)mphy->priv;
|
||||
phy->roc_grant = true;
|
||||
wake_up(&phy->roc_wait);
|
||||
|
||||
duration = le32_to_cpu(event->max_interval);
|
||||
mod_timer(&phy->roc_timer,
|
||||
round_jiffies_up(jiffies + msecs_to_jiffies(duration)));
|
||||
}
|
||||
|
||||
static void
|
||||
mt7615_mcu_beacon_loss_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
||||
{
|
||||
@ -426,6 +453,9 @@ mt7615_mcu_rx_unsolicited_event(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||
case MCU_EVENT_BSS_BEACON_LOSS:
|
||||
mt7615_mcu_beacon_loss_event(dev, skb);
|
||||
break;
|
||||
case MCU_EVENT_ROC:
|
||||
mt7615_mcu_roc_event(dev, skb);
|
||||
break;
|
||||
case MCU_EVENT_SCHED_SCAN_DONE:
|
||||
case MCU_EVENT_SCAN_DONE:
|
||||
mt7615_mcu_scan_event(dev, skb);
|
||||
@ -451,6 +481,7 @@ void mt7615_mcu_rx_event(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||
rxd->eid == MCU_EVENT_SCHED_SCAN_DONE ||
|
||||
rxd->eid == MCU_EVENT_BSS_ABSENCE ||
|
||||
rxd->eid == MCU_EVENT_SCAN_DONE ||
|
||||
rxd->eid == MCU_EVENT_ROC ||
|
||||
!rxd->seq)
|
||||
mt7615_mcu_rx_unsolicited_event(dev, skb);
|
||||
else
|
||||
@ -2741,11 +2772,9 @@ int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable)
|
||||
sizeof(req), true);
|
||||
}
|
||||
|
||||
void m7615_mcu_set_ps_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
||||
int mt7615_mcu_set_vif_ps(struct mt7615_dev *dev, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||
struct mt7615_phy *phy = priv;
|
||||
struct mt76_phy *mphy = phy->mt76;
|
||||
struct {
|
||||
u8 bss_idx;
|
||||
u8 ps_state; /* 0: device awake
|
||||
@ -2754,12 +2783,14 @@ void m7615_mcu_set_ps_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
||||
*/
|
||||
} req = {
|
||||
.bss_idx = mvif->idx,
|
||||
.ps_state = test_bit(MT76_STATE_PS, &mphy->state) ? 2 : 0,
|
||||
.ps_state = vif->bss_conf.ps ? 2 : 0,
|
||||
};
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
__mt76_mcu_send_msg(&phy->dev->mt76, MCU_CMD_SET_PS_PROFILE,
|
||||
&req, sizeof(req), false);
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
return -ENOTSUPP;
|
||||
|
||||
return __mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_PS_PROFILE,
|
||||
&req, sizeof(req), false);
|
||||
}
|
||||
|
||||
int mt7615_mcu_set_channel_domain(struct mt7615_phy *phy)
|
||||
@ -2867,6 +2898,7 @@ int mt7615_mcu_hw_scan(struct mt7615_phy *phy, struct ieee80211_vif *vif,
|
||||
n_ssids++;
|
||||
}
|
||||
req->ssid_type = n_ssids ? BIT(2) : BIT(0);
|
||||
req->ssid_type_ext = n_ssids ? BIT(0) : 0;
|
||||
req->ssids_num = n_ssids;
|
||||
|
||||
/* increase channel time for passive scan */
|
||||
@ -3601,6 +3633,26 @@ int mt7615_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel *chan, int duration)
|
||||
{
|
||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||
struct mt7615_dev *dev = phy->dev;
|
||||
struct mt7615_roc_tlv req = {
|
||||
.bss_idx = mvif->idx,
|
||||
.active = !chan,
|
||||
.max_interval = cpu_to_le32(duration),
|
||||
.primary_chan = chan ? chan->hw_value : 0,
|
||||
.band = chan ? chan->band : 0,
|
||||
.req_type = 2,
|
||||
};
|
||||
|
||||
phy->roc_grant = false;
|
||||
|
||||
return __mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_ROC, &req,
|
||||
sizeof(req), false);
|
||||
}
|
||||
|
||||
int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
|
@ -82,6 +82,7 @@ enum {
|
||||
MCU_EVENT_ACCESS_REG = 0x02,
|
||||
MCU_EVENT_MT_PATCH_SEM = 0x04,
|
||||
MCU_EVENT_SCAN_DONE = 0x0d,
|
||||
MCU_EVENT_ROC = 0x10,
|
||||
MCU_EVENT_BSS_ABSENCE = 0x11,
|
||||
MCU_EVENT_BSS_BEACON_LOSS = 0x13,
|
||||
MCU_EVENT_CH_PRIVILEGE = 0x18,
|
||||
@ -326,7 +327,8 @@ struct mt7615_hw_scan_req {
|
||||
*/
|
||||
u8 ssid_type; /* BIT(0) wildcard SSID
|
||||
* BIT(1) P2P wildcard SSID
|
||||
* BIT(2) specified SSID
|
||||
* BIT(2) specified SSID + wildcard SSID
|
||||
* BIT(2) + ssid_type_ext BIT(0) specified SSID only
|
||||
*/
|
||||
u8 ssids_num;
|
||||
u8 probe_req_num; /* Number of probe request for each SSID */
|
||||
@ -361,7 +363,8 @@ struct mt7615_hw_scan_req {
|
||||
struct mt7615_mcu_scan_ssid ext_ssids[6];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 random_mac[ETH_ALEN]; /* valid when BIT(1) in scan_func is set. */
|
||||
u8 pad[64];
|
||||
u8 pad[63];
|
||||
u8 ssid_type_ext;
|
||||
} __packed;
|
||||
|
||||
#define SCAN_DONE_EVENT_MAX_CHANNEL_NUM 64
|
||||
@ -525,6 +528,23 @@ struct mt7615_gtk_rekey_tlv {
|
||||
u8 reserverd[3];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_roc_tlv {
|
||||
u8 bss_idx;
|
||||
u8 token;
|
||||
u8 active;
|
||||
u8 primary_chan;
|
||||
u8 sco;
|
||||
u8 band;
|
||||
u8 width; /* To support 80/160MHz bandwidth */
|
||||
u8 freq_seg1; /* To support 80/160MHz bandwidth */
|
||||
u8 freq_seg2; /* To support 80/160MHz bandwidth */
|
||||
u8 req_type;
|
||||
u8 dbdc_band;
|
||||
u8 rsv0;
|
||||
__le32 max_interval; /* ms */
|
||||
u8 rsv1[8];
|
||||
} __packed;
|
||||
|
||||
/* offload mcu commands */
|
||||
enum {
|
||||
MCU_CMD_START_HW_SCAN = MCU_CE_PREFIX | 0x03,
|
||||
@ -533,6 +553,7 @@ enum {
|
||||
MCU_CMD_SET_BSS_CONNECTED = MCU_CE_PREFIX | 0x16,
|
||||
MCU_CMD_SET_BSS_ABORT = MCU_CE_PREFIX | 0x17,
|
||||
MCU_CMD_CANCEL_HW_SCAN = MCU_CE_PREFIX | 0x1b,
|
||||
MCU_CMD_SET_ROC = MCU_CE_PREFIX | 0x1c,
|
||||
MCU_CMD_SET_P2P_OPPPS = MCU_CE_PREFIX | 0x33,
|
||||
MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61,
|
||||
MCU_CMD_SCHED_SCAN_REQ = MCU_CE_PREFIX | 0x62,
|
||||
|
@ -201,7 +201,10 @@ struct mt7615_phy {
|
||||
struct sk_buff_head scan_event_list;
|
||||
struct delayed_work scan_work;
|
||||
|
||||
struct work_struct ps_work;
|
||||
struct work_struct roc_work;
|
||||
struct timer_list roc_timer;
|
||||
wait_queue_head_t roc_wait;
|
||||
bool roc_grant;
|
||||
};
|
||||
|
||||
#define mt7615_mcu_add_tx_ba(dev, ...) (dev)->mcu_ops->add_tx_ba((dev), __VA_ARGS__)
|
||||
@ -411,7 +414,7 @@ static inline bool is_mt7622(struct mt76_dev *dev)
|
||||
|
||||
static inline bool is_mt7615(struct mt76_dev *dev)
|
||||
{
|
||||
return mt76_chip(dev) == 0x7615;
|
||||
return mt76_chip(dev) == 0x7615 || mt76_chip(dev) == 0x7611;
|
||||
}
|
||||
|
||||
static inline bool is_mt7663(struct mt76_dev *dev)
|
||||
@ -419,6 +422,11 @@ static inline bool is_mt7663(struct mt76_dev *dev)
|
||||
return mt76_chip(dev) == 0x7663;
|
||||
}
|
||||
|
||||
static inline bool is_mt7611(struct mt76_dev *dev)
|
||||
{
|
||||
return mt76_chip(dev) == 0x7611;
|
||||
}
|
||||
|
||||
static inline void mt7615_irq_enable(struct mt7615_dev *dev, u32 mask)
|
||||
{
|
||||
mt76_set_irq_mask(&dev->mt76, 0, 0, mask);
|
||||
@ -441,7 +449,8 @@ static inline u16 mt7615_wtbl_size(struct mt7615_dev *dev)
|
||||
|
||||
void mt7615_dma_reset(struct mt7615_dev *dev);
|
||||
void mt7615_scan_work(struct work_struct *work);
|
||||
void mt7615_ps_work(struct work_struct *work);
|
||||
void mt7615_roc_work(struct work_struct *work);
|
||||
void mt7615_roc_timer(struct timer_list *timer);
|
||||
void mt7615_init_txpower(struct mt7615_dev *dev,
|
||||
struct ieee80211_supported_band *sband);
|
||||
void mt7615_phy_init(struct mt7615_dev *dev);
|
||||
@ -527,11 +536,13 @@ int mt7615_mcu_set_radar_th(struct mt7615_dev *dev, int index,
|
||||
int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable);
|
||||
int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy);
|
||||
int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy);
|
||||
void m7615_mcu_set_ps_iter(void *priv, u8 *mac, struct ieee80211_vif *vif);
|
||||
int mt7615_mcu_set_vif_ps(struct mt7615_dev *dev, struct ieee80211_vif *vif);
|
||||
int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy);
|
||||
|
||||
int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel *chan, int duration);
|
||||
int mt7615_firmware_own(struct mt7615_dev *dev);
|
||||
int mt7615_driver_own(struct mt7615_dev *dev);
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
static const struct pci_device_id mt7615_pci_device_table[] = {
|
||||
{ PCI_DEVICE(0x14c3, 0x7615) },
|
||||
{ PCI_DEVICE(0x14c3, 0x7663) },
|
||||
{ PCI_DEVICE(0x14c3, 0x7611) },
|
||||
{ },
|
||||
};
|
||||
|
||||
@ -85,8 +86,9 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
napi_disable(&mdev->tx_napi);
|
||||
tasklet_kill(&mdev->tx_tasklet);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mdev->q_rx); i++)
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_disable(&mdev->napi[i]);
|
||||
}
|
||||
tasklet_kill(&dev->irq_tasklet);
|
||||
|
||||
mt7615_dma_reset(dev);
|
||||
@ -119,8 +121,9 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
return 0;
|
||||
|
||||
restore:
|
||||
for (i = 0; i < ARRAY_SIZE(mdev->q_rx); i++)
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_enable(&mdev->napi[i]);
|
||||
}
|
||||
napi_enable(&mdev->tx_napi);
|
||||
if (hif_suspend)
|
||||
mt7615_mcu_set_hif_suspend(dev, false);
|
||||
@ -155,7 +158,7 @@ static int mt7615_pci_resume(struct pci_dev *pdev)
|
||||
if (pdma_reset)
|
||||
dev_err(mdev->dev, "PDMA engine must be reinitialized\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mdev->q_rx); i++) {
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_enable(&mdev->napi[i]);
|
||||
napi_schedule(&mdev->napi[i]);
|
||||
}
|
||||
|
@ -51,7 +51,8 @@ static void mt7663u_stop(struct ieee80211_hw *hw)
|
||||
struct mt7615_dev *dev = hw->priv;
|
||||
|
||||
clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
|
||||
cancel_work_sync(&phy->ps_work);
|
||||
del_timer_sync(&phy->roc_timer);
|
||||
cancel_work_sync(&phy->roc_work);
|
||||
cancel_delayed_work_sync(&phy->scan_work);
|
||||
cancel_delayed_work_sync(&phy->mac_work);
|
||||
mt76u_stop_tx(&dev->mt76);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "mt76x02_dfs.h"
|
||||
#include "mt76x02_dma.h"
|
||||
|
||||
#define MT76x02_N_WCIDS 128
|
||||
#define MT_CALIBRATE_INTERVAL HZ
|
||||
#define MT_MAC_WORK_INTERVAL (HZ / 10)
|
||||
|
||||
@ -246,7 +247,7 @@ mt76x02_rx_get_sta(struct mt76_dev *dev, u8 idx)
|
||||
{
|
||||
struct mt76_wcid *wcid;
|
||||
|
||||
if (idx >= ARRAY_SIZE(dev->wcid))
|
||||
if (idx >= MT76x02_N_WCIDS)
|
||||
return NULL;
|
||||
|
||||
wcid = rcu_dereference(dev->wcid[idx]);
|
||||
|
@ -561,7 +561,7 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid))
|
||||
if (stat->wcid < MT76x02_N_WCIDS)
|
||||
wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]);
|
||||
|
||||
if (wcid && wcid->sta) {
|
||||
|
@ -20,7 +20,7 @@ int mt76x02_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
|
||||
int ret;
|
||||
u8 seq;
|
||||
|
||||
if (mt76_is_mmio(&dev->mt76) && dev->mcu_timeout)
|
||||
if (dev->mcu_timeout)
|
||||
return -EIO;
|
||||
|
||||
skb = mt76_mcu_msg_alloc(mdev, data, len);
|
||||
|
@ -415,7 +415,7 @@ static void mt76x02_reset_state(struct mt76x02_dev *dev)
|
||||
ieee80211_iter_keys_rcu(dev->mt76.hw, NULL, mt76x02_key_sync, NULL);
|
||||
rcu_read_unlock();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid); i++) {
|
||||
for (i = 0; i < MT76x02_N_WCIDS; i++) {
|
||||
struct ieee80211_sta *sta;
|
||||
struct ieee80211_vif *vif;
|
||||
struct mt76x02_sta *msta;
|
||||
@ -489,8 +489,9 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
|
||||
for (i = 0; i < __MT_TXQ_MAX; i++)
|
||||
mt76_queue_tx_cleanup(dev, i, true);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->mt76.q_rx); i++)
|
||||
mt76_for_each_q_rx(&dev->mt76, i) {
|
||||
mt76_queue_rx_reset(dev, i);
|
||||
}
|
||||
|
||||
mt76x02_mac_start(dev);
|
||||
|
||||
|
@ -249,7 +249,7 @@ int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
|
||||
|
||||
memset(msta, 0, sizeof(*msta));
|
||||
|
||||
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid));
|
||||
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT76x02_N_WCIDS);
|
||||
if (idx < 0)
|
||||
return -ENOSPC;
|
||||
|
||||
|
@ -173,14 +173,14 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
|
||||
|
||||
/* Tx Beamformee Rx NDPA & Tx feedback report */
|
||||
cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
|
||||
seq_printf(s, "Tx Beamformee sucessful feedback frames: %ld\n",
|
||||
seq_printf(s, "Tx Beamformee successful feedback frames: %ld\n",
|
||||
FIELD_GET(MT_ETBF_TX_FB_CPL, cnt));
|
||||
seq_printf(s, "Tx Beamformee feedback triggerd counts: %ld\n",
|
||||
seq_printf(s, "Tx Beamformee feedback triggered counts: %ld\n",
|
||||
FIELD_GET(MT_ETBF_TX_FB_TRI, cnt));
|
||||
|
||||
/* Tx SU counters */
|
||||
cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
|
||||
seq_printf(s, "Tx single-user sucessful MPDU counts: %d\n", cnt);
|
||||
seq_printf(s, "Tx single-user successful MPDU counts: %d\n", cnt);
|
||||
|
||||
seq_puts(s, "\n");
|
||||
}
|
||||
|
@ -592,7 +592,6 @@ int mt7915_register_ext_phy(struct mt7915_dev *dev)
|
||||
if (phy)
|
||||
return 0;
|
||||
|
||||
INIT_DELAYED_WORK(&phy->mac_work, mt7915_mac_work);
|
||||
mt7915_cap_dbdc_enable(dev);
|
||||
mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7915_ops);
|
||||
if (!mphy)
|
||||
@ -605,6 +604,8 @@ int mt7915_register_ext_phy(struct mt7915_dev *dev)
|
||||
mphy->antenna_mask = BIT(hweight8(phy->chainmask)) - 1;
|
||||
mt7915_init_wiphy(mphy->hw);
|
||||
|
||||
INIT_DELAYED_WORK(&phy->mac_work, mt7915_mac_work);
|
||||
|
||||
/*
|
||||
* Make the secondary PHY MAC address local without overlapping with
|
||||
* the usual MAC address allocation scheme on multiple virtual interfaces
|
||||
|
@ -235,9 +235,14 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
|
||||
.data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
|
||||
HE_BITS(DATA1_DATA_DCM_KNOWN) |
|
||||
HE_BITS(DATA1_STBC_KNOWN) |
|
||||
HE_BITS(DATA1_CODING_KNOWN),
|
||||
HE_BITS(DATA1_CODING_KNOWN) |
|
||||
HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |
|
||||
HE_BITS(DATA1_DOPPLER_KNOWN) |
|
||||
HE_BITS(DATA1_BSS_COLOR_KNOWN),
|
||||
.data2 = HE_BITS(DATA2_GI_KNOWN) |
|
||||
HE_BITS(DATA2_TXBF_KNOWN),
|
||||
HE_BITS(DATA2_TXBF_KNOWN) |
|
||||
HE_BITS(DATA2_PE_DISAMBIG_KNOWN) |
|
||||
HE_BITS(DATA2_TXOP_KNOWN),
|
||||
};
|
||||
struct ieee80211_radiotap_he *he = NULL;
|
||||
__le32 v2 = rxv->v[2];
|
||||
@ -248,12 +253,6 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
|
||||
he = skb_push(skb, sizeof(known));
|
||||
memcpy(he, &known, sizeof(known));
|
||||
|
||||
he->data1 = HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |
|
||||
HE_BITS(DATA1_DOPPLER_KNOWN) |
|
||||
HE_BITS(DATA1_BSS_COLOR_KNOWN);
|
||||
he->data2 = HE_BITS(DATA2_PE_DISAMBIG_KNOWN) |
|
||||
HE_BITS(DATA2_TXOP_KNOWN);
|
||||
|
||||
he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, v14) |
|
||||
HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, v2);
|
||||
he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, v2) |
|
||||
@ -296,10 +295,10 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
|
||||
HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
|
||||
HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
|
||||
|
||||
he->data4 = HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, v11) |
|
||||
HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, v11) |
|
||||
HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, v11) |
|
||||
HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, v11);
|
||||
he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, v11) |
|
||||
HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, v11) |
|
||||
HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, v11) |
|
||||
HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, v11);
|
||||
|
||||
mt7915_mac_decode_he_radiotap_ru(status, rxv, he);
|
||||
break;
|
||||
@ -426,20 +425,26 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
|
||||
/* RXD Group 3 - P-RXV */
|
||||
if (rxd1 & MT_RXD1_NORMAL_GROUP_3) {
|
||||
u32 v0, v1, v2;
|
||||
|
||||
memcpy(rxv.v, rxd, sizeof(rxv.v));
|
||||
|
||||
rxd += 2;
|
||||
if ((u8 *)rxd - skb->data >= skb->len)
|
||||
return -EINVAL;
|
||||
|
||||
if (rxv.v[0] & MT_PRXV_HT_AD_CODE)
|
||||
v0 = le32_to_cpu(rxv.v[0]);
|
||||
v1 = le32_to_cpu(rxv.v[1]);
|
||||
v2 = le32_to_cpu(rxv.v[2]);
|
||||
|
||||
if (v0 & MT_PRXV_HT_AD_CODE)
|
||||
status->enc_flags |= RX_ENC_FLAG_LDPC;
|
||||
|
||||
status->chains = mphy->antenna_mask;
|
||||
status->chain_signal[0] = to_rssi(MT_PRXV_RCPI0, rxv.v[1]);
|
||||
status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, rxv.v[1]);
|
||||
status->chain_signal[2] = to_rssi(MT_PRXV_RCPI2, rxv.v[1]);
|
||||
status->chain_signal[3] = to_rssi(MT_PRXV_RCPI3, rxv.v[1]);
|
||||
status->chain_signal[0] = to_rssi(MT_PRXV_RCPI0, v1);
|
||||
status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, v1);
|
||||
status->chain_signal[2] = to_rssi(MT_PRXV_RCPI2, v1);
|
||||
status->chain_signal[3] = to_rssi(MT_PRXV_RCPI3, v1);
|
||||
status->signal = status->chain_signal[0];
|
||||
|
||||
for (i = 1; i < hweight8(mphy->antenna_mask); i++) {
|
||||
@ -452,16 +457,16 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
|
||||
/* RXD Group 5 - C-RXV */
|
||||
if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
|
||||
u8 stbc = FIELD_GET(MT_CRXV_HT_STBC, rxv.v[2]);
|
||||
u8 gi = FIELD_GET(MT_CRXV_HT_SHORT_GI, rxv.v[2]);
|
||||
u8 stbc = FIELD_GET(MT_CRXV_HT_STBC, v2);
|
||||
u8 gi = FIELD_GET(MT_CRXV_HT_SHORT_GI, v2);
|
||||
bool cck = false;
|
||||
|
||||
rxd += 18;
|
||||
if ((u8 *)rxd - skb->data >= skb->len)
|
||||
return -EINVAL;
|
||||
|
||||
idx = i = FIELD_GET(MT_PRXV_TX_RATE, rxv.v[0]);
|
||||
rxv.phy = FIELD_GET(MT_CRXV_TX_MODE, rxv.v[2]);
|
||||
idx = i = FIELD_GET(MT_PRXV_TX_RATE, v0);
|
||||
rxv.phy = FIELD_GET(MT_CRXV_TX_MODE, v2);
|
||||
|
||||
switch (rxv.phy) {
|
||||
case MT_PHY_TYPE_CCK:
|
||||
@ -478,7 +483,7 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
break;
|
||||
case MT_PHY_TYPE_VHT:
|
||||
status->nss =
|
||||
FIELD_GET(MT_PRXV_NSTS, rxv.v[0]) + 1;
|
||||
FIELD_GET(MT_PRXV_NSTS, v0) + 1;
|
||||
status->encoding = RX_ENC_VHT;
|
||||
if (i > 9)
|
||||
return -EINVAL;
|
||||
@ -490,7 +495,7 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
case MT_PHY_TYPE_HE_EXT_SU:
|
||||
case MT_PHY_TYPE_HE_TB:
|
||||
status->nss =
|
||||
FIELD_GET(MT_PRXV_NSTS, rxv.v[0]) + 1;
|
||||
FIELD_GET(MT_PRXV_NSTS, v0) + 1;
|
||||
status->encoding = RX_ENC_HE;
|
||||
status->flag |= RX_FLAG_RADIOTAP_HE;
|
||||
i &= GENMASK(3, 0);
|
||||
@ -506,7 +511,7 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
}
|
||||
status->rate_idx = i;
|
||||
|
||||
switch (FIELD_GET(MT_CRXV_FRAME_MODE, rxv.v[2])) {
|
||||
switch (FIELD_GET(MT_CRXV_FRAME_MODE, v2)) {
|
||||
case IEEE80211_STA_RX_BW_20:
|
||||
break;
|
||||
case IEEE80211_STA_RX_BW_40:
|
||||
@ -612,7 +617,7 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
|
||||
skb->priority & IEEE80211_QOS_CTL_TID_MASK) |
|
||||
FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
|
||||
if (ext_phy && q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0)
|
||||
val |= cpu_to_le32(MT_TXD1_TGID);
|
||||
val |= MT_TXD1_TGID;
|
||||
|
||||
txwi[1] = cpu_to_le32(val);
|
||||
|
||||
@ -1141,8 +1146,9 @@ mt7915_dma_reset(struct mt7915_dev *dev)
|
||||
for (i = 0; i < __MT_TXQ_MAX; i++)
|
||||
mt76_queue_tx_cleanup(dev, i, true);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->mt76.q_rx); i++)
|
||||
mt76_for_each_q_rx(&dev->mt76, i) {
|
||||
mt76_queue_rx_reset(dev, i);
|
||||
}
|
||||
|
||||
/* re-init prefetch settings after reset */
|
||||
mt7915_dma_prefetch(dev);
|
||||
|
@ -437,8 +437,10 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
|
||||
mt7915_mcu_add_sta(dev, vif, NULL, join);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ASSOC)
|
||||
if (changed & BSS_CHANGED_ASSOC) {
|
||||
mt7915_mcu_add_bss_info(phy, vif, info->assoc);
|
||||
mt7915_mcu_add_obss_spr(dev, vif, info->he_obss_pd.enable);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_SLOT) {
|
||||
int slottime = info->use_short_slot ? 9 : 20;
|
||||
@ -458,6 +460,9 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
|
||||
if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
|
||||
mt7915_mcu_set_tx(dev, vif);
|
||||
|
||||
if (changed & BSS_CHANGED_HE_OBSS_PD)
|
||||
mt7915_mcu_add_obss_spr(dev, vif, info->he_obss_pd.enable);
|
||||
|
||||
if (changed & (BSS_CHANGED_BEACON |
|
||||
BSS_CHANGED_BEACON_ENABLED))
|
||||
mt7915_mcu_add_beacon(hw, vif, info->enable_beacon);
|
||||
@ -790,7 +795,7 @@ mt7915_sta_rc_update(struct ieee80211_hw *hw,
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
rcu_read_lock();
|
||||
rcu_read_unlock();
|
||||
|
||||
set_bit(changed, &msta->stats.changed);
|
||||
ieee80211_queue_work(hw, &msta->stats_work);
|
||||
|
@ -220,7 +220,7 @@ static int __mt7915_mcu_msg_send(struct mt7915_dev *dev, struct sk_buff *skb,
|
||||
{
|
||||
struct mt7915_mcu_txd *mcu_txd;
|
||||
u8 seq, pkt_fmt, qidx;
|
||||
enum mt7915_txq_id txq;
|
||||
enum mt76_txq_id txq;
|
||||
__le32 *txd;
|
||||
u32 val;
|
||||
|
||||
@ -815,8 +815,7 @@ static void mt7915_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
|
||||
struct mt7915_he_obss_narrow_bw_ru_data *data = _data;
|
||||
const struct element *elem;
|
||||
|
||||
elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data,
|
||||
bss->ies->len);
|
||||
elem = ieee80211_bss_get_elem(bss, WLAN_EID_EXT_CAPABILITY);
|
||||
|
||||
if (!elem || elem->datalen < 10 ||
|
||||
!(elem->data[10] &
|
||||
@ -1802,15 +1801,12 @@ static u8
|
||||
mt7915_mcu_sta_txbf_type(struct mt7915_phy *phy, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct mt7915_sta *msta;
|
||||
u8 type = 0;
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION &&
|
||||
vif->type != NL80211_IFTYPE_AP)
|
||||
return 0;
|
||||
|
||||
msta = (struct mt7915_sta *)sta->drv_priv;
|
||||
|
||||
if (sta->he_cap.has_he) {
|
||||
struct ieee80211_he_cap_elem *pe;
|
||||
const struct ieee80211_he_cap_elem *ve;
|
||||
@ -1954,7 +1950,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
|
||||
|
||||
ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs;
|
||||
ra->supp_mode |= MODE_HT;
|
||||
mcs = hweight32(ra->supp_ht_mcs) - 1;
|
||||
mcs = hweight32(le32_to_cpu(ra->supp_ht_mcs)) - 1;
|
||||
ra->af = sta->ht_cap.ampdu_factor;
|
||||
ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
|
||||
|
||||
@ -1972,7 +1968,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
|
||||
}
|
||||
|
||||
if (sta->vht_cap.vht_supported) {
|
||||
__le16 mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
|
||||
u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map);
|
||||
u16 vht_mcs;
|
||||
u8 af, mcs_prev;
|
||||
|
||||
@ -2399,7 +2395,7 @@ static int mt7915_mcu_init_download(struct mt7915_dev *dev, u32 addr,
|
||||
};
|
||||
int attr;
|
||||
|
||||
if (req.addr == MCU_PATCH_ADDRESS)
|
||||
if (req.addr == cpu_to_le32(MCU_PATCH_ADDRESS))
|
||||
attr = -MCU_CMD_PATCH_START_REQ;
|
||||
else
|
||||
attr = -MCU_CMD_TARGET_ADDRESS_LEN_REQ;
|
||||
@ -2672,7 +2668,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level)
|
||||
u16 len;
|
||||
u8 level;
|
||||
u8 rsv[3];
|
||||
u32 module_idx;
|
||||
__le32 module_idx;
|
||||
} data = {
|
||||
.module_idx = cpu_to_le32(module),
|
||||
.level = level,
|
||||
@ -3159,3 +3155,28 @@ int mt7915_mcu_set_txbf_sounding(struct mt7915_dev *dev)
|
||||
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_TXBF_ACTION,
|
||||
&req, sizeof(req), true);
|
||||
}
|
||||
|
||||
int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
|
||||
bool enable)
|
||||
{
|
||||
#define MT_SPR_ENABLE 1
|
||||
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
|
||||
struct {
|
||||
u8 action;
|
||||
u8 arg_num;
|
||||
u8 band_idx;
|
||||
u8 status;
|
||||
u8 drop_tx_idx;
|
||||
u8 sta_idx; /* 256 sta */
|
||||
u8 rsv[2];
|
||||
u32 val;
|
||||
} __packed req = {
|
||||
.action = MT_SPR_ENABLE,
|
||||
.arg_num = 1,
|
||||
.band_idx = mvif->band_idx,
|
||||
.val = enable,
|
||||
};
|
||||
|
||||
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_SPR,
|
||||
&req, sizeof(req), true);
|
||||
}
|
||||
|
@ -212,6 +212,7 @@ enum {
|
||||
MCU_EXT_CMD_RATE_CTRL = 0x87,
|
||||
MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
|
||||
MCU_EXT_CMD_SET_RDD_TH = 0x9d,
|
||||
MCU_EXT_CMD_SET_SPR = 0xa8,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -301,6 +301,8 @@ int mt7915_mcu_add_key(struct mt7915_dev *dev, struct ieee80211_vif *vif,
|
||||
enum set_key_cmd cmd);
|
||||
int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
int enable);
|
||||
int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
|
||||
bool enable);
|
||||
int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
|
||||
|
@ -42,17 +42,17 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__mt76_poll_msec);
|
||||
|
||||
int mt76_wcid_alloc(unsigned long *mask, int size)
|
||||
int mt76_wcid_alloc(u32 *mask, int size)
|
||||
{
|
||||
int i, idx = 0, cur;
|
||||
|
||||
for (i = 0; i < DIV_ROUND_UP(size, BITS_PER_LONG); i++) {
|
||||
for (i = 0; i < DIV_ROUND_UP(size, 32); i++) {
|
||||
idx = ffs(~mask[i]);
|
||||
if (!idx)
|
||||
continue;
|
||||
|
||||
idx--;
|
||||
cur = i * BITS_PER_LONG + idx;
|
||||
cur = i * 32 + idx;
|
||||
if (cur >= size)
|
||||
break;
|
||||
|
||||
@ -74,13 +74,13 @@ int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy)
|
||||
rcu_read_lock();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->wcid_mask); i++) {
|
||||
unsigned long mask = dev->wcid_mask[i];
|
||||
unsigned long phy_mask = dev->wcid_phy_mask[i];
|
||||
u32 mask = dev->wcid_mask[i];
|
||||
u32 phy_mask = dev->wcid_phy_mask[i];
|
||||
|
||||
if (!mask)
|
||||
continue;
|
||||
|
||||
for (j = i * BITS_PER_LONG; mask; j++, mask >>= 1, phy_mask >>= 1) {
|
||||
for (j = i * 32; mask; j++, mask >>= 1, phy_mask >>= 1) {
|
||||
if (!(mask & 1))
|
||||
continue;
|
||||
|
||||
|
@ -14,24 +14,24 @@
|
||||
#define MT76_INCR(_var, _size) \
|
||||
(_var = (((_var) + 1) % (_size)))
|
||||
|
||||
int mt76_wcid_alloc(unsigned long *mask, int size);
|
||||
int mt76_wcid_alloc(u32 *mask, int size);
|
||||
|
||||
static inline bool
|
||||
mt76_wcid_mask_test(unsigned long *mask, int idx)
|
||||
mt76_wcid_mask_test(u32 *mask, int idx)
|
||||
{
|
||||
return mask[idx / BITS_PER_LONG] & BIT(idx % BITS_PER_LONG);
|
||||
return mask[idx / 32] & BIT(idx % 32);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mt76_wcid_mask_set(unsigned long *mask, int idx)
|
||||
mt76_wcid_mask_set(u32 *mask, int idx)
|
||||
{
|
||||
mask[idx / BITS_PER_LONG] |= BIT(idx % BITS_PER_LONG);
|
||||
mask[idx / 32] |= BIT(idx % 32);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mt76_wcid_mask_clear(unsigned long *mask, int idx)
|
||||
mt76_wcid_mask_clear(u32 *mask, int idx)
|
||||
{
|
||||
mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG);
|
||||
mask[idx / 32] &= ~BIT(idx % 32);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
Loading…
x
Reference in New Issue
Block a user