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.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index ec9efb79985f..1a2c143b34d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -1,17 +1,6 @@
+// SPDX-License-Identifier: ISC
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/of.h>
#include "mt76.h"
@@ -294,6 +283,8 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
init_waitqueue_head(&dev->tx_wait);
skb_queue_head_init(&dev->status_list);
+ tasklet_init(&dev->tx_tasklet, mt76_tx_tasklet, (unsigned long)dev);
+
return dev;
}
EXPORT_SYMBOL_GPL(mt76_alloc_device);
@@ -415,11 +406,6 @@ void mt76_set_channel(struct mt76_dev *dev)
bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
int timeout = HZ / 5;
- if (offchannel)
- set_bit(MT76_OFFCHANNEL, &dev->state);
- else
- clear_bit(MT76_OFFCHANNEL, &dev->state);
-
wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(dev), timeout);
if (dev->drv->update_survey)
@@ -487,9 +473,10 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
if (!key)
return;
- if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
- wcid->rx_check_pn = true;
+ if (key->cipher != WLAN_CIPHER_SUITE_CCMP)
+ return;
+ wcid->rx_check_pn = true;
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
ieee80211_get_key_rx_seq(key, i, &seq);
memcpy(wcid->rx_key_pn[i], seq.ccmp.pn, sizeof(seq.ccmp.pn));
@@ -497,12 +484,12 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
}
EXPORT_SYMBOL(mt76_wcid_key_setup);
-struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
+static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
{
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct mt76_rx_status mstat;
- mstat = *((struct mt76_rx_status *) skb->cb);
+ mstat = *((struct mt76_rx_status *)skb->cb);
memset(status, 0, sizeof(*status));
status->flag = mstat.flag;
@@ -517,17 +504,18 @@ struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
status->chains = mstat.chains;
BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
- BUILD_BUG_ON(sizeof(status->chain_signal) != sizeof(mstat.chain_signal));
- memcpy(status->chain_signal, mstat.chain_signal, sizeof(mstat.chain_signal));
+ BUILD_BUG_ON(sizeof(status->chain_signal) !=
+ sizeof(mstat.chain_signal));
+ memcpy(status->chain_signal, mstat.chain_signal,
+ sizeof(mstat.chain_signal));
return wcid_to_sta(mstat.wcid);
}
-EXPORT_SYMBOL(mt76_rx_convert);
static int
mt76_check_ccmp_pn(struct sk_buff *skb)
{
- struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
struct mt76_wcid *wcid = status->wcid;
struct ieee80211_hdr *hdr;
int ret;
@@ -543,7 +531,7 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
* Validate the first fragment both here and in mac80211
* All further fragments will be validated by mac80211 only.
*/
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
if (ieee80211_is_frag(hdr) &&
!ieee80211_is_first_frag(hdr->frame_control))
return 0;
@@ -566,8 +554,8 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
static void
mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
{
- struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_sta *sta;
struct mt76_wcid *wcid = status->wcid;
bool ps;
@@ -576,13 +564,13 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
if (ieee80211_is_pspoll(hdr->frame_control) && !wcid) {
sta = ieee80211_find_sta_by_ifaddr(dev->hw, hdr->addr2, NULL);
if (sta)
- wcid = status->wcid = (struct mt76_wcid *) sta->drv_priv;
+ wcid = status->wcid = (struct mt76_wcid *)sta->drv_priv;
}
if (!wcid || !wcid->sta)
return;
- sta = container_of((void *) wcid, struct ieee80211_sta, drv_priv);
+ sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
if (status->signal <= 0)
ewma_signal_add(&wcid->rssi, -status->signal);
@@ -598,8 +586,8 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
}
if (ieee80211_has_morefrags(hdr->frame_control) ||
- !(ieee80211_is_mgmt(hdr->frame_control) ||
- ieee80211_is_data(hdr->frame_control)))
+ !(ieee80211_is_mgmt(hdr->frame_control) ||
+ ieee80211_is_data(hdr->frame_control)))
return;
ps = ieee80211_has_pm(hdr->frame_control);
@@ -628,7 +616,7 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
if (!sta->txq[i])
continue;
- mtxq = (struct mt76_txq *) sta->txq[i]->drv_priv;
+ mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
if (!skb_queue_empty(&mtxq->retry_q))
ieee80211_schedule_txq(dev->hw, sta->txq[i]);
}
@@ -714,6 +702,9 @@ void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
rcu_assign_pointer(dev->wcid[idx], NULL);
synchronize_rcu();
+ for (i = 0; i < ARRAY_SIZE(wcid->aggr); i++)
+ mt76_rx_aggr_stop(dev, wcid, i);
+
if (dev->drv->sta_remove)
dev->drv->sta_remove(dev, vif, sta);
@@ -750,7 +741,7 @@ int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
dev->drv->sta_assoc(dev, vif, sta);
if (old_state == IEEE80211_STA_NONE &&
- new_state == IEEE80211_STA_NOTEXIST)
+ new_state == IEEE80211_STA_NOTEXIST)
mt76_sta_remove(dev, vif, sta);
return 0;
@@ -790,7 +781,7 @@ static void
__mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
if (vif->csa_active && ieee80211_csa_is_complete(vif))
- ieee80211_csa_finish(vif);
+ ieee80211_csa_finish(vif);
}
void mt76_csa_finish(struct mt76_dev *dev)
@@ -878,3 +869,20 @@ int mt76_get_rate(struct mt76_dev *dev,
return 0;
}
EXPORT_SYMBOL_GPL(mt76_get_rate);
+
+void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ const u8 *mac)
+{
+ struct mt76_dev *dev = hw->priv;
+
+ set_bit(MT76_SCANNING, &dev->state);
+}
+EXPORT_SYMBOL_GPL(mt76_sw_scan);
+
+void mt76_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct mt76_dev *dev = hw->priv;
+
+ clear_bit(MT76_SCANNING, &dev->state);
+}
+EXPORT_SYMBOL_GPL(mt76_sw_scan_complete);