diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7603')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/core.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/init.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 191 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/main.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/mcu.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h | 15 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7603/regs.h | 6 |
10 files changed, 201 insertions, 110 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/core.c b/drivers/net/wireless/mediatek/mt76/mt7603/core.c index 37e5644b45ef..e7ee58e3379c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/core.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/core.c @@ -35,7 +35,7 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance) if (intr & MT_INT_TX_DONE_ALL) { mt7603_irq_disable(dev, MT_INT_TX_DONE_ALL); - tasklet_schedule(&dev->mt76.tx_tasklet); + napi_schedule(&dev->mt76.tx_napi); } if (intr & MT_INT_RX_DONE(0)) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c index f8b3b6ab6297..a1bc3103cbe9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c @@ -40,6 +40,35 @@ mt7603_radio_read(struct seq_file *s, void *data) return 0; } +static int +mt7603_edcca_set(void *data, u64 val) +{ + struct mt7603_dev *dev = data; + + mutex_lock(&dev->mt76.mutex); + + dev->ed_monitor_enabled = !!val; + dev->ed_monitor = dev->ed_monitor_enabled && + dev->mt76.region == NL80211_DFS_ETSI; + mt7603_init_edcca(dev); + + mutex_unlock(&dev->mt76.mutex); + + return 0; +} + +static int +mt7603_edcca_get(void *data, u64 *val) +{ + struct mt7603_dev *dev = data; + + *val = dev->ed_monitor_enabled; + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_edcca, mt7603_edcca_get, + mt7603_edcca_set, "%lld\n"); + void mt7603_init_debugfs(struct mt7603_dev *dev) { struct dentry *dir; @@ -48,6 +77,7 @@ void mt7603_init_debugfs(struct mt7603_dev *dev) if (!dir) return; + debugfs_create_file("edcca", 0600, dir, dev, &fops_edcca); debugfs_create_u32("reset_test", 0600, dir, &dev->reset_test); debugfs_create_devm_seqfile(dev->mt76.dev, "reset", dir, mt7603_reset_read); diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c index 27e2d9f90553..58dc511f93c5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c @@ -139,15 +139,30 @@ static void mt7603_tx_tasklet(unsigned long data) { struct mt7603_dev *dev = (struct mt7603_dev *)data; + + mt76_txq_schedule_all(&dev->mt76); +} + +static int mt7603_poll_tx(struct napi_struct *napi, int budget) +{ + struct mt7603_dev *dev; int i; + dev = container_of(napi, struct mt7603_dev, mt76.tx_napi); dev->tx_dma_check = 0; + for (i = MT_TXQ_MCU; i >= 0; i--) mt76_queue_tx_cleanup(dev, i, false); - mt76_txq_schedule_all(&dev->mt76); + if (napi_complete_done(napi, 0)) + mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL); - mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL); + for (i = MT_TXQ_MCU; i >= 0; i--) + mt76_queue_tx_cleanup(dev, i, false); + + tasklet_schedule(&dev->mt76.tx_tasklet); + + return 0; } int mt7603_dma_init(struct mt7603_dev *dev) @@ -216,7 +231,15 @@ int mt7603_dma_init(struct mt7603_dev *dev) return ret; mt76_wr(dev, MT_DELAY_INT_CFG, 0); - return mt76_init_queues(dev); + ret = mt76_init_queues(dev); + if (ret) + return ret; + + netif_tx_napi_add(&dev->mt76.napi_dev, &dev->mt76.tx_napi, + mt7603_poll_tx, NAPI_POLL_WEIGHT); + napi_enable(&dev->mt76.tx_napi); + + return 0; } void mt7603_dma_cleanup(struct mt7603_dev *dev) diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h index f27b99b7e359..b893facfba48 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h +++ b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h @@ -69,6 +69,8 @@ enum mt7603_eeprom_field { MT_EE_CP_FT_VERSION = 0x0f0, + MT_EE_TX_POWER_TSSI_OFF = 0x0f2, + MT_EE_XTAL_FREQ_OFFSET = 0x0f4, MT_EE_XTAL_TRIM_2_COMP = 0x0f5, MT_EE_XTAL_TRIM_3_COMP = 0x0f6, diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c index 78cdbb70e178..38834c7d0891 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c @@ -227,11 +227,19 @@ mt7603_mac_init(struct mt7603_dev *dev) mt76_rmw_field(dev, MT_LPON_BTEIR, MT_LPON_BTEIR_MBSS_MODE, 2); mt76_rmw_field(dev, MT_WF_RMACDR, MT_WF_RMACDR_MBSSID_MASK, 2); - mt76_wr(dev, MT_AGG_ARUCR, FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7)); + mt76_wr(dev, MT_AGG_ARUCR, + FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), 2) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), 2) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), 2) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), 1) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), 1) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), 1) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), 1)); + mt76_wr(dev, MT_AGG_ARDCR, - FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 0) | - FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), - max_t(int, 0, MT7603_RATE_RETRY - 2)) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), MT7603_RATE_RETRY - 1) | + FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), MT7603_RATE_RETRY - 1) | FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7603_RATE_RETRY - 1) | FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7603_RATE_RETRY - 1) | FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7603_RATE_RETRY - 1) | @@ -437,7 +445,9 @@ mt7603_regd_notifier(struct wiphy *wiphy, struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct mt7603_dev *dev = hw->priv; - dev->ed_monitor = request->dfs_region == NL80211_DFS_ETSI; + dev->mt76.region = request->dfs_region; + dev->ed_monitor = dev->ed_monitor_enabled && + dev->mt76.region == NL80211_DFS_ETSI; } static int @@ -463,9 +473,13 @@ mt7603_init_txpower(struct mt7603_dev *dev, u8 *eeprom = (u8 *)dev->mt76.eeprom.data; int target_power = eeprom[MT_EE_TX_POWER_0_START_2G + 2] & ~BIT(7); u8 *rate_power = &eeprom[MT_EE_TX_POWER_CCK]; + bool ext_pa = eeprom[MT_EE_NIC_CONF_0 + 1] & BIT(1); int max_offset, cur_offset; int i; + if (ext_pa && is_mt7603(dev)) + target_power = eeprom[MT_EE_TX_POWER_TSSI_OFF] & ~BIT(7); + if (target_power & BIT(6)) target_power = -(target_power & GENMASK(5, 0)); @@ -488,7 +502,7 @@ mt7603_init_txpower(struct mt7603_dev *dev, for (i = 0; i < sband->n_channels; i++) { chan = &sband->channels[i]; - chan->max_power = target_power; + chan->max_power = min_t(int, chan->max_reg_power, target_power); chan->orig_mpwr = target_power; } } diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c index 6d506e34c3ee..40db1cbc832d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c @@ -370,31 +370,6 @@ void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid, mt76_rmw(dev, addr + (15 * 4), tid_mask, tid_val); } -static int -mt7603_get_rate(struct mt7603_dev *dev, struct ieee80211_supported_band *sband, - int idx, bool cck) -{ - int offset = 0; - int len = sband->n_bitrates; - int i; - - if (cck) { - if (sband == &dev->mt76.sband_5g.sband) - return 0; - - idx &= ~BIT(2); /* short preamble */ - } else if (sband == &dev->mt76.sband_2g.sband) { - offset = 4; - } - - for (i = offset; i < len; i++) { - if ((sband->bitrates[i].hw_value & GENMASK(7, 0)) == idx) - return i; - } - - return 0; -} - static struct mt76_wcid * mt7603_rx_get_wcid(struct mt7603_dev *dev, u8 idx, bool unicast) { @@ -418,30 +393,6 @@ mt7603_rx_get_wcid(struct mt7603_dev *dev, u8 idx, bool unicast) return &sta->vif->sta.wcid; } -static void -mt7603_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id) -{ - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - int hdr_len = ieee80211_get_hdrlen_from_skb(skb); - u8 *pn = status->iv; - u8 *hdr; - - __skb_push(skb, 8); - memmove(skb->data, skb->data + 8, hdr_len); - hdr = skb->data + hdr_len; - - hdr[0] = pn[5]; - hdr[1] = pn[4]; - hdr[2] = 0; - hdr[3] = 0x20 | (key_id << 6); - hdr[4] = pn[3]; - hdr[5] = pn[2]; - hdr[6] = pn[1]; - hdr[7] = pn[0]; - - status->flag &= ~RX_FLAG_IV_STRIPPED; -} - int mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) { @@ -532,7 +483,7 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) cck = true; /* fall through */ case MT_PHY_TYPE_OFDM: - i = mt7603_get_rate(dev, sband, i, cck); + i = mt76_get_rate(&dev->mt76, sband, i, cck); break; case MT_PHY_TYPE_HT_GF: case MT_PHY_TYPE_HT: @@ -580,7 +531,7 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) if (insert_ccmp_hdr) { u8 key_id = FIELD_GET(MT_RXD1_NORMAL_KEY_ID, rxd1); - mt7603_insert_ccmp_hdr(skb, key_id); + mt76_insert_ccmp_hdr(skb, key_id); } hdr = (struct ieee80211_hdr *)skb->data; @@ -640,6 +591,7 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta, struct ieee80211_tx_rate *probe_rate, struct ieee80211_tx_rate *rates) { + struct ieee80211_tx_rate *ref; int wcid = sta->wcid.idx; u32 addr = mt7603_wtbl2_addr(wcid); bool stbc = false; @@ -648,7 +600,8 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta, u16 val[4]; u16 probe_val; u32 w9 = mt76_rr(dev, addr + 9 * 4); - int i; + bool rateset; + int i, k; if (!mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000)) return; @@ -656,6 +609,41 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta, for (i = n_rates; i < 4; i++) rates[i] = rates[n_rates - 1]; + rateset = !(sta->rate_set_tsf & BIT(0)); + memcpy(sta->rateset[rateset].rates, rates, + sizeof(sta->rateset[rateset].rates)); + if (probe_rate) { + sta->rateset[rateset].probe_rate = *probe_rate; + ref = &sta->rateset[rateset].probe_rate; + } else { + sta->rateset[rateset].probe_rate.idx = -1; + ref = &sta->rateset[rateset].rates[0]; + } + + rates = sta->rateset[rateset].rates; + for (i = 0; i < ARRAY_SIZE(sta->rateset[rateset].rates); i++) { + /* + * We don't support switching between short and long GI + * within the rate set. For accurate tx status reporting, we + * need to make sure that flags match. + * For improved performance, avoid duplicate entries by + * decrementing the MCS index if necessary + */ + if ((ref->flags ^ rates[i].flags) & IEEE80211_TX_RC_SHORT_GI) + rates[i].flags ^= IEEE80211_TX_RC_SHORT_GI; + + for (k = 0; k < i; k++) { + if (rates[i].idx != rates[k].idx) + continue; + if ((rates[i].flags ^ rates[k].flags) & + IEEE80211_TX_RC_40_MHZ_WIDTH) + continue; + + rates[i].idx--; + } + + } + w9 &= MT_WTBL2_W9_SHORT_GI_20 | MT_WTBL2_W9_SHORT_GI_40 | MT_WTBL2_W9_SHORT_GI_80; @@ -699,19 +687,22 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta, mt76_wr(dev, MT_WTBL_RIUCR1, FIELD_PREP(MT_WTBL_RIUCR1_RATE0, probe_val) | FIELD_PREP(MT_WTBL_RIUCR1_RATE1, val[0]) | - FIELD_PREP(MT_WTBL_RIUCR1_RATE2_LO, val[0])); + FIELD_PREP(MT_WTBL_RIUCR1_RATE2_LO, val[1])); mt76_wr(dev, MT_WTBL_RIUCR2, - FIELD_PREP(MT_WTBL_RIUCR2_RATE2_HI, val[0] >> 8) | + FIELD_PREP(MT_WTBL_RIUCR2_RATE2_HI, val[1] >> 8) | FIELD_PREP(MT_WTBL_RIUCR2_RATE3, val[1]) | - FIELD_PREP(MT_WTBL_RIUCR2_RATE4, val[1]) | + FIELD_PREP(MT_WTBL_RIUCR2_RATE4, val[2]) | FIELD_PREP(MT_WTBL_RIUCR2_RATE5_LO, val[2])); mt76_wr(dev, MT_WTBL_RIUCR3, FIELD_PREP(MT_WTBL_RIUCR3_RATE5_HI, val[2] >> 4) | - FIELD_PREP(MT_WTBL_RIUCR3_RATE6, val[2]) | + FIELD_PREP(MT_WTBL_RIUCR3_RATE6, val[3]) | FIELD_PREP(MT_WTBL_RIUCR3_RATE7, val[3])); + mt76_set(dev, MT_LPON_T0CR, MT_LPON_T0CR_MODE); /* TSF read */ + sta->rate_set_tsf = (mt76_rr(dev, MT_LPON_UTTR0) & ~BIT(0)) | rateset; + mt76_wr(dev, MT_WTBL_UPDATE, FIELD_PREP(MT_WTBL_UPDATE_WLAN_IDX, wcid) | MT_WTBL_UPDATE_RATE_UPDATE | @@ -938,9 +929,9 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { spin_lock_bh(&dev->mt76.lock); - msta->rate_probe = true; mt7603_wtbl_set_rates(dev, msta, &info->control.rates[0], msta->rates); + msta->rate_probe = true; spin_unlock_bh(&dev->mt76.lock); } @@ -955,10 +946,12 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta, struct ieee80211_tx_info *info, __le32 *txs_data) { struct ieee80211_supported_band *sband; - int final_idx = 0; + struct mt7603_rate_set *rs; + int first_idx = 0, last_idx; + u32 rate_set_tsf; u32 final_rate; u32 final_rate_flags; - bool final_mpdu; + bool rs_idx; bool ack_timeout; bool fixed_rate; bool probe; @@ -966,7 +959,6 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta, bool cck = false; int count; u32 txs; - u8 pid; int idx; int i; @@ -974,10 +966,9 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta, probe = !!(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); txs = le32_to_cpu(txs_data[4]); - final_mpdu = txs & MT_TXS4_ACKED_MPDU; ampdu = !fixed_rate && (txs & MT_TXS4_AMPDU); - pid = FIELD_GET(MT_TXS4_PID, txs); count = FIELD_GET(MT_TXS4_TX_COUNT, txs); + last_idx = FIELD_GET(MT_TXS4_LAST_TX_RATE, txs); txs = le32_to_cpu(txs_data[0]); final_rate = FIELD_GET(MT_TXS0_TX_RATE, txs); @@ -999,38 +990,57 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta, if (ampdu || (info->flags & IEEE80211_TX_CTL_AMPDU)) info->flags |= IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_CTL_AMPDU; + first_idx = max_t(int, 0, last_idx - (count + 1) / MT7603_RATE_RETRY); + if (fixed_rate && !probe) { info->status.rates[0].count = count; + i = 0; goto out; } - for (i = 0, idx = 0; i < ARRAY_SIZE(info->status.rates); i++) { - int cur_count = min_t(int, count, 2 * MT7603_RATE_RETRY); + rate_set_tsf = READ_ONCE(sta->rate_set_tsf); + rs_idx = !((u32)(FIELD_GET(MT_TXS1_F0_TIMESTAMP, le32_to_cpu(txs_data[1])) - + rate_set_tsf) < 1000000); + rs_idx ^= rate_set_tsf & BIT(0); + rs = &sta->rateset[rs_idx]; - if (!i && probe) { - cur_count = 1; - } else { - info->status.rates[i] = sta->rates[idx]; - idx++; - } + if (!first_idx && rs->probe_rate.idx >= 0) { + info->status.rates[0] = rs->probe_rate; - if (i && info->status.rates[i].idx < 0) { - info->status.rates[i - 1].count += count; - break; + spin_lock_bh(&dev->mt76.lock); + if (sta->rate_probe) { + mt7603_wtbl_set_rates(dev, sta, NULL, + sta->rates); + sta->rate_probe = false; } + spin_unlock_bh(&dev->mt76.lock); + } else + info->status.rates[0] = rs->rates[first_idx / 2]; + info->status.rates[0].count = 0; - if (!count) { - info->status.rates[i].idx = -1; - break; - } + for (i = 0, idx = first_idx; count && idx <= last_idx; idx++) { + struct ieee80211_tx_rate *cur_rate; + int cur_count; - info->status.rates[i].count = cur_count; - final_idx = i; + cur_rate = &rs->rates[idx / 2]; + cur_count = min_t(int, MT7603_RATE_RETRY, count); count -= cur_count; + + if (idx && (cur_rate->idx != info->status.rates[i].idx || + cur_rate->flags != info->status.rates[i].flags)) { + i++; + if (i == ARRAY_SIZE(info->status.rates)) + break; + + info->status.rates[i] = *cur_rate; + info->status.rates[i].count = 0; + } + + info->status.rates[i].count += cur_count; } out: - final_rate_flags = info->status.rates[final_idx].flags; + final_rate_flags = info->status.rates[i].flags; switch (FIELD_GET(MT_TX_RATE_MODE, final_rate)) { case MT_PHY_TYPE_CCK: @@ -1042,7 +1052,8 @@ out: else sband = &dev->mt76.sband_2g.sband; final_rate &= GENMASK(5, 0); - final_rate = mt7603_get_rate(dev, sband, final_rate, cck); + final_rate = mt76_get_rate(&dev->mt76, sband, final_rate, + cck); final_rate_flags = 0; break; case MT_PHY_TYPE_HT_GF: @@ -1056,8 +1067,8 @@ out: return false; } - info->status.rates[final_idx].idx = final_rate; - info->status.rates[final_idx].flags = final_rate_flags; + info->status.rates[i].idx = final_rate; + info->status.rates[i].flags = final_rate_flags; return true; } @@ -1078,16 +1089,6 @@ mt7603_mac_add_txs_skb(struct mt7603_dev *dev, struct mt7603_sta *sta, int pid, if (skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { - spin_lock_bh(&dev->mt76.lock); - if (sta->rate_probe) { - mt7603_wtbl_set_rates(dev, sta, NULL, - sta->rates); - sta->rate_probe = false; - } - spin_unlock_bh(&dev->mt76.lock); - } - if (!mt7603_fill_txs(dev, sta, info, txs_data)) { ieee80211_tx_info_clear_status(info); info->status.rates[0].idx = -1; @@ -1282,6 +1283,7 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev) tasklet_disable(&dev->mt76.pre_tbtt_tasklet); napi_disable(&dev->mt76.napi[0]); napi_disable(&dev->mt76.napi[1]); + napi_disable(&dev->mt76.tx_napi); mutex_lock(&dev->mt76.mutex); @@ -1326,7 +1328,8 @@ skip_dma_reset: mutex_unlock(&dev->mt76.mutex); tasklet_enable(&dev->mt76.tx_tasklet); - tasklet_schedule(&dev->mt76.tx_tasklet); + napi_enable(&dev->mt76.tx_napi); + napi_schedule(&dev->mt76.tx_napi); tasklet_enable(&dev->mt76.pre_tbtt_tasklet); mt7603_beacon_set_timer(dev, -1, beacon_int); diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c index 0a0334dc40d5..e5d4cb6381a8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c @@ -103,8 +103,7 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_unlock(&dev->mt76.mutex); } -static void -mt7603_init_edcca(struct mt7603_dev *dev) +void mt7603_init_edcca(struct mt7603_dev *dev) { /* Set lower signal level to -65dBm */ mt76_rmw_field(dev, MT_RXTD(8), MT_RXTD_8_LOWER_SIGNAL, 0x23); @@ -207,8 +206,11 @@ mt7603_config(struct ieee80211_hw *hw, u32 changed) int ret = 0; if (changed & (IEEE80211_CONF_CHANGE_CHANNEL | - IEEE80211_CONF_CHANGE_POWER)) + IEEE80211_CONF_CHANGE_POWER)) { + ieee80211_stop_queues(hw); ret = mt7603_set_channel(dev, &hw->conf.chandef); + ieee80211_wake_queues(hw); + } if (changed & IEEE80211_CONF_CHANGE_MONITOR) { mutex_lock(&dev->mt76.mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7603/mcu.c index 6357b5658a32..343ddc5543c2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/mcu.c @@ -346,7 +346,7 @@ int mt7603_mcu_set_eeprom(struct mt7603_dev *dev) }; struct req_data { - u16 addr; + __le16 addr; u8 val; u8 pad; } __packed; diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h index fa64bbaab0d2..2c6f7b4cf0e9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h +++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h @@ -51,6 +51,11 @@ enum mt7603_bw { MT_BW_80, }; +struct mt7603_rate_set { + struct ieee80211_tx_rate probe_rate; + struct ieee80211_tx_rate rates[4]; +}; + struct mt7603_sta { struct mt76_wcid wcid; /* must be first */ @@ -58,7 +63,11 @@ struct mt7603_sta { struct sk_buff_head psq; - struct ieee80211_tx_rate rates[8]; + struct ieee80211_tx_rate rates[4]; + + struct mt7603_rate_set rateset[2]; + u32 rate_set_tsf; + u8 rate_count; u8 n_rates; @@ -117,8 +126,9 @@ struct mt7603_dev { u8 mac_work_count; u8 mcu_running; - u8 ed_monitor; + u8 ed_monitor_enabled; + u8 ed_monitor; s8 ed_trigger; u8 ed_strict_mode; u8 ed_strong_signal; @@ -241,4 +251,5 @@ void mt7603_update_channel(struct mt76_dev *mdev); void mt7603_edcca_set_strict(struct mt7603_dev *dev, bool val); void mt7603_cca_stats_reset(struct mt7603_dev *dev); +void mt7603_init_edcca(struct mt7603_dev *dev); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h index 9d257d5c309d..eb9eefe8e125 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7603/regs.h @@ -480,6 +480,12 @@ enum { #define MT_LPON_BASE 0x24000 #define MT_LPON(n) (MT_LPON_BASE + (n)) +#define MT_LPON_T0CR MT_LPON(0x010) +#define MT_LPON_T0CR_MODE GENMASK(1, 0) + +#define MT_LPON_UTTR0 MT_LPON(0x018) +#define MT_LPON_UTTR1 MT_LPON(0x01c) + #define MT_LPON_BTEIR MT_LPON(0x020) #define MT_LPON_BTEIR_MBSS_MODE GENMASK(31, 29) |