Skip to content

Commit

Permalink
Merge tag 'mt76-for-kvalo-2020-05-28' of https://github.com/nbd168/wi…
Browse files Browse the repository at this point in the history
…reless

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
  • Loading branch information
Kalle Valo committed May 29, 2020
2 parents 982d728 + d9045b1 commit 5cf2740
Show file tree
Hide file tree
Showing 27 changed files with 335 additions and 124 deletions.
2 changes: 1 addition & 1 deletion drivers/net/wireless/mediatek/mt76/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/mediatek/mt76/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down Expand Up @@ -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]);
}
Expand Down
10 changes: 7 additions & 3 deletions drivers/net/wireless/mediatek/mt76/mt76.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/wireless/mediatek/mt76/mt7603/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);

Expand Down
7 changes: 7 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down
22 changes: 15 additions & 7 deletions drivers/net/wireless/mediatek/mt76/mt7615/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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);

/*
Expand Down Expand Up @@ -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;
Expand Down
17 changes: 12 additions & 5 deletions drivers/net/wireless/mediatek/mt76/mt7615/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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);
Expand Down
108 changes: 83 additions & 25 deletions drivers/net/wireless/mediatek/mt76/mt7615/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 5cf2740

Please sign in to comment.