summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76/mac80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mac80211.c')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mac80211.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 907098101898..3d4bf72700a5 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -58,12 +58,15 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
CHAN5G(132, 5660),
CHAN5G(136, 5680),
CHAN5G(140, 5700),
+ CHAN5G(144, 5720),
CHAN5G(149, 5745),
CHAN5G(153, 5765),
CHAN5G(157, 5785),
CHAN5G(161, 5805),
CHAN5G(165, 5825),
+ CHAN5G(169, 5845),
+ CHAN5G(173, 5865),
};
static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
@@ -279,7 +282,8 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
- WIPHY_FLAG_SUPPORTS_TDLS;
+ WIPHY_FLAG_SUPPORTS_TDLS |
+ WIPHY_FLAG_AP_UAPSD;
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
@@ -289,6 +293,7 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
wiphy->available_antennas_rx = dev->phy.antenna_mask;
hw->txq_data_size = sizeof(struct mt76_txq);
+ hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
if (!hw->max_tx_fragments)
hw->max_tx_fragments = 16;
@@ -300,7 +305,11 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
ieee80211_hw_set(hw, TX_AMSDU);
- ieee80211_hw_set(hw, TX_FRAG_LIST);
+
+ /* TODO: avoid linearization for SDIO */
+ if (!mt76_is_sdio(dev))
+ ieee80211_hw_set(hw, TX_FRAG_LIST);
+
ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS);
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
@@ -432,6 +441,12 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
tasklet_init(&dev->tx_tasklet, mt76_tx_tasklet, (unsigned long)dev);
+ dev->wq = alloc_ordered_workqueue("mt76", 0);
+ if (!dev->wq) {
+ ieee80211_free_hw(hw);
+ return NULL;
+ }
+
return dev;
}
EXPORT_SYMBOL_GPL(mt76_alloc_device);
@@ -485,7 +500,12 @@ EXPORT_SYMBOL_GPL(mt76_unregister_device);
void mt76_free_device(struct mt76_dev *dev)
{
- mt76_tx_free(dev);
+ if (dev->wq) {
+ destroy_workqueue(dev->wq);
+ dev->wq = NULL;
+ }
+ if (mt76_is_mmio(dev))
+ mt76_tx_free(dev);
ieee80211_free_hw(dev->hw);
}
EXPORT_SYMBOL_GPL(mt76_free_device);
@@ -500,6 +520,13 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
return;
}
+#ifdef CONFIG_NL80211_TESTMODE
+ if (dev->test.state == MT76_TM_STATE_RX_FRAMES) {
+ dev->test.rx_stats.packets[q]++;
+ if (status->flag & RX_FLAG_FAILED_FCS_CRC)
+ dev->test.rx_stats.fcs_error[q]++;
+ }
+#endif
__skb_queue_tail(&dev->rx_skb[q], skb);
}
EXPORT_SYMBOL_GPL(mt76_rx);
@@ -537,8 +564,7 @@ mt76_channel_state(struct mt76_phy *phy, struct ieee80211_channel *c)
return &msband->chan[idx];
}
-static void
-mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
+void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
{
struct mt76_channel_state *state = phy->chan_state;
@@ -546,6 +572,7 @@ mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time)
phy->survey_time));
phy->survey_time = time;
}
+EXPORT_SYMBOL_GPL(mt76_update_survey_active_time);
void mt76_update_survey(struct mt76_dev *dev)
{