mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 06:34:11 +08:00
mt76 patches for 5.4
* beacon tx fix for mt76x02 * sparse/checkpatch warning fixes * DFS pattern detector for mt7615 (DFS channels not enabled yet) * CSA support for mt7615 * mt7615 cleanup/fixes * mt7615 rate control improvements * usb fixes * mt7615 powersave buffering fix * new device support for mt76x0 * support for more ciphers in mt7615 * watchdog time fixes * smart carrier sense on mt7615 * survey support on mt7615 * multiple interfaces on mt76x02u * calibration data fix for mt7615 * fix for sending BAR after disassoc -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2 Comment: GPGTools - http://gpgtools.org iEYEABECAAYFAl1xNGoACgkQ130UHQKnbvXSxgCfTd+g5fbvbPW31ETNPVITP+UF 3EoAoNjSe0psgOAiNtys10V/YWy5RZak =hYbe -----END PGP SIGNATURE----- Merge tag 'mt76-for-kvalo-2019-09-05' of https://github.com/nbd168/wireless mt76 patches for 5.4 * beacon tx fix for mt76x02 * sparse/checkpatch warning fixes * DFS pattern detector for mt7615 (DFS channels not enabled yet) * CSA support for mt7615 * mt7615 cleanup/fixes * mt7615 rate control improvements * usb fixes * mt7615 powersave buffering fix * new device support for mt76x0 * support for more ciphers in mt7615 * watchdog time fixes * smart carrier sense on mt7615 * survey support on mt7615 * multiple interfaces on mt76x02u * calibration data fix for mt7615 * fix for sending BAR after disassoc
This commit is contained in:
commit
a18da8f619
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2018 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 "mt76.h"
|
#include "mt76.h"
|
||||||
|
|
||||||
@ -34,7 +23,8 @@ mt76_aggr_release(struct mt76_rx_tid *tid, struct sk_buff_head *frames, int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mt76_rx_aggr_release_frames(struct mt76_rx_tid *tid, struct sk_buff_head *frames,
|
mt76_rx_aggr_release_frames(struct mt76_rx_tid *tid,
|
||||||
|
struct sk_buff_head *frames,
|
||||||
u16 head)
|
u16 head)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
@ -74,15 +64,14 @@ mt76_rx_aggr_check_release(struct mt76_rx_tid *tid, struct sk_buff_head *frames)
|
|||||||
for (idx = (tid->head + 1) % tid->size;
|
for (idx = (tid->head + 1) % tid->size;
|
||||||
idx != start && nframes;
|
idx != start && nframes;
|
||||||
idx = (idx + 1) % tid->size) {
|
idx = (idx + 1) % tid->size) {
|
||||||
|
|
||||||
skb = tid->reorder_buf[idx];
|
skb = tid->reorder_buf[idx];
|
||||||
if (!skb)
|
if (!skb)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nframes--;
|
nframes--;
|
||||||
status = (struct mt76_rx_status *) skb->cb;
|
status = (struct mt76_rx_status *)skb->cb;
|
||||||
if (!time_after(jiffies, status->reorder_time +
|
if (!time_after(jiffies,
|
||||||
REORDER_TIMEOUT))
|
status->reorder_time + REORDER_TIMEOUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mt76_rx_aggr_release_frames(tid, frames, status->seqno);
|
mt76_rx_aggr_release_frames(tid, frames, status->seqno);
|
||||||
@ -122,8 +111,8 @@ mt76_rx_aggr_reorder_work(struct work_struct *work)
|
|||||||
static void
|
static void
|
||||||
mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
|
mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
|
||||||
{
|
{
|
||||||
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
|
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
|
||||||
struct ieee80211_bar *bar = (struct ieee80211_bar *) skb->data;
|
struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data;
|
||||||
struct mt76_wcid *wcid = status->wcid;
|
struct mt76_wcid *wcid = status->wcid;
|
||||||
struct mt76_rx_tid *tid;
|
struct mt76_rx_tid *tid;
|
||||||
u16 seqno;
|
u16 seqno;
|
||||||
@ -148,8 +137,8 @@ mt76_rx_aggr_check_ctl(struct sk_buff *skb, struct sk_buff_head *frames)
|
|||||||
|
|
||||||
void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
|
void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
|
||||||
{
|
{
|
||||||
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
|
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
|
||||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
struct mt76_wcid *wcid = status->wcid;
|
struct mt76_wcid *wcid = status->wcid;
|
||||||
struct ieee80211_sta *sta;
|
struct ieee80211_sta *sta;
|
||||||
struct mt76_rx_tid *tid;
|
struct mt76_rx_tid *tid;
|
||||||
@ -233,7 +222,8 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
|
|||||||
tid->nframes++;
|
tid->nframes++;
|
||||||
mt76_rx_aggr_release_head(tid, frames);
|
mt76_rx_aggr_release_head(tid, frames);
|
||||||
|
|
||||||
ieee80211_queue_delayed_work(tid->dev->hw, &tid->reorder_work, REORDER_TIMEOUT);
|
ieee80211_queue_delayed_work(tid->dev->hw, &tid->reorder_work,
|
||||||
|
REORDER_TIMEOUT);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock_bh(&tid->lock);
|
spin_unlock_bh(&tid->lock);
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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 "mt76.h"
|
#include "mt76.h"
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
@ -442,6 +431,12 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
|
|||||||
mt76_dma_rx_cleanup(dev, q);
|
mt76_dma_rx_cleanup(dev, q);
|
||||||
mt76_dma_sync_idx(dev, q);
|
mt76_dma_sync_idx(dev, q);
|
||||||
mt76_dma_rx_fill(dev, q);
|
mt76_dma_rx_fill(dev, q);
|
||||||
|
|
||||||
|
if (!q->rx_head)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev_kfree_skb(q->rx_head);
|
||||||
|
q->rx_head = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -504,7 +499,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
|
|||||||
skb_reserve(skb, q->buf_offset);
|
skb_reserve(skb, q->buf_offset);
|
||||||
|
|
||||||
if (q == &dev->q_rx[MT_RXQ_MCU]) {
|
if (q == &dev->q_rx[MT_RXQ_MCU]) {
|
||||||
u32 *rxfce = (u32 *) skb->cb;
|
u32 *rxfce = (u32 *)skb->cb;
|
||||||
*rxfce = info;
|
*rxfce = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
#ifndef __MT76_DMA_H
|
#ifndef __MT76_DMA_H
|
||||||
#define __MT76_DMA_H
|
#define __MT76_DMA_H
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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 <linux/of.h>
|
||||||
#include <linux/of_net.h>
|
#include <linux/of_net.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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 <linux/of.h>
|
||||||
#include "mt76.h"
|
#include "mt76.h"
|
||||||
@ -294,6 +283,8 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
|
|||||||
init_waitqueue_head(&dev->tx_wait);
|
init_waitqueue_head(&dev->tx_wait);
|
||||||
skb_queue_head_init(&dev->status_list);
|
skb_queue_head_init(&dev->status_list);
|
||||||
|
|
||||||
|
tasklet_init(&dev->tx_tasklet, mt76_tx_tasklet, (unsigned long)dev);
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76_alloc_device);
|
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;
|
bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
|
||||||
int timeout = HZ / 5;
|
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);
|
wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(dev), timeout);
|
||||||
|
|
||||||
if (dev->drv->update_survey)
|
if (dev->drv->update_survey)
|
||||||
@ -487,9 +473,10 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
|
|||||||
if (!key)
|
if (!key)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
|
if (key->cipher != WLAN_CIPHER_SUITE_CCMP)
|
||||||
wcid->rx_check_pn = true;
|
return;
|
||||||
|
|
||||||
|
wcid->rx_check_pn = true;
|
||||||
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||||
ieee80211_get_key_rx_seq(key, i, &seq);
|
ieee80211_get_key_rx_seq(key, i, &seq);
|
||||||
memcpy(wcid->rx_key_pn[i], seq.ccmp.pn, sizeof(seq.ccmp.pn));
|
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);
|
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 ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||||
struct mt76_rx_status mstat;
|
struct mt76_rx_status mstat;
|
||||||
|
|
||||||
mstat = *((struct mt76_rx_status *) skb->cb);
|
mstat = *((struct mt76_rx_status *)skb->cb);
|
||||||
memset(status, 0, sizeof(*status));
|
memset(status, 0, sizeof(*status));
|
||||||
|
|
||||||
status->flag = mstat.flag;
|
status->flag = mstat.flag;
|
||||||
@ -517,17 +504,18 @@ struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
|
|||||||
status->chains = mstat.chains;
|
status->chains = mstat.chains;
|
||||||
|
|
||||||
BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
|
BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
|
||||||
BUILD_BUG_ON(sizeof(status->chain_signal) != sizeof(mstat.chain_signal));
|
BUILD_BUG_ON(sizeof(status->chain_signal) !=
|
||||||
memcpy(status->chain_signal, mstat.chain_signal, sizeof(mstat.chain_signal));
|
sizeof(mstat.chain_signal));
|
||||||
|
memcpy(status->chain_signal, mstat.chain_signal,
|
||||||
|
sizeof(mstat.chain_signal));
|
||||||
|
|
||||||
return wcid_to_sta(mstat.wcid);
|
return wcid_to_sta(mstat.wcid);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mt76_rx_convert);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mt76_check_ccmp_pn(struct sk_buff *skb)
|
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 mt76_wcid *wcid = status->wcid;
|
||||||
struct ieee80211_hdr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
int ret;
|
int ret;
|
||||||
@ -543,7 +531,7 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
|
|||||||
* Validate the first fragment both here and in mac80211
|
* Validate the first fragment both here and in mac80211
|
||||||
* All further fragments will be validated by mac80211 only.
|
* 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) &&
|
if (ieee80211_is_frag(hdr) &&
|
||||||
!ieee80211_is_first_frag(hdr->frame_control))
|
!ieee80211_is_first_frag(hdr->frame_control))
|
||||||
return 0;
|
return 0;
|
||||||
@ -566,8 +554,8 @@ mt76_check_ccmp_pn(struct sk_buff *skb)
|
|||||||
static void
|
static void
|
||||||
mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
|
mt76_check_sta(struct mt76_dev *dev, 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 ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
struct ieee80211_sta *sta;
|
struct ieee80211_sta *sta;
|
||||||
struct mt76_wcid *wcid = status->wcid;
|
struct mt76_wcid *wcid = status->wcid;
|
||||||
bool ps;
|
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) {
|
if (ieee80211_is_pspoll(hdr->frame_control) && !wcid) {
|
||||||
sta = ieee80211_find_sta_by_ifaddr(dev->hw, hdr->addr2, NULL);
|
sta = ieee80211_find_sta_by_ifaddr(dev->hw, hdr->addr2, NULL);
|
||||||
if (sta)
|
if (sta)
|
||||||
wcid = status->wcid = (struct mt76_wcid *) sta->drv_priv;
|
wcid = status->wcid = (struct mt76_wcid *)sta->drv_priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wcid || !wcid->sta)
|
if (!wcid || !wcid->sta)
|
||||||
return;
|
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)
|
if (status->signal <= 0)
|
||||||
ewma_signal_add(&wcid->rssi, -status->signal);
|
ewma_signal_add(&wcid->rssi, -status->signal);
|
||||||
@ -628,7 +616,7 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
|
|||||||
if (!sta->txq[i])
|
if (!sta->txq[i])
|
||||||
continue;
|
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))
|
if (!skb_queue_empty(&mtxq->retry_q))
|
||||||
ieee80211_schedule_txq(dev->hw, sta->txq[i]);
|
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);
|
rcu_assign_pointer(dev->wcid[idx], NULL);
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(wcid->aggr); i++)
|
||||||
|
mt76_rx_aggr_stop(dev, wcid, i);
|
||||||
|
|
||||||
if (dev->drv->sta_remove)
|
if (dev->drv->sta_remove)
|
||||||
dev->drv->sta_remove(dev, vif, sta);
|
dev->drv->sta_remove(dev, vif, sta);
|
||||||
|
|
||||||
@ -878,3 +869,20 @@ int mt76_get_rate(struct mt76_dev *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76_get_rate);
|
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);
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76.h"
|
#include "mt76.h"
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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 "mt76.h"
|
#include "mt76.h"
|
||||||
@ -40,10 +29,16 @@ static u32 mt76_mmio_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mt76_mmio_copy(struct mt76_dev *dev, u32 offset, const void *data,
|
static void mt76_mmio_write_copy(struct mt76_dev *dev, u32 offset,
|
||||||
int len)
|
const void *data, int len)
|
||||||
{
|
{
|
||||||
__iowrite32_copy(dev->mmio.regs + offset, data, len >> 2);
|
__iowrite32_copy(dev->mmio.regs + offset, data, DIV_ROUND_UP(len, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mt76_mmio_read_copy(struct mt76_dev *dev, u32 offset,
|
||||||
|
void *data, int len)
|
||||||
|
{
|
||||||
|
__ioread32_copy(data, dev->mmio.regs + offset, DIV_ROUND_UP(len, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mt76_mmio_wr_rp(struct mt76_dev *dev, u32 base,
|
static int mt76_mmio_wr_rp(struct mt76_dev *dev, u32 base,
|
||||||
@ -89,7 +84,8 @@ void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs)
|
|||||||
.rr = mt76_mmio_rr,
|
.rr = mt76_mmio_rr,
|
||||||
.rmw = mt76_mmio_rmw,
|
.rmw = mt76_mmio_rmw,
|
||||||
.wr = mt76_mmio_wr,
|
.wr = mt76_mmio_wr,
|
||||||
.copy = mt76_mmio_copy,
|
.write_copy = mt76_mmio_write_copy,
|
||||||
|
.read_copy = mt76_mmio_read_copy,
|
||||||
.wr_rp = mt76_mmio_wr_rp,
|
.wr_rp = mt76_mmio_wr_rp,
|
||||||
.rd_rp = mt76_mmio_rd_rp,
|
.rd_rp = mt76_mmio_rd_rp,
|
||||||
.type = MT76_BUS_MMIO,
|
.type = MT76_BUS_MMIO,
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76_H
|
#ifndef __MT76_H
|
||||||
@ -49,7 +38,9 @@ struct mt76_bus_ops {
|
|||||||
u32 (*rr)(struct mt76_dev *dev, u32 offset);
|
u32 (*rr)(struct mt76_dev *dev, u32 offset);
|
||||||
void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
|
void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
|
||||||
u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val);
|
u32 (*rmw)(struct mt76_dev *dev, u32 offset, u32 mask, u32 val);
|
||||||
void (*copy)(struct mt76_dev *dev, u32 offset, const void *data,
|
void (*write_copy)(struct mt76_dev *dev, u32 offset, const void *data,
|
||||||
|
int len);
|
||||||
|
void (*read_copy)(struct mt76_dev *dev, u32 offset, void *data,
|
||||||
int len);
|
int len);
|
||||||
int (*wr_rp)(struct mt76_dev *dev, u32 base,
|
int (*wr_rp)(struct mt76_dev *dev, u32 base,
|
||||||
const struct mt76_reg_pair *rp, int len);
|
const struct mt76_reg_pair *rp, int len);
|
||||||
@ -213,6 +204,7 @@ struct mt76_wcid {
|
|||||||
|
|
||||||
u8 rx_check_pn;
|
u8 rx_check_pn;
|
||||||
u8 rx_key_pn[IEEE80211_NUM_TIDS][6];
|
u8 rx_key_pn[IEEE80211_NUM_TIDS][6];
|
||||||
|
u16 cipher;
|
||||||
|
|
||||||
u32 tx_info;
|
u32 tx_info;
|
||||||
bool sw_iv;
|
bool sw_iv;
|
||||||
@ -280,7 +272,6 @@ enum {
|
|||||||
MT76_STATE_MCU_RUNNING,
|
MT76_STATE_MCU_RUNNING,
|
||||||
MT76_SCANNING,
|
MT76_SCANNING,
|
||||||
MT76_RESET,
|
MT76_RESET,
|
||||||
MT76_OFFCHANNEL,
|
|
||||||
MT76_REMOVED,
|
MT76_REMOVED,
|
||||||
MT76_READING_STATS,
|
MT76_READING_STATS,
|
||||||
};
|
};
|
||||||
@ -390,7 +381,10 @@ enum mt76u_out_ep {
|
|||||||
#define MCU_RESP_URB_SIZE 1024
|
#define MCU_RESP_URB_SIZE 1024
|
||||||
struct mt76_usb {
|
struct mt76_usb {
|
||||||
struct mutex usb_ctrl_mtx;
|
struct mutex usb_ctrl_mtx;
|
||||||
|
union {
|
||||||
u8 data[32];
|
u8 data[32];
|
||||||
|
__le32 reg_val;
|
||||||
|
};
|
||||||
|
|
||||||
struct tasklet_struct rx_tasklet;
|
struct tasklet_struct rx_tasklet;
|
||||||
struct delayed_work stat_work;
|
struct delayed_work stat_work;
|
||||||
@ -496,6 +490,8 @@ struct mt76_dev {
|
|||||||
|
|
||||||
u8 csa_complete;
|
u8 csa_complete;
|
||||||
|
|
||||||
|
ktime_t survey_time;
|
||||||
|
|
||||||
u32 rxfilter;
|
u32 rxfilter;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
@ -538,7 +534,8 @@ struct mt76_rx_status {
|
|||||||
#define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__)
|
#define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__)
|
||||||
#define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__)
|
#define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__)
|
||||||
#define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__)
|
#define __mt76_rmw(dev, ...) (dev)->bus->rmw((dev), __VA_ARGS__)
|
||||||
#define __mt76_wr_copy(dev, ...) (dev)->bus->copy((dev), __VA_ARGS__)
|
#define __mt76_wr_copy(dev, ...) (dev)->bus->write_copy((dev), __VA_ARGS__)
|
||||||
|
#define __mt76_rr_copy(dev, ...) (dev)->bus->read_copy((dev), __VA_ARGS__)
|
||||||
|
|
||||||
#define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val)
|
#define __mt76_set(dev, offset, val) __mt76_rmw(dev, offset, 0, val)
|
||||||
#define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0)
|
#define __mt76_clear(dev, offset, val) __mt76_rmw(dev, offset, val, 0)
|
||||||
@ -546,7 +543,8 @@ struct mt76_rx_status {
|
|||||||
#define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__)
|
#define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__)
|
||||||
#define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__)
|
#define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__)
|
||||||
#define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__)
|
#define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__)
|
||||||
#define mt76_wr_copy(dev, ...) (dev)->mt76.bus->copy(&((dev)->mt76), __VA_ARGS__)
|
#define mt76_wr_copy(dev, ...) (dev)->mt76.bus->write_copy(&((dev)->mt76), __VA_ARGS__)
|
||||||
|
#define mt76_rr_copy(dev, ...) (dev)->mt76.bus->read_copy(&((dev)->mt76), __VA_ARGS__)
|
||||||
#define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__)
|
#define mt76_wr_rp(dev, ...) (dev)->mt76.bus->wr_rp(&((dev)->mt76), __VA_ARGS__)
|
||||||
#define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__)
|
#define mt76_rd_rp(dev, ...) (dev)->mt76.bus->rd_rp(&((dev)->mt76), __VA_ARGS__)
|
||||||
|
|
||||||
@ -675,7 +673,7 @@ static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb)
|
|||||||
{
|
{
|
||||||
BUILD_BUG_ON(sizeof(struct mt76_tx_cb) >
|
BUILD_BUG_ON(sizeof(struct mt76_tx_cb) >
|
||||||
sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data));
|
sizeof(IEEE80211_SKB_CB(skb)->status.status_driver_data));
|
||||||
return ((void *) IEEE80211_SKB_CB(skb)->status.status_driver_data);
|
return ((void *)IEEE80211_SKB_CB(skb)->status.status_driver_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mt76_insert_hdr_pad(struct sk_buff *skb)
|
static inline void mt76_insert_hdr_pad(struct sk_buff *skb)
|
||||||
@ -710,6 +708,7 @@ void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
|||||||
bool send_bar);
|
bool send_bar);
|
||||||
void mt76_txq_schedule(struct mt76_dev *dev, enum mt76_txq_id qid);
|
void mt76_txq_schedule(struct mt76_dev *dev, enum mt76_txq_id qid);
|
||||||
void mt76_txq_schedule_all(struct mt76_dev *dev);
|
void mt76_txq_schedule_all(struct mt76_dev *dev);
|
||||||
|
void mt76_tx_tasklet(unsigned long data);
|
||||||
void mt76_release_buffered_frames(struct ieee80211_hw *hw,
|
void mt76_release_buffered_frames(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta,
|
||||||
u16 tids, int nframes,
|
u16 tids, int nframes,
|
||||||
@ -750,8 +749,6 @@ int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
|
void __mt76_sta_remove(struct mt76_dev *dev, struct ieee80211_vif *vif,
|
||||||
struct ieee80211_sta *sta);
|
struct ieee80211_sta *sta);
|
||||||
|
|
||||||
struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb);
|
|
||||||
|
|
||||||
int mt76_get_min_avg_rssi(struct mt76_dev *dev);
|
int mt76_get_min_avg_rssi(struct mt76_dev *dev);
|
||||||
|
|
||||||
int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
@ -765,6 +762,10 @@ void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id);
|
|||||||
int mt76_get_rate(struct mt76_dev *dev,
|
int mt76_get_rate(struct mt76_dev *dev,
|
||||||
struct ieee80211_supported_band *sband,
|
struct ieee80211_supported_band *sband,
|
||||||
int idx, bool cck);
|
int idx, bool cck);
|
||||||
|
void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
|
const u8 *mac);
|
||||||
|
void mt76_sw_scan_complete(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif);
|
||||||
|
|
||||||
/* internal */
|
/* internal */
|
||||||
void mt76_tx_free(struct mt76_dev *dev);
|
void mt76_tx_free(struct mt76_dev *dev);
|
||||||
|
@ -5,6 +5,8 @@ config MT7603E
|
|||||||
depends on MAC80211
|
depends on MAC80211
|
||||||
depends on PCI
|
depends on PCI
|
||||||
help
|
help
|
||||||
This adds support for MT7603E wireless PCIe devices and the WLAN core on
|
This adds support for MT7603E wireless PCIe devices and the WLAN core
|
||||||
MT7628/MT7688 SoC devices
|
on MT7628/MT7688 SoC devices. This family supports IEEE 802.11n 2x2
|
||||||
|
to 300Mbps PHY rate
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include "mt7603.h"
|
#include "mt7603.h"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include "mt7603.h"
|
#include "mt7603.h"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include "mt7603.h"
|
#include "mt7603.h"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include "mt7603.h"
|
#include "mt7603.h"
|
||||||
#include "mac.h"
|
#include "mac.h"
|
||||||
@ -63,7 +63,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
|
|||||||
txd[0] = cpu_to_le32(val);
|
txd[0] = cpu_to_le32(val);
|
||||||
|
|
||||||
sta = container_of(priv, struct ieee80211_sta, drv_priv);
|
sta = container_of(priv, struct ieee80211_sta, drv_priv);
|
||||||
hdr = (struct ieee80211_hdr *) &skb->data[MT_TXD_SIZE];
|
hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
|
||||||
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
|
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
|
||||||
ieee80211_sta_set_buffered(sta, tid, true);
|
ieee80211_sta_set_buffered(sta, tid, true);
|
||||||
|
|
||||||
@ -135,14 +135,6 @@ mt7603_init_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
static int mt7603_poll_tx(struct napi_struct *napi, int budget)
|
||||||
{
|
{
|
||||||
struct mt7603_dev *dev;
|
struct mt7603_dev *dev;
|
||||||
@ -178,11 +170,6 @@ int mt7603_dma_init(struct mt7603_dev *dev)
|
|||||||
|
|
||||||
mt76_dma_attach(&dev->mt76);
|
mt76_dma_attach(&dev->mt76);
|
||||||
|
|
||||||
init_waitqueue_head(&dev->mt76.mmio.mcu.wait);
|
|
||||||
skb_queue_head_init(&dev->mt76.mmio.mcu.res_q);
|
|
||||||
|
|
||||||
tasklet_init(&dev->mt76.tx_tasklet, mt7603_tx_tasklet, (unsigned long)dev);
|
|
||||||
|
|
||||||
mt76_clear(dev, MT_WPDMA_GLO_CFG,
|
mt76_clear(dev, MT_WPDMA_GLO_CFG,
|
||||||
MT_WPDMA_GLO_CFG_TX_DMA_EN |
|
MT_WPDMA_GLO_CFG_TX_DMA_EN |
|
||||||
MT_WPDMA_GLO_CFG_RX_DMA_EN |
|
MT_WPDMA_GLO_CFG_RX_DMA_EN |
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include "mt7603.h"
|
#include "mt7603.h"
|
||||||
#include "eeprom.h"
|
#include "eeprom.h"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include "mt7603.h"
|
#include "mt7603.h"
|
||||||
@ -248,8 +248,7 @@ mt7603_mac_init(struct mt7603_dev *dev)
|
|||||||
FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7603_RATE_RETRY - 1));
|
FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7603_RATE_RETRY - 1));
|
||||||
|
|
||||||
mt76_wr(dev, MT_AGG_ARCR,
|
mt76_wr(dev, MT_AGG_ARCR,
|
||||||
(MT_AGG_ARCR_INIT_RATE1 |
|
(FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) |
|
||||||
FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) |
|
|
||||||
MT_AGG_ARCR_RATE_DOWN_RATIO_EN |
|
MT_AGG_ARCR_RATE_DOWN_RATIO_EN |
|
||||||
FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) |
|
FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) |
|
||||||
FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4)));
|
FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4)));
|
||||||
@ -507,7 +506,6 @@ mt7603_init_txpower(struct mt7603_dev *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int mt7603_register_device(struct mt7603_dev *dev)
|
int mt7603_register_device(struct mt7603_dev *dev)
|
||||||
{
|
{
|
||||||
struct mt76_bus_ops *bus_ops;
|
struct mt76_bus_ops *bus_ops;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/timekeeping.h>
|
#include <linux/timekeeping.h>
|
||||||
@ -639,9 +639,11 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, struct mt7603_sta *sta,
|
|||||||
IEEE80211_TX_RC_40_MHZ_WIDTH)
|
IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!rates[i].idx)
|
||||||
|
continue;
|
||||||
|
|
||||||
rates[i].idx--;
|
rates[i].idx--;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w9 &= MT_WTBL2_W9_SHORT_GI_20 | MT_WTBL2_W9_SHORT_GI_40 |
|
w9 &= MT_WTBL2_W9_SHORT_GI_20 | MT_WTBL2_W9_SHORT_GI_40 |
|
||||||
@ -1014,8 +1016,9 @@ mt7603_fill_txs(struct mt7603_dev *dev, struct mt7603_sta *sta,
|
|||||||
sta->rate_probe = false;
|
sta->rate_probe = false;
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&dev->mt76.lock);
|
spin_unlock_bh(&dev->mt76.lock);
|
||||||
} else
|
} else {
|
||||||
info->status.rates[0] = rs->rates[first_idx / 2];
|
info->status.rates[0] = rs->rates[first_idx / 2];
|
||||||
|
}
|
||||||
info->status.rates[0].count = 0;
|
info->status.rates[0].count = 0;
|
||||||
|
|
||||||
for (i = 0, idx = first_idx; count && idx <= last_idx; idx++) {
|
for (i = 0, idx = first_idx; count && idx <= last_idx; idx++) {
|
||||||
@ -1470,8 +1473,9 @@ void mt7603_update_channel(struct mt76_dev *mdev)
|
|||||||
spin_lock_bh(&dev->mt76.cc_lock);
|
spin_lock_bh(&dev->mt76.cc_lock);
|
||||||
cur_time = ktime_get_boottime();
|
cur_time = ktime_get_boottime();
|
||||||
state->cc_busy += busy;
|
state->cc_busy += busy;
|
||||||
state->cc_active += ktime_to_us(ktime_sub(cur_time, dev->survey_time));
|
state->cc_active += ktime_to_us(ktime_sub(cur_time,
|
||||||
dev->survey_time = cur_time;
|
dev->mt76.survey_time));
|
||||||
|
dev->mt76.survey_time = cur_time;
|
||||||
spin_unlock_bh(&dev->mt76.cc_lock);
|
spin_unlock_bh(&dev->mt76.cc_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
@ -14,7 +14,7 @@ mt7603_start(struct ieee80211_hw *hw)
|
|||||||
struct mt7603_dev *dev = hw->priv;
|
struct mt7603_dev *dev = hw->priv;
|
||||||
|
|
||||||
mt7603_mac_start(dev);
|
mt7603_mac_start(dev);
|
||||||
dev->survey_time = ktime_get_boottime();
|
dev->mt76.survey_time = ktime_get_boottime();
|
||||||
set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
|
set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
|
||||||
mt7603_mac_work(&dev->mt76.mac_work.work);
|
mt7603_mac_work(&dev->mt76.mac_work.work);
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
|
|||||||
mt76_txq_schedule_all(&dev->mt76);
|
mt76_txq_schedule_all(&dev->mt76);
|
||||||
|
|
||||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||||
MT7603_WATCHDOG_TIME);
|
msecs_to_jiffies(MT7603_WATCHDOG_TIME));
|
||||||
|
|
||||||
/* reset channel stats */
|
/* reset channel stats */
|
||||||
mt76_clear(dev, MT_MIB_CTL, MT_MIB_CTL_READ_CLR_DIS);
|
mt76_clear(dev, MT_MIB_CTL, MT_MIB_CTL_READ_CLR_DIS);
|
||||||
@ -182,7 +182,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
|
|||||||
mt76_rr(dev, MT_MIB_STAT_PSCCA);
|
mt76_rr(dev, MT_MIB_STAT_PSCCA);
|
||||||
mt7603_cca_stats_reset(dev);
|
mt7603_cca_stats_reset(dev);
|
||||||
|
|
||||||
dev->survey_time = ktime_get_boottime();
|
dev->mt76.survey_time = ktime_get_boottime();
|
||||||
|
|
||||||
mt7603_init_edcca(dev);
|
mt7603_init_edcca(dev);
|
||||||
|
|
||||||
@ -399,7 +399,7 @@ mt7603_ps_set_more_data(struct sk_buff *skb)
|
|||||||
{
|
{
|
||||||
struct ieee80211_hdr *hdr;
|
struct ieee80211_hdr *hdr;
|
||||||
|
|
||||||
hdr = (struct ieee80211_hdr *) &skb->data[MT_TXD_SIZE];
|
hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
|
||||||
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,23 +536,6 @@ mt7603_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
mt7603_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
||||||
const u8 *mac)
|
|
||||||
{
|
|
||||||
struct mt7603_dev *dev = hw->priv;
|
|
||||||
|
|
||||||
set_bit(MT76_SCANNING, &dev->mt76.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
mt7603_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|
||||||
{
|
|
||||||
struct mt7603_dev *dev = hw->priv;
|
|
||||||
|
|
||||||
clear_bit(MT76_SCANNING, &dev->mt76.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mt7603_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
mt7603_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
u32 queues, bool drop)
|
u32 queues, bool drop)
|
||||||
@ -569,7 +552,7 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
struct ieee80211_txq *txq = sta->txq[params->tid];
|
struct ieee80211_txq *txq = sta->txq[params->tid];
|
||||||
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
|
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
|
||||||
u16 tid = params->tid;
|
u16 tid = params->tid;
|
||||||
u16 *ssn = ¶ms->ssn;
|
u16 ssn = params->ssn;
|
||||||
u8 ba_size = params->buf_size;
|
u8 ba_size = params->buf_size;
|
||||||
struct mt76_txq *mtxq;
|
struct mt76_txq *mtxq;
|
||||||
|
|
||||||
@ -580,7 +563,7 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case IEEE80211_AMPDU_RX_START:
|
case IEEE80211_AMPDU_RX_START:
|
||||||
mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, *ssn,
|
mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,
|
||||||
params->buf_size);
|
params->buf_size);
|
||||||
mt7603_mac_rx_ba_reset(dev, sta->addr, tid);
|
mt7603_mac_rx_ba_reset(dev, sta->addr, tid);
|
||||||
break;
|
break;
|
||||||
@ -595,11 +578,10 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
||||||
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
||||||
mtxq->aggr = false;
|
mtxq->aggr = false;
|
||||||
ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
|
|
||||||
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
|
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_TX_START:
|
case IEEE80211_AMPDU_TX_START:
|
||||||
mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(*ssn);
|
mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
|
||||||
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_TX_STOP_CONT:
|
case IEEE80211_AMPDU_TX_STOP_CONT:
|
||||||
@ -647,7 +629,8 @@ mt7603_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
|
|||||||
mt7603_mac_set_timing(dev);
|
mt7603_mac_set_timing(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mt7603_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
|
static void mt7603_tx(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_tx_control *control,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
@ -682,8 +665,8 @@ const struct ieee80211_ops mt7603_ops = {
|
|||||||
.sta_state = mt76_sta_state,
|
.sta_state = mt76_sta_state,
|
||||||
.set_key = mt7603_set_key,
|
.set_key = mt7603_set_key,
|
||||||
.conf_tx = mt7603_conf_tx,
|
.conf_tx = mt7603_conf_tx,
|
||||||
.sw_scan_start = mt7603_sw_scan,
|
.sw_scan_start = mt76_sw_scan,
|
||||||
.sw_scan_complete = mt7603_sw_scan_complete,
|
.sw_scan_complete = mt76_sw_scan_complete,
|
||||||
.flush = mt7603_flush,
|
.flush = mt7603_flush,
|
||||||
.ampdu_action = mt7603_ampdu_action,
|
.ampdu_action = mt7603_ampdu_action,
|
||||||
.get_txpower = mt76_get_txpower,
|
.get_txpower = mt76_get_txpower,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include "mt7603.h"
|
#include "mt7603.h"
|
||||||
|
@ -116,7 +116,6 @@ struct mt7603_dev {
|
|||||||
|
|
||||||
s8 tx_power_limit;
|
s8 tx_power_limit;
|
||||||
|
|
||||||
ktime_t survey_time;
|
|
||||||
ktime_t ed_time;
|
ktime_t ed_time;
|
||||||
|
|
||||||
struct mt76_queue q_rx;
|
struct mt76_queue q_rx;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: ISC */
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@ -9,7 +9,6 @@
|
|||||||
static int
|
static int
|
||||||
mt76_wmac_probe(struct platform_device *pdev)
|
mt76_wmac_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
struct mt7603_dev *dev;
|
struct mt7603_dev *dev;
|
||||||
void __iomem *mem_base;
|
void __iomem *mem_base;
|
||||||
struct mt76_dev *mdev;
|
struct mt76_dev *mdev;
|
||||||
@ -20,7 +19,7 @@ mt76_wmac_probe(struct platform_device *pdev)
|
|||||||
if (irq < 0)
|
if (irq < 0)
|
||||||
return irq;
|
return irq;
|
||||||
|
|
||||||
mem_base = devm_ioremap_resource(&pdev->dev, res);
|
mem_base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
if (IS_ERR(mem_base)) {
|
if (IS_ERR(mem_base)) {
|
||||||
dev_err(&pdev->dev, "Failed to get memory resource\n");
|
dev_err(&pdev->dev, "Failed to get memory resource\n");
|
||||||
return PTR_ERR(mem_base);
|
return PTR_ERR(mem_base);
|
||||||
|
@ -5,4 +5,9 @@ config MT7615E
|
|||||||
depends on MAC80211
|
depends on MAC80211
|
||||||
depends on PCI
|
depends on PCI
|
||||||
help
|
help
|
||||||
This adds support for MT7615-based wireless PCIe devices.
|
This adds support for MT7615-based wireless PCIe devices,
|
||||||
|
which support concurrent dual-band operation at both 5GHz
|
||||||
|
and 2.4GHz, IEEE 802.11ac 4x4:4SS 1733Mbps PHY rate, wave2
|
||||||
|
MU-MIMO up to 4 users/group and 160MHz channels.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here.
|
||||||
|
@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
obj-$(CONFIG_MT7615E) += mt7615e.o
|
obj-$(CONFIG_MT7615E) += mt7615e.o
|
||||||
|
|
||||||
mt7615e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o
|
mt7615e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
|
||||||
|
debugfs.o
|
||||||
|
91
drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
Normal file
91
drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
|
|
||||||
|
#include "mt7615.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7615_radar_pattern_set(void *data, u64 val)
|
||||||
|
{
|
||||||
|
struct mt7615_dev *dev = data;
|
||||||
|
|
||||||
|
return mt7615_mcu_rdd_send_pattern(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
|
||||||
|
mt7615_radar_pattern_set, "%lld\n");
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7615_scs_set(void *data, u64 val)
|
||||||
|
{
|
||||||
|
struct mt7615_dev *dev = data;
|
||||||
|
|
||||||
|
mt7615_mac_set_scs(dev, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7615_scs_get(void *data, u64 *val)
|
||||||
|
{
|
||||||
|
struct mt7615_dev *dev = data;
|
||||||
|
|
||||||
|
*val = dev->scs_en;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
|
||||||
|
mt7615_scs_set, "%lld\n");
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7615_radio_read(struct seq_file *s, void *data)
|
||||||
|
{
|
||||||
|
struct mt7615_dev *dev = dev_get_drvdata(s->private);
|
||||||
|
|
||||||
|
seq_printf(s, "Sensitivity: ofdm=%d cck=%d\n",
|
||||||
|
dev->ofdm_sensitivity, dev->cck_sensitivity);
|
||||||
|
seq_printf(s, "False CCA: ofdm=%d cck=%d\n",
|
||||||
|
dev->false_cca_ofdm, dev->false_cca_cck);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt7615_read_temperature(struct seq_file *s, void *data)
|
||||||
|
{
|
||||||
|
struct mt7615_dev *dev = dev_get_drvdata(s->private);
|
||||||
|
int temp;
|
||||||
|
|
||||||
|
/* cpu */
|
||||||
|
temp = mt7615_mcu_get_temperature(dev, 0);
|
||||||
|
seq_printf(s, "Temperature: %d\n", temp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt7615_init_debugfs(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
struct dentry *dir;
|
||||||
|
|
||||||
|
dir = mt76_register_debugfs(&dev->mt76);
|
||||||
|
if (!dir)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
|
||||||
|
debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
|
||||||
|
mt7615_radio_read);
|
||||||
|
debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
|
||||||
|
/* test pattern knobs */
|
||||||
|
debugfs_create_u8("pattern_len", 0600, dir,
|
||||||
|
&dev->radar_pattern.n_pulses);
|
||||||
|
debugfs_create_u32("pulse_period", 0600, dir,
|
||||||
|
&dev->radar_pattern.period);
|
||||||
|
debugfs_create_u16("pulse_width", 0600, dir,
|
||||||
|
&dev->radar_pattern.width);
|
||||||
|
debugfs_create_u16("pulse_power", 0600, dir,
|
||||||
|
&dev->radar_pattern.power);
|
||||||
|
debugfs_create_file("radar_trigger", 0200, dir, dev,
|
||||||
|
&fops_radar_pattern);
|
||||||
|
debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
|
||||||
|
mt7615_read_temperature);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -76,7 +76,7 @@ void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
|
|||||||
mt7615_mac_tx_free(dev, skb);
|
mt7615_mac_tx_free(dev, skb);
|
||||||
break;
|
break;
|
||||||
case PKT_TYPE_RX_EVENT:
|
case PKT_TYPE_RX_EVENT:
|
||||||
mt76_mcu_rx_event(&dev->mt76, skb);
|
mt7615_mcu_rx_event(dev, skb);
|
||||||
break;
|
break;
|
||||||
case PKT_TYPE_NORMAL:
|
case PKT_TYPE_NORMAL:
|
||||||
if (!mt7615_mac_fill_rx(dev, skb)) {
|
if (!mt7615_mac_fill_rx(dev, skb)) {
|
||||||
@ -90,13 +90,6 @@ void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mt7615_tx_tasklet(unsigned long data)
|
|
||||||
{
|
|
||||||
struct mt7615_dev *dev = (struct mt7615_dev *)data;
|
|
||||||
|
|
||||||
mt76_txq_schedule_all(&dev->mt76);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mt7615_poll_tx(struct napi_struct *napi, int budget)
|
static int mt7615_poll_tx(struct napi_struct *napi, int budget)
|
||||||
{
|
{
|
||||||
static const u8 queue_map[] = {
|
static const u8 queue_map[] = {
|
||||||
@ -128,9 +121,6 @@ int mt7615_dma_init(struct mt7615_dev *dev)
|
|||||||
|
|
||||||
mt76_dma_attach(&dev->mt76);
|
mt76_dma_attach(&dev->mt76);
|
||||||
|
|
||||||
tasklet_init(&dev->mt76.tx_tasklet, mt7615_tx_tasklet,
|
|
||||||
(unsigned long)dev);
|
|
||||||
|
|
||||||
mt76_wr(dev, MT_WPDMA_GLO_CFG,
|
mt76_wr(dev, MT_WPDMA_GLO_CFG,
|
||||||
MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE |
|
MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE |
|
||||||
MT_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN |
|
MT_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN |
|
||||||
|
@ -154,6 +154,42 @@ int mt7615_eeprom_get_power_index(struct mt7615_dev *dev,
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mt7615_apply_cal_free_data(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
static const u16 ical[] = {
|
||||||
|
0x53, 0x54, 0x55, 0x56, 0x57, 0x5c, 0x5d, 0x62, 0x63, 0x68,
|
||||||
|
0x69, 0x6e, 0x6f, 0x73, 0x74, 0x78, 0x79, 0x82, 0x83, 0x87,
|
||||||
|
0x88, 0x8c, 0x8d, 0x91, 0x92, 0x96, 0x97, 0x9b, 0x9c, 0xa0,
|
||||||
|
0xa1, 0xaa, 0xab, 0xaf, 0xb0, 0xb4, 0xb5, 0xb9, 0xba, 0xf4,
|
||||||
|
0xf7, 0xff,
|
||||||
|
0x140, 0x141, 0x145, 0x146, 0x14a, 0x14b, 0x154, 0x155, 0x159,
|
||||||
|
0x15a, 0x15e, 0x15f, 0x163, 0x164, 0x168, 0x169, 0x16d, 0x16e,
|
||||||
|
0x172, 0x173, 0x17c, 0x17d, 0x181, 0x182, 0x186, 0x187, 0x18b,
|
||||||
|
0x18c
|
||||||
|
};
|
||||||
|
static const u16 ical_nocheck[] = {
|
||||||
|
0x110, 0x111, 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118,
|
||||||
|
0x1b5, 0x1b6, 0x1b7, 0x3ac, 0x3ad, 0x3ae, 0x3af, 0x3b0, 0x3b1,
|
||||||
|
0x3b2
|
||||||
|
};
|
||||||
|
u8 *eeprom = dev->mt76.eeprom.data;
|
||||||
|
u8 *otp = dev->mt76.otp.data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!otp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ical); i++)
|
||||||
|
if (!otp[ical[i]])
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ical); i++)
|
||||||
|
eeprom[ical[i]] = otp[ical[i]];
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ical_nocheck); i++)
|
||||||
|
eeprom[ical_nocheck[i]] = otp[ical_nocheck[i]];
|
||||||
|
}
|
||||||
|
|
||||||
int mt7615_eeprom_init(struct mt7615_dev *dev)
|
int mt7615_eeprom_init(struct mt7615_dev *dev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -166,6 +202,8 @@ int mt7615_eeprom_init(struct mt7615_dev *dev)
|
|||||||
if (ret && dev->mt76.otp.data)
|
if (ret && dev->mt76.otp.data)
|
||||||
memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
|
memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
|
||||||
MT7615_EEPROM_SIZE);
|
MT7615_EEPROM_SIZE);
|
||||||
|
else
|
||||||
|
mt7615_apply_cal_free_data(dev);
|
||||||
|
|
||||||
mt7615_eeprom_parse_hw_cap(dev);
|
mt7615_eeprom_parse_hw_cap(dev);
|
||||||
memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
|
memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
|
||||||
|
@ -20,10 +20,24 @@ static void mt7615_phy_init(struct mt7615_dev *dev)
|
|||||||
|
|
||||||
static void mt7615_mac_init(struct mt7615_dev *dev)
|
static void mt7615_mac_init(struct mt7615_dev *dev)
|
||||||
{
|
{
|
||||||
/* enable band 0 clk */
|
u32 val;
|
||||||
mt76_rmw(dev, MT_CFG_CCR,
|
|
||||||
MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN,
|
/* enable band 0/1 clk */
|
||||||
MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN);
|
mt76_set(dev, MT_CFG_CCR,
|
||||||
|
MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN |
|
||||||
|
MT_CFG_CCR_MAC_D1_1X_GC_EN | MT_CFG_CCR_MAC_D1_2X_GC_EN);
|
||||||
|
|
||||||
|
val = mt76_rmw(dev, MT_TMAC_TRCR0,
|
||||||
|
MT_TMAC_TRCR_CCA_SEL | MT_TMAC_TRCR_SEC_CCA_SEL,
|
||||||
|
FIELD_PREP(MT_TMAC_TRCR_CCA_SEL, 2) |
|
||||||
|
FIELD_PREP(MT_TMAC_TRCR_SEC_CCA_SEL, 0));
|
||||||
|
mt76_wr(dev, MT_TMAC_TRCR1, val);
|
||||||
|
|
||||||
|
val = MT_AGG_ACR_PKT_TIME_EN | MT_AGG_ACR_NO_BA_AR_RULE |
|
||||||
|
FIELD_PREP(MT_AGG_ACR_CFEND_RATE, 0x49) | /* 24M */
|
||||||
|
FIELD_PREP(MT_AGG_ACR_BAR_RATE, 0x4b); /* 6M */
|
||||||
|
mt76_wr(dev, MT_AGG_ACR0, val);
|
||||||
|
mt76_wr(dev, MT_AGG_ACR1, val);
|
||||||
|
|
||||||
mt76_rmw_field(dev, MT_TMAC_CTCR0,
|
mt76_rmw_field(dev, MT_TMAC_CTCR0,
|
||||||
MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);
|
MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);
|
||||||
@ -36,6 +50,7 @@ static void mt7615_mac_init(struct mt7615_dev *dev)
|
|||||||
MT_TMAC_CTCR0_INS_DDLMT_EN);
|
MT_TMAC_CTCR0_INS_DDLMT_EN);
|
||||||
|
|
||||||
mt7615_mcu_set_rts_thresh(dev, 0x92b);
|
mt7615_mcu_set_rts_thresh(dev, 0x92b);
|
||||||
|
mt7615_mac_set_scs(dev, false);
|
||||||
|
|
||||||
mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS,
|
mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS,
|
||||||
MT_AGG_SCR_NLNAV_MID_PTEC_DIS);
|
MT_AGG_SCR_NLNAV_MID_PTEC_DIS);
|
||||||
@ -45,11 +60,19 @@ static void mt7615_mac_init(struct mt7615_dev *dev)
|
|||||||
mt76_wr(dev, MT_DMA_DCR0, MT_DMA_DCR0_RX_VEC_DROP |
|
mt76_wr(dev, MT_DMA_DCR0, MT_DMA_DCR0_RX_VEC_DROP |
|
||||||
FIELD_PREP(MT_DMA_DCR0_MAX_RX_LEN, 3072));
|
FIELD_PREP(MT_DMA_DCR0_MAX_RX_LEN, 3072));
|
||||||
|
|
||||||
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,
|
mt76_wr(dev, MT_AGG_ARDCR,
|
||||||
FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 0) |
|
FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), MT7615_RATE_RETRY - 1) |
|
||||||
FIELD_PREP(MT_AGG_ARxCR_LIMIT(1),
|
FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), MT7615_RATE_RETRY - 1) |
|
||||||
max_t(int, 0, MT7615_RATE_RETRY - 2)) |
|
|
||||||
FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7615_RATE_RETRY - 1) |
|
FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7615_RATE_RETRY - 1) |
|
||||||
FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7615_RATE_RETRY - 1) |
|
FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7615_RATE_RETRY - 1) |
|
||||||
FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7615_RATE_RETRY - 1) |
|
FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7615_RATE_RETRY - 1) |
|
||||||
@ -58,8 +81,7 @@ static void mt7615_mac_init(struct mt7615_dev *dev)
|
|||||||
FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7615_RATE_RETRY - 1));
|
FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7615_RATE_RETRY - 1));
|
||||||
|
|
||||||
mt76_wr(dev, MT_AGG_ARCR,
|
mt76_wr(dev, MT_AGG_ARCR,
|
||||||
(MT_AGG_ARCR_INIT_RATE1 |
|
(FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) |
|
||||||
FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) |
|
|
||||||
MT_AGG_ARCR_RATE_DOWN_RATIO_EN |
|
MT_AGG_ARCR_RATE_DOWN_RATIO_EN |
|
||||||
FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) |
|
FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) |
|
||||||
FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4)));
|
FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4)));
|
||||||
@ -155,17 +177,6 @@ static const struct ieee80211_iface_combination if_comb[] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mt7615_init_debugfs(struct mt7615_dev *dev)
|
|
||||||
{
|
|
||||||
struct dentry *dir;
|
|
||||||
|
|
||||||
dir = mt76_register_debugfs(&dev->mt76);
|
|
||||||
if (!dir)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mt7615_init_txpower(struct mt7615_dev *dev,
|
mt7615_init_txpower(struct mt7615_dev *dev,
|
||||||
struct ieee80211_supported_band *sband)
|
struct ieee80211_supported_band *sband)
|
||||||
@ -208,6 +219,30 @@ mt7615_init_txpower(struct mt7615_dev *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_regd_notifier(struct wiphy *wiphy,
|
||||||
|
struct regulatory_request *request)
|
||||||
|
{
|
||||||
|
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||||
|
struct mt7615_dev *dev = hw->priv;
|
||||||
|
struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
|
||||||
|
|
||||||
|
if (request->dfs_region == dev->mt76.region)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev->mt76.region = request->dfs_region;
|
||||||
|
|
||||||
|
if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mt7615_dfs_stop_radar_detector(dev);
|
||||||
|
if (request->dfs_region == NL80211_DFS_UNSET)
|
||||||
|
mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, MT_HW_RDD0,
|
||||||
|
MT_RX_SEL0, 0);
|
||||||
|
else
|
||||||
|
mt7615_dfs_start_radar_detector(dev);
|
||||||
|
}
|
||||||
|
|
||||||
int mt7615_register_device(struct mt7615_dev *dev)
|
int mt7615_register_device(struct mt7615_dev *dev)
|
||||||
{
|
{
|
||||||
struct ieee80211_hw *hw = mt76_hw(dev);
|
struct ieee80211_hw *hw = mt76_hw(dev);
|
||||||
@ -230,6 +265,8 @@ int mt7615_register_device(struct mt7615_dev *dev)
|
|||||||
|
|
||||||
wiphy->iface_combinations = if_comb;
|
wiphy->iface_combinations = if_comb;
|
||||||
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
|
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
|
||||||
|
wiphy->reg_notifier = mt7615_regd_notifier;
|
||||||
|
wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
||||||
|
|
||||||
ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
|
ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
|
||||||
ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
|
ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
|
||||||
@ -243,6 +280,7 @@ int mt7615_register_device(struct mt7615_dev *dev)
|
|||||||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
|
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
|
||||||
dev->mt76.chainmask = 0x404;
|
dev->mt76.chainmask = 0x404;
|
||||||
dev->mt76.antenna_mask = 0xf;
|
dev->mt76.antenna_mask = 0xf;
|
||||||
|
dev->dfs_state = -1;
|
||||||
|
|
||||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||||
#ifdef CONFIG_MAC80211_MESH
|
#ifdef CONFIG_MAC80211_MESH
|
||||||
|
@ -232,11 +232,9 @@ void mt7615_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
|
|||||||
struct mt76_txwi_cache *t;
|
struct mt76_txwi_cache *t;
|
||||||
struct mt7615_dev *dev;
|
struct mt7615_dev *dev;
|
||||||
struct mt7615_txp *txp;
|
struct mt7615_txp *txp;
|
||||||
u8 *txwi_ptr;
|
|
||||||
|
|
||||||
txwi_ptr = mt76_get_txwi_ptr(mdev, e->txwi);
|
|
||||||
txp = (struct mt7615_txp *)(txwi_ptr + MT_TXD_SIZE);
|
|
||||||
dev = container_of(mdev, struct mt7615_dev, mt76);
|
dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||||
|
txp = mt7615_txwi_to_txp(mdev, e->txwi);
|
||||||
|
|
||||||
spin_lock_bh(&dev->token_lock);
|
spin_lock_bh(&dev->token_lock);
|
||||||
t = idr_remove(&dev->token, le16_to_cpu(txp->token));
|
t = idr_remove(&dev->token, le16_to_cpu(txp->token));
|
||||||
@ -248,12 +246,13 @@ void mt7615_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
|
|||||||
mt76_tx_complete_skb(mdev, e->skb);
|
mt76_tx_complete_skb(mdev, e->skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 mt7615_mac_tx_rate_val(struct mt7615_dev *dev,
|
static u16
|
||||||
|
mt7615_mac_tx_rate_val(struct mt7615_dev *dev,
|
||||||
const struct ieee80211_tx_rate *rate,
|
const struct ieee80211_tx_rate *rate,
|
||||||
bool stbc, u8 *bw)
|
bool stbc, u8 *bw)
|
||||||
{
|
{
|
||||||
u8 phy, nss, rate_idx;
|
u8 phy, nss, rate_idx;
|
||||||
u16 rateval;
|
u16 rateval = 0;
|
||||||
|
|
||||||
*bw = 0;
|
*bw = 0;
|
||||||
|
|
||||||
@ -291,13 +290,15 @@ u16 mt7615_mac_tx_rate_val(struct mt7615_dev *dev,
|
|||||||
rate_idx = val & 0xff;
|
rate_idx = val & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
rateval = (FIELD_PREP(MT_TX_RATE_IDX, rate_idx) |
|
if (stbc && nss == 1) {
|
||||||
|
nss++;
|
||||||
|
rateval |= MT_TX_RATE_STBC;
|
||||||
|
}
|
||||||
|
|
||||||
|
rateval |= (FIELD_PREP(MT_TX_RATE_IDX, rate_idx) |
|
||||||
FIELD_PREP(MT_TX_RATE_MODE, phy) |
|
FIELD_PREP(MT_TX_RATE_MODE, phy) |
|
||||||
FIELD_PREP(MT_TX_RATE_NSS, nss - 1));
|
FIELD_PREP(MT_TX_RATE_NSS, nss - 1));
|
||||||
|
|
||||||
if (stbc && nss == 1)
|
|
||||||
rateval |= MT_TX_RATE_STBC;
|
|
||||||
|
|
||||||
return rateval;
|
return rateval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,9 +310,10 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
|||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
struct ieee80211_tx_rate *rate = &info->control.rates[0];
|
struct ieee80211_tx_rate *rate = &info->control.rates[0];
|
||||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
|
bool multicast = is_multicast_ether_addr(hdr->addr1);
|
||||||
struct ieee80211_vif *vif = info->control.vif;
|
struct ieee80211_vif *vif = info->control.vif;
|
||||||
int tx_count = 8;
|
int tx_count = 8;
|
||||||
u8 fc_type, fc_stype, p_fmt, q_idx, omac_idx = 0;
|
u8 fc_type, fc_stype, p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
|
||||||
__le16 fc = hdr->frame_control;
|
__le16 fc = hdr->frame_control;
|
||||||
u16 seqno = 0;
|
u16 seqno = 0;
|
||||||
u32 val;
|
u32 val;
|
||||||
@ -320,6 +322,7 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
|||||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||||
|
|
||||||
omac_idx = mvif->omac_idx;
|
omac_idx = mvif->omac_idx;
|
||||||
|
wmm_idx = mvif->wmm_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sta) {
|
if (sta) {
|
||||||
@ -331,8 +334,9 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
|||||||
fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
|
fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
|
||||||
fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
|
fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
|
||||||
|
|
||||||
if (ieee80211_is_data(fc)) {
|
if (ieee80211_is_data(fc) || ieee80211_is_bufferable_mmpdu(fc)) {
|
||||||
q_idx = skb_get_queue_mapping(skb);
|
q_idx = wmm_idx * MT7615_MAX_WMM_SETS +
|
||||||
|
skb_get_queue_mapping(skb);
|
||||||
p_fmt = MT_TX_TYPE_CT;
|
p_fmt = MT_TX_TYPE_CT;
|
||||||
} else if (ieee80211_is_beacon(fc)) {
|
} else if (ieee80211_is_beacon(fc)) {
|
||||||
q_idx = MT_LMAC_BCN0;
|
q_idx = MT_LMAC_BCN0;
|
||||||
@ -360,8 +364,18 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
|||||||
|
|
||||||
val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
|
val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
|
||||||
FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) |
|
FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) |
|
||||||
FIELD_PREP(MT_TXD2_MULTICAST,
|
FIELD_PREP(MT_TXD2_MULTICAST, multicast);
|
||||||
is_multicast_ether_addr(hdr->addr1));
|
if (key) {
|
||||||
|
if (multicast && ieee80211_is_robust_mgmt_frame(skb) &&
|
||||||
|
key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
|
||||||
|
val |= MT_TXD2_BIP;
|
||||||
|
txwi[3] = 0;
|
||||||
|
} else {
|
||||||
|
txwi[3] = cpu_to_le32(MT_TXD3_PROTECT_FRAME);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
txwi[3] = 0;
|
||||||
|
}
|
||||||
txwi[2] = cpu_to_le32(val);
|
txwi[2] = cpu_to_le32(val);
|
||||||
|
|
||||||
if (!(info->flags & IEEE80211_TX_CTL_AMPDU))
|
if (!(info->flags & IEEE80211_TX_CTL_AMPDU))
|
||||||
@ -418,14 +432,11 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
|||||||
}
|
}
|
||||||
val |= FIELD_PREP(MT_TXD3_SEQ, seqno);
|
val |= FIELD_PREP(MT_TXD3_SEQ, seqno);
|
||||||
|
|
||||||
txwi[3] = cpu_to_le32(val);
|
txwi[3] |= cpu_to_le32(val);
|
||||||
|
|
||||||
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
|
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||||
txwi[3] |= cpu_to_le32(MT_TXD3_NO_ACK);
|
txwi[3] |= cpu_to_le32(MT_TXD3_NO_ACK);
|
||||||
|
|
||||||
if (key)
|
|
||||||
txwi[3] |= cpu_to_le32(MT_TXD3_PROTECT_FRAME);
|
|
||||||
|
|
||||||
txwi[7] = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
|
txwi[7] = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
|
||||||
FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
|
FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
|
||||||
|
|
||||||
@ -436,16 +447,318 @@ void mt7615_txp_skb_unmap(struct mt76_dev *dev,
|
|||||||
struct mt76_txwi_cache *t)
|
struct mt76_txwi_cache *t)
|
||||||
{
|
{
|
||||||
struct mt7615_txp *txp;
|
struct mt7615_txp *txp;
|
||||||
u8 *txwi;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
txwi = mt76_get_txwi_ptr(dev, t);
|
txp = mt7615_txwi_to_txp(dev, t);
|
||||||
txp = (struct mt7615_txp *)(txwi + MT_TXD_SIZE);
|
|
||||||
for (i = 1; i < txp->nbuf; i++)
|
for (i = 1; i < txp->nbuf; i++)
|
||||||
dma_unmap_single(dev->dev, le32_to_cpu(txp->buf[i]),
|
dma_unmap_single(dev->dev, le32_to_cpu(txp->buf[i]),
|
||||||
le16_to_cpu(txp->len[i]), DMA_TO_DEVICE);
|
le16_to_cpu(txp->len[i]), DMA_TO_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 mt7615_mac_wtbl_addr(int wcid)
|
||||||
|
{
|
||||||
|
return MT_WTBL_BASE + wcid * MT_WTBL_ENTRY_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt7615_mac_set_rates(struct mt7615_dev *dev, struct mt7615_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 = mt7615_mac_wtbl_addr(wcid);
|
||||||
|
bool stbc = false;
|
||||||
|
int n_rates = sta->n_rates;
|
||||||
|
u8 bw, bw_prev, bw_idx = 0;
|
||||||
|
u16 val[4];
|
||||||
|
u16 probe_val;
|
||||||
|
u32 w5, w27;
|
||||||
|
bool rateset;
|
||||||
|
int i, k;
|
||||||
|
|
||||||
|
if (!mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000))
|
||||||
|
return;
|
||||||
|
|
||||||
|
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 |
|
||||||
|
IEEE80211_TX_RC_80_MHZ_WIDTH |
|
||||||
|
IEEE80211_TX_RC_160_MHZ_WIDTH))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!rates[i].idx)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rates[i].idx--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val[0] = mt7615_mac_tx_rate_val(dev, &rates[0], stbc, &bw);
|
||||||
|
bw_prev = bw;
|
||||||
|
|
||||||
|
if (probe_rate) {
|
||||||
|
probe_val = mt7615_mac_tx_rate_val(dev, probe_rate, stbc, &bw);
|
||||||
|
if (bw)
|
||||||
|
bw_idx = 1;
|
||||||
|
else
|
||||||
|
bw_prev = 0;
|
||||||
|
} else {
|
||||||
|
probe_val = val[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
val[1] = mt7615_mac_tx_rate_val(dev, &rates[1], stbc, &bw);
|
||||||
|
if (bw_prev) {
|
||||||
|
bw_idx = 3;
|
||||||
|
bw_prev = bw;
|
||||||
|
}
|
||||||
|
|
||||||
|
val[2] = mt7615_mac_tx_rate_val(dev, &rates[2], stbc, &bw);
|
||||||
|
if (bw_prev) {
|
||||||
|
bw_idx = 5;
|
||||||
|
bw_prev = bw;
|
||||||
|
}
|
||||||
|
|
||||||
|
val[3] = mt7615_mac_tx_rate_val(dev, &rates[3], stbc, &bw);
|
||||||
|
if (bw_prev)
|
||||||
|
bw_idx = 7;
|
||||||
|
|
||||||
|
w27 = mt76_rr(dev, addr + 27 * 4);
|
||||||
|
w27 &= ~MT_WTBL_W27_CC_BW_SEL;
|
||||||
|
w27 |= FIELD_PREP(MT_WTBL_W27_CC_BW_SEL, bw);
|
||||||
|
|
||||||
|
w5 = mt76_rr(dev, addr + 5 * 4);
|
||||||
|
w5 &= ~(MT_WTBL_W5_BW_CAP | MT_WTBL_W5_CHANGE_BW_RATE |
|
||||||
|
MT_WTBL_W5_MPDU_OK_COUNT |
|
||||||
|
MT_WTBL_W5_MPDU_FAIL_COUNT |
|
||||||
|
MT_WTBL_W5_RATE_IDX);
|
||||||
|
w5 |= FIELD_PREP(MT_WTBL_W5_BW_CAP, bw) |
|
||||||
|
FIELD_PREP(MT_WTBL_W5_CHANGE_BW_RATE, bw_idx ? bw_idx - 1 : 7);
|
||||||
|
|
||||||
|
mt76_wr(dev, MT_WTBL_RIUCR0, w5);
|
||||||
|
|
||||||
|
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[1]));
|
||||||
|
|
||||||
|
mt76_wr(dev, MT_WTBL_RIUCR2,
|
||||||
|
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[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[3]) |
|
||||||
|
FIELD_PREP(MT_WTBL_RIUCR3_RATE7, val[3]));
|
||||||
|
|
||||||
|
mt76_wr(dev, MT_WTBL_UPDATE,
|
||||||
|
FIELD_PREP(MT_WTBL_UPDATE_WLAN_IDX, wcid) |
|
||||||
|
MT_WTBL_UPDATE_RATE_UPDATE |
|
||||||
|
MT_WTBL_UPDATE_TX_COUNT_CLEAR);
|
||||||
|
|
||||||
|
mt76_wr(dev, addr + 27 * 4, w27);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (!(sta->wcid.tx_info & MT_WCID_TX_INFO_SET))
|
||||||
|
mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000);
|
||||||
|
|
||||||
|
sta->rate_count = 2 * MT7615_RATE_RETRY * n_rates;
|
||||||
|
sta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mt7615_cipher_type
|
||||||
|
mt7615_mac_get_cipher(int cipher)
|
||||||
|
{
|
||||||
|
switch (cipher) {
|
||||||
|
case WLAN_CIPHER_SUITE_WEP40:
|
||||||
|
return MT_CIPHER_WEP40;
|
||||||
|
case WLAN_CIPHER_SUITE_WEP104:
|
||||||
|
return MT_CIPHER_WEP104;
|
||||||
|
case WLAN_CIPHER_SUITE_TKIP:
|
||||||
|
return MT_CIPHER_TKIP;
|
||||||
|
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||||
|
return MT_CIPHER_BIP_CMAC_128;
|
||||||
|
case WLAN_CIPHER_SUITE_CCMP:
|
||||||
|
return MT_CIPHER_AES_CCMP;
|
||||||
|
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||||
|
return MT_CIPHER_CCMP_256;
|
||||||
|
case WLAN_CIPHER_SUITE_GCMP:
|
||||||
|
return MT_CIPHER_GCMP;
|
||||||
|
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||||
|
return MT_CIPHER_GCMP_256;
|
||||||
|
case WLAN_CIPHER_SUITE_SMS4:
|
||||||
|
return MT_CIPHER_WAPI;
|
||||||
|
default:
|
||||||
|
return MT_CIPHER_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
|
||||||
|
struct ieee80211_key_conf *key,
|
||||||
|
enum mt7615_cipher_type cipher,
|
||||||
|
enum set_key_cmd cmd)
|
||||||
|
{
|
||||||
|
u32 addr = mt7615_mac_wtbl_addr(wcid->idx) + 30 * 4;
|
||||||
|
u8 data[32] = {};
|
||||||
|
|
||||||
|
if (key->keylen > sizeof(data))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mt76_rr_copy(dev, addr, data, sizeof(data));
|
||||||
|
if (cmd == SET_KEY) {
|
||||||
|
if (cipher == MT_CIPHER_TKIP) {
|
||||||
|
/* Rx/Tx MIC keys are swapped */
|
||||||
|
memcpy(data + 16, key->key + 24, 8);
|
||||||
|
memcpy(data + 24, key->key + 16, 8);
|
||||||
|
}
|
||||||
|
if (cipher != MT_CIPHER_BIP_CMAC_128 && wcid->cipher)
|
||||||
|
memmove(data + 16, data, 16);
|
||||||
|
if (cipher != MT_CIPHER_BIP_CMAC_128 || !wcid->cipher)
|
||||||
|
memcpy(data, key->key, key->keylen);
|
||||||
|
else if (cipher == MT_CIPHER_BIP_CMAC_128)
|
||||||
|
memcpy(data + 16, key->key, 16);
|
||||||
|
} else {
|
||||||
|
if (wcid->cipher & ~BIT(cipher)) {
|
||||||
|
if (cipher != MT_CIPHER_BIP_CMAC_128)
|
||||||
|
memmove(data, data + 16, 16);
|
||||||
|
memset(data + 16, 0, 16);
|
||||||
|
} else {
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mt76_wr_copy(dev, addr, data, sizeof(data));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
|
||||||
|
enum mt7615_cipher_type cipher, int keyidx,
|
||||||
|
enum set_key_cmd cmd)
|
||||||
|
{
|
||||||
|
u32 addr = mt7615_mac_wtbl_addr(wcid->idx), w0, w1;
|
||||||
|
|
||||||
|
if (!mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000))
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
|
||||||
|
w0 = mt76_rr(dev, addr);
|
||||||
|
w1 = mt76_rr(dev, addr + 4);
|
||||||
|
if (cmd == SET_KEY) {
|
||||||
|
w0 |= MT_WTBL_W0_RX_KEY_VALID |
|
||||||
|
FIELD_PREP(MT_WTBL_W0_RX_IK_VALID,
|
||||||
|
cipher == MT_CIPHER_BIP_CMAC_128);
|
||||||
|
if (cipher != MT_CIPHER_BIP_CMAC_128 ||
|
||||||
|
!wcid->cipher)
|
||||||
|
w0 |= FIELD_PREP(MT_WTBL_W0_KEY_IDX, keyidx);
|
||||||
|
} else {
|
||||||
|
if (!(wcid->cipher & ~BIT(cipher)))
|
||||||
|
w0 &= ~(MT_WTBL_W0_RX_KEY_VALID |
|
||||||
|
MT_WTBL_W0_KEY_IDX);
|
||||||
|
if (cipher == MT_CIPHER_BIP_CMAC_128)
|
||||||
|
w0 &= ~MT_WTBL_W0_RX_IK_VALID;
|
||||||
|
}
|
||||||
|
mt76_wr(dev, MT_WTBL_RICR0, w0);
|
||||||
|
mt76_wr(dev, MT_WTBL_RICR1, w1);
|
||||||
|
|
||||||
|
mt76_wr(dev, MT_WTBL_UPDATE,
|
||||||
|
FIELD_PREP(MT_WTBL_UPDATE_WLAN_IDX, wcid->idx) |
|
||||||
|
MT_WTBL_UPDATE_RXINFO_UPDATE);
|
||||||
|
|
||||||
|
if (!mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000))
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid,
|
||||||
|
enum mt7615_cipher_type cipher,
|
||||||
|
enum set_key_cmd cmd)
|
||||||
|
{
|
||||||
|
u32 addr = mt7615_mac_wtbl_addr(wcid->idx);
|
||||||
|
|
||||||
|
if (cmd == SET_KEY) {
|
||||||
|
if (cipher != MT_CIPHER_BIP_CMAC_128 || !wcid->cipher)
|
||||||
|
mt76_rmw(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE,
|
||||||
|
FIELD_PREP(MT_WTBL_W2_KEY_TYPE, cipher));
|
||||||
|
} else {
|
||||||
|
if (cipher != MT_CIPHER_BIP_CMAC_128 &&
|
||||||
|
wcid->cipher & BIT(MT_CIPHER_BIP_CMAC_128))
|
||||||
|
mt76_rmw(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE,
|
||||||
|
FIELD_PREP(MT_WTBL_W2_KEY_TYPE,
|
||||||
|
MT_CIPHER_BIP_CMAC_128));
|
||||||
|
else if (!(wcid->cipher & ~BIT(cipher)))
|
||||||
|
mt76_clear(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
|
||||||
|
struct mt76_wcid *wcid,
|
||||||
|
struct ieee80211_key_conf *key,
|
||||||
|
enum set_key_cmd cmd)
|
||||||
|
{
|
||||||
|
enum mt7615_cipher_type cipher;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
cipher = mt7615_mac_get_cipher(key->cipher);
|
||||||
|
if (cipher == MT_CIPHER_NONE)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
spin_lock_bh(&dev->mt76.lock);
|
||||||
|
|
||||||
|
mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cmd);
|
||||||
|
err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cmd);
|
||||||
|
if (err < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, key->keyidx,
|
||||||
|
cmd);
|
||||||
|
if (err < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (cmd == SET_KEY)
|
||||||
|
wcid->cipher |= BIT(cipher);
|
||||||
|
else
|
||||||
|
wcid->cipher &= ~BIT(cipher);
|
||||||
|
|
||||||
|
out:
|
||||||
|
spin_unlock_bh(&dev->mt76.lock);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||||
enum mt76_txq_id qid, struct mt76_wcid *wcid,
|
enum mt76_txq_id qid, struct mt76_wcid *wcid,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta,
|
||||||
@ -469,9 +782,9 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||||||
|
|
||||||
if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
|
if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
|
||||||
spin_lock_bh(&dev->mt76.lock);
|
spin_lock_bh(&dev->mt76.lock);
|
||||||
msta->rate_probe = true;
|
mt7615_mac_set_rates(dev, msta, &info->control.rates[0],
|
||||||
mt7615_mcu_set_rates(dev, msta, &info->control.rates[0],
|
|
||||||
msta->rates);
|
msta->rates);
|
||||||
|
msta->rate_probe = true;
|
||||||
spin_unlock_bh(&dev->mt76.lock);
|
spin_unlock_bh(&dev->mt76.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,9 +836,13 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,
|
|||||||
struct ieee80211_tx_info *info, __le32 *txs_data)
|
struct ieee80211_tx_info *info, __le32 *txs_data)
|
||||||
{
|
{
|
||||||
struct ieee80211_supported_band *sband;
|
struct ieee80211_supported_band *sband;
|
||||||
int i, idx, count, final_idx = 0;
|
struct mt7615_rate_set *rs;
|
||||||
|
int first_idx = 0, last_idx;
|
||||||
|
int i, idx, count;
|
||||||
bool fixed_rate, ack_timeout;
|
bool fixed_rate, ack_timeout;
|
||||||
bool probe, ampdu, cck = false;
|
bool probe, ampdu, cck = false;
|
||||||
|
bool rs_idx;
|
||||||
|
u32 rate_set_tsf;
|
||||||
u32 final_rate, final_rate_flags, final_nss, txs;
|
u32 final_rate, final_rate_flags, final_nss, txs;
|
||||||
|
|
||||||
fixed_rate = info->status.rates[0].count;
|
fixed_rate = info->status.rates[0].count;
|
||||||
@ -536,6 +853,7 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,
|
|||||||
|
|
||||||
txs = le32_to_cpu(txs_data[3]);
|
txs = le32_to_cpu(txs_data[3]);
|
||||||
count = FIELD_GET(MT_TXS3_TX_COUNT, txs);
|
count = FIELD_GET(MT_TXS3_TX_COUNT, txs);
|
||||||
|
last_idx = FIELD_GET(MT_TXS3_LAST_TX_RATE, txs);
|
||||||
|
|
||||||
txs = le32_to_cpu(txs_data[0]);
|
txs = le32_to_cpu(txs_data[0]);
|
||||||
final_rate = FIELD_GET(MT_TXS0_TX_RATE, txs);
|
final_rate = FIELD_GET(MT_TXS0_TX_RATE, txs);
|
||||||
@ -557,38 +875,57 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta,
|
|||||||
if (ampdu || (info->flags & IEEE80211_TX_CTL_AMPDU))
|
if (ampdu || (info->flags & IEEE80211_TX_CTL_AMPDU))
|
||||||
info->flags |= IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_CTL_AMPDU;
|
info->flags |= IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_CTL_AMPDU;
|
||||||
|
|
||||||
|
first_idx = max_t(int, 0, last_idx - (count + 1) / MT7615_RATE_RETRY);
|
||||||
|
|
||||||
if (fixed_rate && !probe) {
|
if (fixed_rate && !probe) {
|
||||||
info->status.rates[0].count = count;
|
info->status.rates[0].count = count;
|
||||||
|
i = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, idx = 0; i < ARRAY_SIZE(info->status.rates); i++) {
|
rate_set_tsf = READ_ONCE(sta->rate_set_tsf);
|
||||||
int cur_count = min_t(int, count, 2 * MT7615_RATE_RETRY);
|
rs_idx = !((u32)(FIELD_GET(MT_TXS4_F0_TIMESTAMP, le32_to_cpu(txs_data[4])) -
|
||||||
|
rate_set_tsf) < 1000000);
|
||||||
|
rs_idx ^= rate_set_tsf & BIT(0);
|
||||||
|
rs = &sta->rateset[rs_idx];
|
||||||
|
|
||||||
if (!i && probe) {
|
if (!first_idx && rs->probe_rate.idx >= 0) {
|
||||||
cur_count = 1;
|
info->status.rates[0] = rs->probe_rate;
|
||||||
|
|
||||||
|
spin_lock_bh(&dev->mt76.lock);
|
||||||
|
if (sta->rate_probe) {
|
||||||
|
mt7615_mac_set_rates(dev, sta, NULL, sta->rates);
|
||||||
|
sta->rate_probe = false;
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&dev->mt76.lock);
|
||||||
} else {
|
} else {
|
||||||
info->status.rates[i] = sta->rates[idx];
|
info->status.rates[0] = rs->rates[first_idx / 2];
|
||||||
idx++;
|
|
||||||
}
|
}
|
||||||
|
info->status.rates[0].count = 0;
|
||||||
|
|
||||||
if (i && info->status.rates[i].idx < 0) {
|
for (i = 0, idx = first_idx; count && idx <= last_idx; idx++) {
|
||||||
info->status.rates[i - 1].count += count;
|
struct ieee80211_tx_rate *cur_rate;
|
||||||
break;
|
int cur_count;
|
||||||
}
|
|
||||||
|
|
||||||
if (!count) {
|
cur_rate = &rs->rates[idx / 2];
|
||||||
info->status.rates[i].idx = -1;
|
cur_count = min_t(int, MT7615_RATE_RETRY, count);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
info->status.rates[i].count = cur_count;
|
|
||||||
final_idx = i;
|
|
||||||
count -= cur_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:
|
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)) {
|
switch (FIELD_GET(MT_TX_RATE_MODE, final_rate)) {
|
||||||
case MT_PHY_TYPE_CCK:
|
case MT_PHY_TYPE_CCK:
|
||||||
@ -613,6 +950,10 @@ out:
|
|||||||
break;
|
break;
|
||||||
case MT_PHY_TYPE_VHT:
|
case MT_PHY_TYPE_VHT:
|
||||||
final_nss = FIELD_GET(MT_TX_RATE_NSS, final_rate);
|
final_nss = FIELD_GET(MT_TX_RATE_NSS, final_rate);
|
||||||
|
|
||||||
|
if ((final_rate & MT_TX_RATE_STBC) && final_nss)
|
||||||
|
final_nss--;
|
||||||
|
|
||||||
final_rate_flags |= IEEE80211_TX_RC_VHT_MCS;
|
final_rate_flags |= IEEE80211_TX_RC_VHT_MCS;
|
||||||
final_rate = (final_rate & MT_TX_RATE_IDX) | (final_nss << 4);
|
final_rate = (final_rate & MT_TX_RATE_IDX) | (final_nss << 4);
|
||||||
break;
|
break;
|
||||||
@ -620,8 +961,8 @@ out:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->status.rates[final_idx].idx = final_rate;
|
info->status.rates[i].idx = final_rate;
|
||||||
info->status.rates[final_idx].flags = final_rate_flags;
|
info->status.rates[i].flags = final_rate_flags;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -642,16 +983,6 @@ static bool mt7615_mac_add_txs_skb(struct mt7615_dev *dev,
|
|||||||
if (skb) {
|
if (skb) {
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(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) {
|
|
||||||
mt7615_mcu_set_rates(dev, sta, NULL,
|
|
||||||
sta->rates);
|
|
||||||
sta->rate_probe = false;
|
|
||||||
}
|
|
||||||
spin_unlock_bh(&dev->mt76.lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mt7615_fill_txs(dev, sta, info, txs_data)) {
|
if (!mt7615_fill_txs(dev, sta, info, txs_data)) {
|
||||||
ieee80211_tx_info_clear_status(info);
|
ieee80211_tx_info_clear_status(info);
|
||||||
info->status.rates[0].idx = -1;
|
info->status.rates[0].idx = -1;
|
||||||
@ -735,6 +1066,198 @@ void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
|
|||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_mac_set_default_sensitivity(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
mt76_rmw(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
|
||||||
|
MT_WF_PHY_B0_PD_OFDM_MASK,
|
||||||
|
MT_WF_PHY_B0_PD_OFDM(0x13c));
|
||||||
|
mt76_rmw(dev, MT_WF_PHY_B1_MIN_PRI_PWR,
|
||||||
|
MT_WF_PHY_B1_PD_OFDM_MASK,
|
||||||
|
MT_WF_PHY_B1_PD_OFDM(0x13c));
|
||||||
|
|
||||||
|
mt76_rmw(dev, MT_WF_PHY_B0_RXTD_CCK_PD,
|
||||||
|
MT_WF_PHY_B0_PD_CCK_MASK,
|
||||||
|
MT_WF_PHY_B0_PD_CCK(0x92));
|
||||||
|
mt76_rmw(dev, MT_WF_PHY_B1_RXTD_CCK_PD,
|
||||||
|
MT_WF_PHY_B1_PD_CCK_MASK,
|
||||||
|
MT_WF_PHY_B1_PD_CCK(0x92));
|
||||||
|
|
||||||
|
dev->ofdm_sensitivity = -98;
|
||||||
|
dev->cck_sensitivity = -110;
|
||||||
|
dev->last_cca_adj = jiffies;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable)
|
||||||
|
{
|
||||||
|
mutex_lock(&dev->mt76.mutex);
|
||||||
|
|
||||||
|
if (dev->scs_en == enable)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
/* DBDC not supported */
|
||||||
|
mt76_set(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
|
||||||
|
MT_WF_PHY_B0_PD_BLK);
|
||||||
|
if (is_mt7622(&dev->mt76)) {
|
||||||
|
mt76_set(dev, MT_MIB_M0_MISC_CR, 0x7 << 8);
|
||||||
|
mt76_set(dev, MT_MIB_M0_MISC_CR, 0x7);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mt76_clear(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
|
||||||
|
MT_WF_PHY_B0_PD_BLK);
|
||||||
|
mt76_clear(dev, MT_WF_PHY_B1_MIN_PRI_PWR,
|
||||||
|
MT_WF_PHY_B1_PD_BLK);
|
||||||
|
}
|
||||||
|
|
||||||
|
mt7615_mac_set_default_sensitivity(dev);
|
||||||
|
dev->scs_en = enable;
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt7615_mac_cca_stats_reset(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
mt76_clear(dev, MT_WF_PHY_R0_B0_PHYMUX_5, GENMASK(22, 20));
|
||||||
|
mt76_set(dev, MT_WF_PHY_R0_B0_PHYMUX_5, BIT(22) | BIT(20));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_mac_adjust_sensitivity(struct mt7615_dev *dev,
|
||||||
|
u32 rts_err_rate, bool ofdm)
|
||||||
|
{
|
||||||
|
int false_cca = ofdm ? dev->false_cca_ofdm : dev->false_cca_cck;
|
||||||
|
u16 def_th = ofdm ? -98 : -110;
|
||||||
|
bool update = false;
|
||||||
|
s8 *sensitivity;
|
||||||
|
int signal;
|
||||||
|
|
||||||
|
sensitivity = ofdm ? &dev->ofdm_sensitivity : &dev->cck_sensitivity;
|
||||||
|
signal = mt76_get_min_avg_rssi(&dev->mt76);
|
||||||
|
if (!signal) {
|
||||||
|
mt7615_mac_set_default_sensitivity(dev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal = min(signal, -72);
|
||||||
|
if (false_cca > 500) {
|
||||||
|
if (rts_err_rate > MT_FRAC(40, 100))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* decrease coverage */
|
||||||
|
if (*sensitivity == def_th && signal > -90) {
|
||||||
|
*sensitivity = -90;
|
||||||
|
update = true;
|
||||||
|
} else if (*sensitivity + 2 < signal) {
|
||||||
|
*sensitivity += 2;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
} else if ((false_cca > 0 && false_cca < 50) ||
|
||||||
|
rts_err_rate > MT_FRAC(60, 100)) {
|
||||||
|
/* increase coverage */
|
||||||
|
if (*sensitivity - 2 >= def_th) {
|
||||||
|
*sensitivity -= 2;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*sensitivity > signal) {
|
||||||
|
*sensitivity = signal;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
u16 val;
|
||||||
|
|
||||||
|
if (ofdm) {
|
||||||
|
/* DBDC not supported */
|
||||||
|
val = *sensitivity * 2 + 512;
|
||||||
|
mt76_rmw(dev, MT_WF_PHY_B0_MIN_PRI_PWR,
|
||||||
|
MT_WF_PHY_B0_PD_OFDM_MASK,
|
||||||
|
MT_WF_PHY_B0_PD_OFDM(val));
|
||||||
|
} else {
|
||||||
|
val = *sensitivity + 256;
|
||||||
|
mt76_rmw(dev, MT_WF_PHY_B0_RXTD_CCK_PD,
|
||||||
|
MT_WF_PHY_B0_PD_CCK_MASK,
|
||||||
|
MT_WF_PHY_B0_PD_CCK(val));
|
||||||
|
mt76_rmw(dev, MT_WF_PHY_B1_RXTD_CCK_PD,
|
||||||
|
MT_WF_PHY_B1_PD_CCK_MASK,
|
||||||
|
MT_WF_PHY_B1_PD_CCK(val));
|
||||||
|
}
|
||||||
|
dev->last_cca_adj = jiffies;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_mac_scs_check(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
u32 val, rts_cnt = 0, rts_retries_cnt = 0, rts_err_rate = 0;
|
||||||
|
u32 mdrdy_cck, mdrdy_ofdm, pd_cck, pd_ofdm;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!dev->scs_en)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
u32 data;
|
||||||
|
|
||||||
|
val = mt76_rr(dev, MT_MIB_MB_SDR0(i));
|
||||||
|
data = FIELD_GET(MT_MIB_RTS_RETRIES_COUNT_MASK, val);
|
||||||
|
if (data > rts_retries_cnt) {
|
||||||
|
rts_cnt = FIELD_GET(MT_MIB_RTS_COUNT_MASK, val);
|
||||||
|
rts_retries_cnt = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val = mt76_rr(dev, MT_WF_PHY_R0_B0_PHYCTRL_STS0);
|
||||||
|
pd_cck = FIELD_GET(MT_WF_PHYCTRL_STAT_PD_CCK, val);
|
||||||
|
pd_ofdm = FIELD_GET(MT_WF_PHYCTRL_STAT_PD_OFDM, val);
|
||||||
|
|
||||||
|
val = mt76_rr(dev, MT_WF_PHY_R0_B0_PHYCTRL_STS5);
|
||||||
|
mdrdy_cck = FIELD_GET(MT_WF_PHYCTRL_STAT_MDRDY_CCK, val);
|
||||||
|
mdrdy_ofdm = FIELD_GET(MT_WF_PHYCTRL_STAT_MDRDY_OFDM, val);
|
||||||
|
|
||||||
|
dev->false_cca_ofdm = pd_ofdm - mdrdy_ofdm;
|
||||||
|
dev->false_cca_cck = pd_cck - mdrdy_cck;
|
||||||
|
mt7615_mac_cca_stats_reset(dev);
|
||||||
|
|
||||||
|
if (rts_cnt + rts_retries_cnt)
|
||||||
|
rts_err_rate = MT_FRAC(rts_retries_cnt,
|
||||||
|
rts_cnt + rts_retries_cnt);
|
||||||
|
|
||||||
|
/* cck */
|
||||||
|
mt7615_mac_adjust_sensitivity(dev, rts_err_rate, false);
|
||||||
|
/* ofdm */
|
||||||
|
mt7615_mac_adjust_sensitivity(dev, rts_err_rate, true);
|
||||||
|
|
||||||
|
if (time_after(jiffies, dev->last_cca_adj + 10 * HZ))
|
||||||
|
mt7615_mac_set_default_sensitivity(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt7615_update_channel(struct mt76_dev *mdev)
|
||||||
|
{
|
||||||
|
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||||
|
struct mt76_channel_state *state;
|
||||||
|
ktime_t cur_time;
|
||||||
|
u32 busy;
|
||||||
|
|
||||||
|
if (!test_bit(MT76_STATE_RUNNING, &mdev->state))
|
||||||
|
return;
|
||||||
|
|
||||||
|
state = mt76_channel_state(mdev, mdev->chandef.chan);
|
||||||
|
/* TODO: add DBDC support */
|
||||||
|
busy = mt76_get_field(dev, MT_MIB_SDR16(0), MT_MIB_BUSY_MASK);
|
||||||
|
|
||||||
|
spin_lock_bh(&mdev->cc_lock);
|
||||||
|
cur_time = ktime_get_boottime();
|
||||||
|
state->cc_busy += busy;
|
||||||
|
state->cc_active += ktime_to_us(ktime_sub(cur_time,
|
||||||
|
mdev->survey_time));
|
||||||
|
mdev->survey_time = cur_time;
|
||||||
|
spin_unlock_bh(&mdev->cc_lock);
|
||||||
|
}
|
||||||
|
|
||||||
void mt7615_mac_work(struct work_struct *work)
|
void mt7615_mac_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct mt7615_dev *dev;
|
struct mt7615_dev *dev;
|
||||||
@ -742,7 +1265,103 @@ void mt7615_mac_work(struct work_struct *work)
|
|||||||
dev = (struct mt7615_dev *)container_of(work, struct mt76_dev,
|
dev = (struct mt7615_dev *)container_of(work, struct mt76_dev,
|
||||||
mac_work.work);
|
mac_work.work);
|
||||||
|
|
||||||
|
mutex_lock(&dev->mt76.mutex);
|
||||||
|
mt7615_update_channel(&dev->mt76);
|
||||||
|
if (++dev->mac_work_count == 5) {
|
||||||
|
mt7615_mac_scs_check(dev);
|
||||||
|
dev->mac_work_count = 0;
|
||||||
|
}
|
||||||
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
|
|
||||||
mt76_tx_status_check(&dev->mt76, NULL, false);
|
mt76_tx_status_check(&dev->mt76, NULL, false);
|
||||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||||
MT7615_WATCHDOG_TIME);
|
MT7615_WATCHDOG_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = mt7615_mcu_rdd_cmd(dev, RDD_STOP, MT_HW_RDD0,
|
||||||
|
MT_RX_SEL0, 0);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (chandef->width == NL80211_CHAN_WIDTH_160 ||
|
||||||
|
chandef->width == NL80211_CHAN_WIDTH_80P80)
|
||||||
|
err = mt7615_mcu_rdd_cmd(dev, RDD_STOP, MT_HW_RDD1,
|
||||||
|
MT_RX_SEL0, 0);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt7615_dfs_start_rdd(struct mt7615_dev *dev, int chain)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = mt7615_mcu_rdd_cmd(dev, RDD_START, chain, MT_RX_SEL0, 0);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return mt7615_mcu_rdd_cmd(dev, RDD_DET_MODE, chain,
|
||||||
|
MT_RX_SEL0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* start CAC */
|
||||||
|
err = mt7615_mcu_rdd_cmd(dev, RDD_CAC_START, MT_HW_RDD0,
|
||||||
|
MT_RX_SEL0, 0);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* TODO: DBDC support */
|
||||||
|
|
||||||
|
err = mt7615_dfs_start_rdd(dev, MT_HW_RDD0);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (chandef->width == NL80211_CHAN_WIDTH_160 ||
|
||||||
|
chandef->width == NL80211_CHAN_WIDTH_80P80) {
|
||||||
|
err = mt7615_dfs_start_rdd(dev, MT_HW_RDD1);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt7615_dfs_init_radar_detector(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (dev->mt76.region == NL80211_DFS_UNSET)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (test_bit(MT76_SCANNING, &dev->mt76.state))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (dev->dfs_state == chandef->chan->dfs_state)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dev->dfs_state = chandef->chan->dfs_state;
|
||||||
|
|
||||||
|
if (chandef->chan->flags & IEEE80211_CHAN_RADAR) {
|
||||||
|
if (chandef->chan->dfs_state != NL80211_DFS_AVAILABLE)
|
||||||
|
return mt7615_dfs_start_radar_detector(dev);
|
||||||
|
else
|
||||||
|
return mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, MT_HW_RDD0,
|
||||||
|
MT_RX_SEL0, 0);
|
||||||
|
} else {
|
||||||
|
err = mt7615_mcu_rdd_cmd(dev, RDD_NORMAL_START,
|
||||||
|
MT_HW_RDD0, MT_RX_SEL0, 0);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return mt7615_dfs_stop_radar_detector(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -302,4 +302,32 @@ struct mt7615_tx_free {
|
|||||||
#define MT_TXS6_F1_RCPI_1 GENMASK(15, 8)
|
#define MT_TXS6_F1_RCPI_1 GENMASK(15, 8)
|
||||||
#define MT_TXS6_F1_RCPI_0 GENMASK(7, 0)
|
#define MT_TXS6_F1_RCPI_0 GENMASK(7, 0)
|
||||||
|
|
||||||
|
enum mt7615_cipher_type {
|
||||||
|
MT_CIPHER_NONE,
|
||||||
|
MT_CIPHER_WEP40,
|
||||||
|
MT_CIPHER_TKIP,
|
||||||
|
MT_CIPHER_TKIP_NO_MIC,
|
||||||
|
MT_CIPHER_AES_CCMP,
|
||||||
|
MT_CIPHER_WEP104,
|
||||||
|
MT_CIPHER_BIP_CMAC_128,
|
||||||
|
MT_CIPHER_WEP128,
|
||||||
|
MT_CIPHER_WAPI,
|
||||||
|
MT_CIPHER_CCMP_256 = 10,
|
||||||
|
MT_CIPHER_GCMP,
|
||||||
|
MT_CIPHER_GCMP_256,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct mt7615_txp *
|
||||||
|
mt7615_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t)
|
||||||
|
{
|
||||||
|
u8 *txwi;
|
||||||
|
|
||||||
|
if (!t)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
txwi = mt76_get_txwi_ptr(dev, t);
|
||||||
|
|
||||||
|
return (struct mt7615_txp *)(txwi + MT_TXD_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,6 +16,7 @@ static int mt7615_start(struct ieee80211_hw *hw)
|
|||||||
{
|
{
|
||||||
struct mt7615_dev *dev = hw->priv;
|
struct mt7615_dev *dev = hw->priv;
|
||||||
|
|
||||||
|
dev->mt76.survey_time = ktime_get_boottime();
|
||||||
set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
|
set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
|
||||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||||
MT7615_WATCHDOG_TIME);
|
MT7615_WATCHDOG_TIME);
|
||||||
@ -85,9 +86,9 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
|
|||||||
}
|
}
|
||||||
mvif->omac_idx = idx;
|
mvif->omac_idx = idx;
|
||||||
|
|
||||||
/* TODO: DBDC support. Use band 0 and wmm 0 for now */
|
/* TODO: DBDC support. Use band 0 for now */
|
||||||
mvif->band_idx = 0;
|
mvif->band_idx = 0;
|
||||||
mvif->wmm_idx = 0;
|
mvif->wmm_idx = mvif->idx % MT7615_MAX_WMM_SETS;
|
||||||
|
|
||||||
ret = mt7615_mcu_set_dev_info(dev, vif, 1);
|
ret = mt7615_mcu_set_dev_info(dev, vif, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -135,20 +136,32 @@ static int mt7615_set_channel(struct mt7615_dev *dev)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cancel_delayed_work_sync(&dev->mt76.mac_work);
|
cancel_delayed_work_sync(&dev->mt76.mac_work);
|
||||||
|
|
||||||
|
mutex_lock(&dev->mt76.mutex);
|
||||||
set_bit(MT76_RESET, &dev->mt76.state);
|
set_bit(MT76_RESET, &dev->mt76.state);
|
||||||
|
|
||||||
|
mt7615_dfs_check_channel(dev);
|
||||||
|
|
||||||
mt76_set_channel(&dev->mt76);
|
mt76_set_channel(&dev->mt76);
|
||||||
|
|
||||||
ret = mt7615_mcu_set_channel(dev);
|
ret = mt7615_mcu_set_channel(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out;
|
||||||
|
|
||||||
|
ret = mt7615_dfs_init_radar_detector(dev);
|
||||||
|
mt7615_mac_cca_stats_reset(dev);
|
||||||
|
dev->mt76.survey_time = ktime_get_boottime();
|
||||||
|
/* TODO: add DBDC support */
|
||||||
|
mt76_rr(dev, MT_MIB_SDR16(0));
|
||||||
|
|
||||||
|
out:
|
||||||
clear_bit(MT76_RESET, &dev->mt76.state);
|
clear_bit(MT76_RESET, &dev->mt76.state);
|
||||||
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
|
|
||||||
mt76_txq_schedule_all(&dev->mt76);
|
mt76_txq_schedule_all(&dev->mt76);
|
||||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||||
MT7615_WATCHDOG_TIME);
|
MT7615_WATCHDOG_TIME);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||||
@ -172,18 +185,34 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||||||
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
|
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
/* fall back to sw encryption for unsupported ciphers */
|
||||||
|
switch (key->cipher) {
|
||||||
|
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||||
|
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;
|
||||||
|
break;
|
||||||
|
case WLAN_CIPHER_SUITE_WEP40:
|
||||||
|
case WLAN_CIPHER_SUITE_WEP104:
|
||||||
|
case WLAN_CIPHER_SUITE_TKIP:
|
||||||
|
case WLAN_CIPHER_SUITE_CCMP:
|
||||||
|
case WLAN_CIPHER_SUITE_CCMP_256:
|
||||||
|
case WLAN_CIPHER_SUITE_GCMP:
|
||||||
|
case WLAN_CIPHER_SUITE_GCMP_256:
|
||||||
|
case WLAN_CIPHER_SUITE_SMS4:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd == SET_KEY) {
|
if (cmd == SET_KEY) {
|
||||||
key->hw_key_idx = wcid->idx;
|
key->hw_key_idx = wcid->idx;
|
||||||
wcid->hw_key_idx = idx;
|
wcid->hw_key_idx = idx;
|
||||||
} else {
|
} else if (idx == wcid->hw_key_idx) {
|
||||||
if (idx == wcid->hw_key_idx)
|
|
||||||
wcid->hw_key_idx = -1;
|
wcid->hw_key_idx = -1;
|
||||||
|
|
||||||
key = NULL;
|
|
||||||
}
|
}
|
||||||
mt76_wcid_key_setup(&dev->mt76, wcid, key);
|
mt76_wcid_key_setup(&dev->mt76, wcid,
|
||||||
|
cmd == SET_KEY ? key : NULL);
|
||||||
|
|
||||||
return mt7615_mcu_set_wtbl_key(dev, wcid->idx, key, cmd);
|
return mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
|
static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
@ -191,14 +220,14 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
|
|||||||
struct mt7615_dev *dev = hw->priv;
|
struct mt7615_dev *dev = hw->priv;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&dev->mt76.mutex);
|
|
||||||
|
|
||||||
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
||||||
ieee80211_stop_queues(hw);
|
ieee80211_stop_queues(hw);
|
||||||
ret = mt7615_set_channel(dev);
|
ret = mt7615_set_channel(dev);
|
||||||
ieee80211_wake_queues(hw);
|
ieee80211_wake_queues(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&dev->mt76.mutex);
|
||||||
|
|
||||||
if (changed & IEEE80211_CONF_CHANGE_POWER)
|
if (changed & IEEE80211_CONF_CHANGE_POWER)
|
||||||
ret = mt7615_mcu_set_tx_power(dev);
|
ret = mt7615_mcu_set_tx_power(dev);
|
||||||
|
|
||||||
@ -220,16 +249,12 @@ static int
|
|||||||
mt7615_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
|
mt7615_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
|
||||||
const struct ieee80211_tx_queue_params *params)
|
const struct ieee80211_tx_queue_params *params)
|
||||||
{
|
{
|
||||||
|
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||||
struct mt7615_dev *dev = hw->priv;
|
struct mt7615_dev *dev = hw->priv;
|
||||||
static const u8 wmm_queue_map[] = {
|
|
||||||
[IEEE80211_AC_BK] = 0,
|
|
||||||
[IEEE80211_AC_BE] = 1,
|
|
||||||
[IEEE80211_AC_VI] = 2,
|
|
||||||
[IEEE80211_AC_VO] = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* TODO: hw wmm_set 1~3 */
|
queue += mvif->wmm_idx * MT7615_MAX_WMM_SETS;
|
||||||
return mt7615_mcu_set_wmm(dev, wmm_queue_map[queue], params);
|
|
||||||
|
return mt7615_mcu_set_wmm(dev, queue, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mt7615_configure_filter(struct ieee80211_hw *hw,
|
static void mt7615_configure_filter(struct ieee80211_hw *hw,
|
||||||
@ -299,6 +324,18 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
|
|||||||
mutex_unlock(&dev->mt76.mutex);
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_channel_switch_beacon(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
|
struct cfg80211_chan_def *chandef)
|
||||||
|
{
|
||||||
|
struct mt7615_dev *dev = hw->priv;
|
||||||
|
|
||||||
|
mutex_lock(&dev->mt76.mutex);
|
||||||
|
mt7615_mcu_set_bcn(dev, vif, true);
|
||||||
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
int mt7615_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
|
int mt7615_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
|
||||||
struct ieee80211_sta *sta)
|
struct ieee80211_sta *sta)
|
||||||
{
|
{
|
||||||
@ -358,7 +395,7 @@ static void mt7615_sta_rate_tbl_update(struct ieee80211_hw *hw,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
msta->n_rates = i;
|
msta->n_rates = i;
|
||||||
mt7615_mcu_set_rates(dev, msta, NULL, msta->rates);
|
mt7615_mac_set_rates(dev, msta, NULL, msta->rates);
|
||||||
msta->rate_probe = false;
|
msta->rate_probe = false;
|
||||||
spin_unlock_bh(&dev->mt76.lock);
|
spin_unlock_bh(&dev->mt76.lock);
|
||||||
}
|
}
|
||||||
@ -410,7 +447,7 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
struct ieee80211_txq *txq = sta->txq[params->tid];
|
struct ieee80211_txq *txq = sta->txq[params->tid];
|
||||||
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
|
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
|
||||||
u16 tid = params->tid;
|
u16 tid = params->tid;
|
||||||
u16 *ssn = ¶ms->ssn;
|
u16 ssn = params->ssn;
|
||||||
struct mt76_txq *mtxq;
|
struct mt76_txq *mtxq;
|
||||||
|
|
||||||
if (!txq)
|
if (!txq)
|
||||||
@ -420,7 +457,7 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case IEEE80211_AMPDU_RX_START:
|
case IEEE80211_AMPDU_RX_START:
|
||||||
mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, *ssn,
|
mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,
|
||||||
params->buf_size);
|
params->buf_size);
|
||||||
mt7615_mcu_set_rx_ba(dev, params, 1);
|
mt7615_mcu_set_rx_ba(dev, params, 1);
|
||||||
break;
|
break;
|
||||||
@ -436,11 +473,10 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
||||||
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
||||||
mtxq->aggr = false;
|
mtxq->aggr = false;
|
||||||
ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
|
|
||||||
mt7615_mcu_set_tx_ba(dev, params, 0);
|
mt7615_mcu_set_tx_ba(dev, params, 0);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_TX_START:
|
case IEEE80211_AMPDU_TX_START:
|
||||||
mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(*ssn);
|
mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
|
||||||
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_TX_STOP_CONT:
|
case IEEE80211_AMPDU_TX_STOP_CONT:
|
||||||
@ -453,23 +489,6 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
mt7615_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
||||||
const u8 *mac)
|
|
||||||
{
|
|
||||||
struct mt7615_dev *dev = hw->priv;
|
|
||||||
|
|
||||||
set_bit(MT76_SCANNING, &dev->mt76.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
mt7615_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|
||||||
{
|
|
||||||
struct mt7615_dev *dev = hw->priv;
|
|
||||||
|
|
||||||
clear_bit(MT76_SCANNING, &dev->mt76.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct ieee80211_ops mt7615_ops = {
|
const struct ieee80211_ops mt7615_ops = {
|
||||||
.tx = mt7615_tx,
|
.tx = mt7615_tx,
|
||||||
.start = mt7615_start,
|
.start = mt7615_start,
|
||||||
@ -486,8 +505,10 @@ const struct ieee80211_ops mt7615_ops = {
|
|||||||
.set_rts_threshold = mt7615_set_rts_threshold,
|
.set_rts_threshold = mt7615_set_rts_threshold,
|
||||||
.wake_tx_queue = mt76_wake_tx_queue,
|
.wake_tx_queue = mt76_wake_tx_queue,
|
||||||
.sta_rate_tbl_update = mt7615_sta_rate_tbl_update,
|
.sta_rate_tbl_update = mt7615_sta_rate_tbl_update,
|
||||||
.sw_scan_start = mt7615_sw_scan,
|
.sw_scan_start = mt76_sw_scan,
|
||||||
.sw_scan_complete = mt7615_sw_scan_complete,
|
.sw_scan_complete = mt76_sw_scan_complete,
|
||||||
.release_buffered_frames = mt76_release_buffered_frames,
|
.release_buffered_frames = mt76_release_buffered_frames,
|
||||||
.get_txpower = mt76_get_txpower,
|
.get_txpower = mt76_get_txpower,
|
||||||
|
.channel_switch_beacon = mt7615_channel_switch_beacon,
|
||||||
|
.get_survey = mt76_get_survey,
|
||||||
};
|
};
|
||||||
|
@ -75,7 +75,7 @@ static int __mt7615_mcu_msg_send(struct mt7615_dev *dev, struct sk_buff *skb,
|
|||||||
|
|
||||||
txd = mcu_txd->txd;
|
txd = mcu_txd->txd;
|
||||||
|
|
||||||
val = FIELD_PREP(MT_TXD0_TX_BYTES, cpu_to_le16(skb->len)) |
|
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
|
||||||
FIELD_PREP(MT_TXD0_P_IDX, MT_TX_PORT_IDX_MCU) |
|
FIELD_PREP(MT_TXD0_P_IDX, MT_TX_PORT_IDX_MCU) |
|
||||||
FIELD_PREP(MT_TXD0_Q_IDX, q_idx);
|
FIELD_PREP(MT_TXD0_Q_IDX, q_idx);
|
||||||
txd[0] = cpu_to_le32(val);
|
txd[0] = cpu_to_le32(val);
|
||||||
@ -112,13 +112,39 @@ static int __mt7615_mcu_msg_send(struct mt7615_dev *dev, struct sk_buff *skb,
|
|||||||
return mt76_tx_queue_skb_raw(dev, qid, skb, 0);
|
return mt76_tx_queue_skb_raw(dev, qid, skb, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7615_mcu_parse_response(struct mt7615_dev *dev, int cmd,
|
||||||
|
struct sk_buff *skb, int seq)
|
||||||
|
{
|
||||||
|
struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (seq != rxd->seq)
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case -MCU_CMD_PATCH_SEM_CONTROL:
|
||||||
|
skb_pull(skb, sizeof(*rxd) - 4);
|
||||||
|
ret = *skb->data;
|
||||||
|
break;
|
||||||
|
case MCU_EXT_CMD_GET_TEMP:
|
||||||
|
skb_pull(skb, sizeof(*rxd));
|
||||||
|
ret = le32_to_cpu(*(__le32 *)skb->data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
|
mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
|
||||||
int len, bool wait_resp)
|
int len, bool wait_resp)
|
||||||
{
|
{
|
||||||
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||||
unsigned long expires = jiffies + 10 * HZ;
|
unsigned long expires = jiffies + 10 * HZ;
|
||||||
struct mt7615_mcu_rxd *rxd;
|
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int ret, seq;
|
int ret, seq;
|
||||||
|
|
||||||
@ -141,15 +167,8 @@ mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rxd = (struct mt7615_mcu_rxd *)skb->data;
|
ret = mt7615_mcu_parse_response(dev, cmd, skb, seq);
|
||||||
if (seq != rxd->seq)
|
if (ret != -EAGAIN)
|
||||||
continue;
|
|
||||||
|
|
||||||
if (cmd == -MCU_CMD_PATCH_SEM_CONTROL) {
|
|
||||||
skb_pull(skb, sizeof(*rxd) - 4);
|
|
||||||
ret = *skb->data;
|
|
||||||
}
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +178,62 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
||||||
|
{
|
||||||
|
if (vif->csa_active)
|
||||||
|
ieee80211_csa_finish(vif);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;
|
||||||
|
|
||||||
|
switch (rxd->ext_eid) {
|
||||||
|
case MCU_EXT_EVENT_RDD_REPORT:
|
||||||
|
ieee80211_radar_detected(dev->mt76.hw);
|
||||||
|
dev->hw_pattern++;
|
||||||
|
break;
|
||||||
|
case MCU_EXT_EVENT_CSA_NOTIFY:
|
||||||
|
ieee80211_iterate_active_interfaces_atomic(dev->mt76.hw,
|
||||||
|
IEEE80211_IFACE_ITER_RESUME_ALL,
|
||||||
|
mt7615_mcu_csa_finish, dev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mt7615_mcu_rx_unsolicited_event(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;
|
||||||
|
|
||||||
|
switch (rxd->eid) {
|
||||||
|
case MCU_EVENT_EXT:
|
||||||
|
mt7615_mcu_rx_ext_event(dev, skb);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mt7615_mcu_rx_event(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;
|
||||||
|
|
||||||
|
if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
|
||||||
|
rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
|
||||||
|
rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
|
||||||
|
rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
|
||||||
|
!rxd->seq)
|
||||||
|
mt7615_mcu_rx_unsolicited_event(dev, skb);
|
||||||
|
else
|
||||||
|
mt76_mcu_rx_event(&dev->mt76, skb);
|
||||||
|
}
|
||||||
|
|
||||||
static int mt7615_mcu_init_download(struct mt7615_dev *dev, u32 addr,
|
static int mt7615_mcu_init_download(struct mt7615_dev *dev, u32 addr,
|
||||||
u32 len, u32 mode)
|
u32 len, u32 mode)
|
||||||
{
|
{
|
||||||
@ -192,6 +267,7 @@ static int mt7615_mcu_send_firmware(struct mt7615_dev *dev, const void *data,
|
|||||||
|
|
||||||
data += cur_len;
|
data += cur_len;
|
||||||
len -= cur_len;
|
len -= cur_len;
|
||||||
|
mt76_queue_tx_cleanup(dev, MT_TXQ_FWDL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -257,9 +333,9 @@ static int mt7615_driver_own(struct mt7615_dev *dev)
|
|||||||
|
|
||||||
static int mt7615_load_patch(struct mt7615_dev *dev)
|
static int mt7615_load_patch(struct mt7615_dev *dev)
|
||||||
{
|
{
|
||||||
const struct firmware *fw;
|
|
||||||
const struct mt7615_patch_hdr *hdr;
|
|
||||||
const char *firmware = MT7615_ROM_PATCH;
|
const char *firmware = MT7615_ROM_PATCH;
|
||||||
|
const struct mt7615_patch_hdr *hdr;
|
||||||
|
const struct firmware *fw = NULL;
|
||||||
int len, ret, sem;
|
int len, ret, sem;
|
||||||
|
|
||||||
sem = mt7615_mcu_patch_sem_ctrl(dev, 1);
|
sem = mt7615_mcu_patch_sem_ctrl(dev, 1);
|
||||||
@ -275,7 +351,7 @@ static int mt7615_load_patch(struct mt7615_dev *dev)
|
|||||||
|
|
||||||
ret = request_firmware(&fw, firmware, dev->mt76.dev);
|
ret = request_firmware(&fw, firmware, dev->mt76.dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out;
|
||||||
|
|
||||||
if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
|
if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
|
||||||
dev_err(dev->mt76.dev, "Invalid firmware\n");
|
dev_err(dev->mt76.dev, "Invalid firmware\n");
|
||||||
@ -323,7 +399,7 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 gen_dl_mode(u8 feature_set, bool is_cr4)
|
static u32 mt7615_mcu_gen_dl_mode(u8 feature_set, bool is_cr4)
|
||||||
{
|
{
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
|
|
||||||
@ -337,14 +413,45 @@ static u32 gen_dl_mode(u8 feature_set, bool is_cr4)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7615_mcu_send_ram_firmware(struct mt7615_dev *dev,
|
||||||
|
const struct mt7615_fw_trailer *hdr,
|
||||||
|
const u8 *data, bool is_cr4)
|
||||||
|
{
|
||||||
|
int n_region = is_cr4 ? CR4_REGION_NUM : N9_REGION_NUM;
|
||||||
|
int err, i, offset = 0;
|
||||||
|
u32 len, addr, mode;
|
||||||
|
|
||||||
|
for (i = 0; i < n_region; i++) {
|
||||||
|
mode = mt7615_mcu_gen_dl_mode(hdr[i].feature_set, is_cr4);
|
||||||
|
len = le32_to_cpu(hdr[i].len) + IMG_CRC_LEN;
|
||||||
|
addr = le32_to_cpu(hdr[i].addr);
|
||||||
|
|
||||||
|
err = mt7615_mcu_init_download(dev, addr, len, mode);
|
||||||
|
if (err) {
|
||||||
|
dev_err(dev->mt76.dev, "Download request failed\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mt7615_mcu_send_firmware(dev, data + offset, len);
|
||||||
|
if (err) {
|
||||||
|
dev_err(dev->mt76.dev, "Failed to send firmware to device\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mt7615_load_ram(struct mt7615_dev *dev)
|
static int mt7615_load_ram(struct mt7615_dev *dev)
|
||||||
{
|
{
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
const struct mt7615_fw_trailer *hdr;
|
const struct mt7615_fw_trailer *hdr;
|
||||||
const char *n9_firmware = MT7615_FIRMWARE_N9;
|
const char *n9_firmware = MT7615_FIRMWARE_N9;
|
||||||
const char *cr4_firmware = MT7615_FIRMWARE_CR4;
|
const char *cr4_firmware = MT7615_FIRMWARE_CR4;
|
||||||
u32 n9_ilm_addr, offset;
|
int ret;
|
||||||
int i, ret;
|
|
||||||
|
|
||||||
ret = request_firmware(&fw, n9_firmware, dev->mt76.dev);
|
ret = request_firmware(&fw, n9_firmware, dev->mt76.dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -362,31 +469,12 @@ static int mt7615_load_ram(struct mt7615_dev *dev)
|
|||||||
dev_info(dev->mt76.dev, "N9 Firmware Version: %.10s, Build Time: %.15s\n",
|
dev_info(dev->mt76.dev, "N9 Firmware Version: %.10s, Build Time: %.15s\n",
|
||||||
hdr->fw_ver, hdr->build_date);
|
hdr->fw_ver, hdr->build_date);
|
||||||
|
|
||||||
n9_ilm_addr = le32_to_cpu(hdr->addr);
|
ret = mt7615_mcu_send_ram_firmware(dev, hdr, fw->data, false);
|
||||||
|
if (ret)
|
||||||
for (offset = 0, i = 0; i < N9_REGION_NUM; i++) {
|
|
||||||
u32 len, addr, mode;
|
|
||||||
|
|
||||||
len = le32_to_cpu(hdr[i].len) + IMG_CRC_LEN;
|
|
||||||
addr = le32_to_cpu(hdr[i].addr);
|
|
||||||
mode = gen_dl_mode(hdr[i].feature_set, false);
|
|
||||||
|
|
||||||
ret = mt7615_mcu_init_download(dev, addr, len, mode);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev->mt76.dev, "Download request failed\n");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
ret = mt7615_mcu_send_firmware(dev, fw->data + offset, len);
|
ret = mt7615_mcu_start_firmware(dev, le32_to_cpu(hdr->addr),
|
||||||
if (ret) {
|
FW_START_OVERRIDE);
|
||||||
dev_err(dev->mt76.dev, "Failed to send firmware to device\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = mt7615_mcu_start_firmware(dev, n9_ilm_addr, FW_START_OVERRIDE);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev->mt76.dev, "Failed to start N9 firmware\n");
|
dev_err(dev->mt76.dev, "Failed to start N9 firmware\n");
|
||||||
goto out;
|
goto out;
|
||||||
@ -410,27 +498,9 @@ static int mt7615_load_ram(struct mt7615_dev *dev)
|
|||||||
dev_info(dev->mt76.dev, "CR4 Firmware Version: %.10s, Build Time: %.15s\n",
|
dev_info(dev->mt76.dev, "CR4 Firmware Version: %.10s, Build Time: %.15s\n",
|
||||||
hdr->fw_ver, hdr->build_date);
|
hdr->fw_ver, hdr->build_date);
|
||||||
|
|
||||||
for (offset = 0, i = 0; i < CR4_REGION_NUM; i++) {
|
ret = mt7615_mcu_send_ram_firmware(dev, hdr, fw->data, true);
|
||||||
u32 len, addr, mode;
|
if (ret)
|
||||||
|
|
||||||
len = le32_to_cpu(hdr[i].len) + IMG_CRC_LEN;
|
|
||||||
addr = le32_to_cpu(hdr[i].addr);
|
|
||||||
mode = gen_dl_mode(hdr[i].feature_set, true);
|
|
||||||
|
|
||||||
ret = mt7615_mcu_init_download(dev, addr, len, mode);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev->mt76.dev, "Download request failed\n");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
ret = mt7615_mcu_send_firmware(dev, fw->data + offset, len);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev->mt76.dev, "Failed to send firmware to device\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = mt7615_mcu_start_firmware(dev, 0, FW_START_WORKING_PDA_CR4);
|
ret = mt7615_mcu_start_firmware(dev, 0, FW_START_WORKING_PDA_CR4);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -469,6 +539,8 @@ static int mt7615_load_firmware(struct mt7615_dev *dev)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mt76_queue_tx_cleanup(dev, MT_TXQ_FWDL, false);
|
||||||
|
|
||||||
dev_dbg(dev->mt76.dev, "Firmware init done\n");
|
dev_dbg(dev->mt76.dev, "Firmware init done\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -573,6 +645,8 @@ int mt7615_mcu_set_wmm(struct mt7615_dev *dev, u8 queue,
|
|||||||
#define WMM_CW_MIN_SET BIT(1)
|
#define WMM_CW_MIN_SET BIT(1)
|
||||||
#define WMM_CW_MAX_SET BIT(2)
|
#define WMM_CW_MAX_SET BIT(2)
|
||||||
#define WMM_TXOP_SET BIT(3)
|
#define WMM_TXOP_SET BIT(3)
|
||||||
|
#define WMM_PARAM_SET (WMM_AIFS_SET | WMM_CW_MIN_SET | \
|
||||||
|
WMM_CW_MAX_SET | WMM_TXOP_SET)
|
||||||
struct req_data {
|
struct req_data {
|
||||||
u8 number;
|
u8 number;
|
||||||
u8 rsv[3];
|
u8 rsv[3];
|
||||||
@ -585,19 +659,17 @@ int mt7615_mcu_set_wmm(struct mt7615_dev *dev, u8 queue,
|
|||||||
} __packed req = {
|
} __packed req = {
|
||||||
.number = 1,
|
.number = 1,
|
||||||
.queue = queue,
|
.queue = queue,
|
||||||
.valid = WMM_AIFS_SET | WMM_TXOP_SET,
|
.valid = WMM_PARAM_SET,
|
||||||
.aifs = params->aifs,
|
.aifs = params->aifs,
|
||||||
|
.cw_min = 5,
|
||||||
|
.cw_max = cpu_to_le16(10),
|
||||||
.txop = cpu_to_le16(params->txop),
|
.txop = cpu_to_le16(params->txop),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (params->cw_min) {
|
if (params->cw_min)
|
||||||
req.valid |= WMM_CW_MIN_SET;
|
req.cw_min = fls(params->cw_min);
|
||||||
req.cw_min = params->cw_min;
|
if (params->cw_max)
|
||||||
}
|
req.cw_max = cpu_to_le16(fls(params->cw_max));
|
||||||
if (params->cw_max) {
|
|
||||||
req.valid |= WMM_CW_MAX_SET;
|
|
||||||
req.cw_max = cpu_to_le16(params->cw_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EDCA_UPDATE,
|
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EDCA_UPDATE,
|
||||||
&req, sizeof(req), true);
|
&req, sizeof(req), true);
|
||||||
@ -824,78 +896,6 @@ int mt7615_mcu_set_bss_info(struct mt7615_dev *dev,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mt7615_cipher_type
|
|
||||||
mt7615_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
|
|
||||||
{
|
|
||||||
if (!key || key->keylen > 32)
|
|
||||||
return MT_CIPHER_NONE;
|
|
||||||
|
|
||||||
memcpy(key_data, key->key, key->keylen);
|
|
||||||
|
|
||||||
switch (key->cipher) {
|
|
||||||
case WLAN_CIPHER_SUITE_WEP40:
|
|
||||||
return MT_CIPHER_WEP40;
|
|
||||||
case WLAN_CIPHER_SUITE_WEP104:
|
|
||||||
return MT_CIPHER_WEP104;
|
|
||||||
case WLAN_CIPHER_SUITE_TKIP:
|
|
||||||
/* Rx/Tx MIC keys are swapped */
|
|
||||||
memcpy(key_data + 16, key->key + 24, 8);
|
|
||||||
memcpy(key_data + 24, key->key + 16, 8);
|
|
||||||
return MT_CIPHER_TKIP;
|
|
||||||
case WLAN_CIPHER_SUITE_CCMP:
|
|
||||||
return MT_CIPHER_AES_CCMP;
|
|
||||||
case WLAN_CIPHER_SUITE_CCMP_256:
|
|
||||||
return MT_CIPHER_CCMP_256;
|
|
||||||
case WLAN_CIPHER_SUITE_GCMP:
|
|
||||||
return MT_CIPHER_GCMP;
|
|
||||||
case WLAN_CIPHER_SUITE_GCMP_256:
|
|
||||||
return MT_CIPHER_GCMP_256;
|
|
||||||
case WLAN_CIPHER_SUITE_SMS4:
|
|
||||||
return MT_CIPHER_WAPI;
|
|
||||||
default:
|
|
||||||
return MT_CIPHER_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mt7615_mcu_set_wtbl_key(struct mt7615_dev *dev, int wcid,
|
|
||||||
struct ieee80211_key_conf *key,
|
|
||||||
enum set_key_cmd cmd)
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
struct wtbl_req_hdr hdr;
|
|
||||||
struct wtbl_sec_key key;
|
|
||||||
} req = {
|
|
||||||
.hdr = {
|
|
||||||
.wlan_idx = wcid,
|
|
||||||
.operation = WTBL_SET,
|
|
||||||
.tlv_num = cpu_to_le16(1),
|
|
||||||
},
|
|
||||||
.key = {
|
|
||||||
.tag = cpu_to_le16(WTBL_SEC_KEY),
|
|
||||||
.len = cpu_to_le16(sizeof(struct wtbl_sec_key)),
|
|
||||||
.add = cmd,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (cmd == SET_KEY) {
|
|
||||||
u8 cipher;
|
|
||||||
|
|
||||||
cipher = mt7615_get_key_info(key, req.key.key_material);
|
|
||||||
if (cipher == MT_CIPHER_NONE)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
req.key.rkv = 1;
|
|
||||||
req.key.cipher_id = cipher;
|
|
||||||
req.key.key_id = key->keyidx;
|
|
||||||
req.key.key_len = key->keylen;
|
|
||||||
} else {
|
|
||||||
req.key.key_len = sizeof(req.key.key_material);
|
|
||||||
}
|
|
||||||
|
|
||||||
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_WTBL_UPDATE,
|
|
||||||
&req, sizeof(req), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mt7615_mcu_add_wtbl_bmc(struct mt7615_dev *dev,
|
mt7615_mcu_add_wtbl_bmc(struct mt7615_dev *dev,
|
||||||
struct mt7615_vif *mvif)
|
struct mt7615_vif *mvif)
|
||||||
@ -1099,6 +1099,7 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
|||||||
{
|
{
|
||||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||||
struct mt76_wcid *wcid = &dev->mt76.global_wcid;
|
struct mt76_wcid *wcid = &dev->mt76.global_wcid;
|
||||||
|
struct ieee80211_mutable_offsets offs;
|
||||||
struct req {
|
struct req {
|
||||||
u8 omac_idx;
|
u8 omac_idx;
|
||||||
u8 enable;
|
u8 enable;
|
||||||
@ -1119,13 +1120,10 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
|||||||
.enable = en,
|
.enable = en,
|
||||||
.wlan_idx = wcid->idx,
|
.wlan_idx = wcid->idx,
|
||||||
.band_idx = mvif->band_idx,
|
.band_idx = mvif->band_idx,
|
||||||
/* pky_type: 0 for bcn, 1 for tim */
|
|
||||||
.pkt_type = 0,
|
|
||||||
};
|
};
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
u16 tim_off;
|
|
||||||
|
|
||||||
skb = ieee80211_beacon_get_tim(mt76_hw(dev), vif, &tim_off, NULL);
|
skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -1139,8 +1137,14 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
|||||||
0, NULL);
|
0, NULL);
|
||||||
memcpy(req.pkt + MT_TXD_SIZE, skb->data, skb->len);
|
memcpy(req.pkt + MT_TXD_SIZE, skb->data, skb->len);
|
||||||
req.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
|
req.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
|
||||||
req.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + tim_off);
|
req.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
|
||||||
|
if (offs.csa_counter_offs[0]) {
|
||||||
|
u16 csa_offs;
|
||||||
|
|
||||||
|
csa_offs = MT_TXD_SIZE + offs.csa_counter_offs[0] - 4;
|
||||||
|
req.csa_ie_pos = cpu_to_le16(csa_offs);
|
||||||
|
req.csa_cnt = skb->data[offs.csa_counter_offs[0]];
|
||||||
|
}
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
|
|
||||||
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_BCN_OFFLOAD,
|
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_BCN_OFFLOAD,
|
||||||
@ -1213,9 +1217,62 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
|
||||||
|
enum mt7615_rdd_cmd cmd, u8 index,
|
||||||
|
u8 rx_sel, u8 val)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
u8 ctrl;
|
||||||
|
u8 rdd_idx;
|
||||||
|
u8 rdd_rx_sel;
|
||||||
|
u8 val;
|
||||||
|
u8 rsv[4];
|
||||||
|
} req = {
|
||||||
|
.ctrl = cmd,
|
||||||
|
.rdd_idx = index,
|
||||||
|
.rdd_rx_sel = rx_sel,
|
||||||
|
.val = val,
|
||||||
|
};
|
||||||
|
|
||||||
|
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_CTRL,
|
||||||
|
&req, sizeof(req), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
u8 pulse_num;
|
||||||
|
u8 rsv[3];
|
||||||
|
struct {
|
||||||
|
u32 start_time;
|
||||||
|
u16 width;
|
||||||
|
s16 power;
|
||||||
|
} pattern[32];
|
||||||
|
} req = {
|
||||||
|
.pulse_num = dev->radar_pattern.n_pulses,
|
||||||
|
};
|
||||||
|
u32 start_time = ktime_to_ms(ktime_get_boottime());
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (dev->radar_pattern.n_pulses > ARRAY_SIZE(req.pattern))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* TODO: add some noise here */
|
||||||
|
for (i = 0; i < dev->radar_pattern.n_pulses; i++) {
|
||||||
|
req.pattern[i].width = dev->radar_pattern.width;
|
||||||
|
req.pattern[i].power = dev->radar_pattern.power;
|
||||||
|
req.pattern[i].start_time = start_time +
|
||||||
|
i * dev->radar_pattern.period;
|
||||||
|
}
|
||||||
|
|
||||||
|
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_PATTERN,
|
||||||
|
&req, sizeof(req), false);
|
||||||
|
}
|
||||||
|
|
||||||
int mt7615_mcu_set_channel(struct mt7615_dev *dev)
|
int mt7615_mcu_set_channel(struct mt7615_dev *dev)
|
||||||
{
|
{
|
||||||
struct cfg80211_chan_def *chdef = &dev->mt76.chandef;
|
struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
|
||||||
|
int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
|
||||||
struct {
|
struct {
|
||||||
u8 control_chan;
|
u8 control_chan;
|
||||||
u8 center_chan;
|
u8 center_chan;
|
||||||
@ -1234,17 +1291,20 @@ int mt7615_mcu_set_channel(struct mt7615_dev *dev)
|
|||||||
u8 rsv1[3];
|
u8 rsv1[3];
|
||||||
u8 txpower_sku[53];
|
u8 txpower_sku[53];
|
||||||
u8 rsv2[3];
|
u8 rsv2[3];
|
||||||
} req = {0};
|
} req = {
|
||||||
|
.control_chan = chandef->chan->hw_value,
|
||||||
|
.center_chan = ieee80211_frequency_to_channel(freq1),
|
||||||
|
.tx_streams = (dev->mt76.chainmask >> 8) & 0xf,
|
||||||
|
.rx_streams_mask = dev->mt76.antenna_mask,
|
||||||
|
.center_chan2 = ieee80211_frequency_to_channel(freq2),
|
||||||
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
req.control_chan = chdef->chan->hw_value;
|
if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) &&
|
||||||
req.center_chan = ieee80211_frequency_to_channel(chdef->center_freq1);
|
chandef->chan->dfs_state != NL80211_DFS_AVAILABLE)
|
||||||
req.tx_streams = (dev->mt76.chainmask >> 8) & 0xf;
|
req.switch_reason = CH_SWITCH_DFS;
|
||||||
req.rx_streams_mask = dev->mt76.antenna_mask;
|
else
|
||||||
req.switch_reason = CH_SWITCH_NORMAL;
|
req.switch_reason = CH_SWITCH_NORMAL;
|
||||||
req.band_idx = 0;
|
|
||||||
req.center_chan2 = ieee80211_frequency_to_channel(chdef->center_freq2);
|
|
||||||
req.txpower_drop = 0;
|
|
||||||
|
|
||||||
switch (dev->mt76.chandef.width) {
|
switch (dev->mt76.chandef.width) {
|
||||||
case NL80211_CHAN_WIDTH_40:
|
case NL80211_CHAN_WIDTH_40:
|
||||||
@ -1269,6 +1329,7 @@ int mt7615_mcu_set_channel(struct mt7615_dev *dev)
|
|||||||
case NL80211_CHAN_WIDTH_20:
|
case NL80211_CHAN_WIDTH_20:
|
||||||
default:
|
default:
|
||||||
req.bw = CMD_CBW_20MHZ;
|
req.bw = CMD_CBW_20MHZ;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
memset(req.txpower_sku, 0x3f, 49);
|
memset(req.txpower_sku, 0x3f, 49);
|
||||||
|
|
||||||
@ -1533,92 +1594,15 @@ int mt7615_mcu_set_rx_ba(struct mt7615_dev *dev,
|
|||||||
&wtbl_req, sizeof(wtbl_req), true);
|
&wtbl_req, sizeof(wtbl_req), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mt7615_mcu_set_rates(struct mt7615_dev *dev, struct mt7615_sta *sta,
|
int mt7615_mcu_get_temperature(struct mt7615_dev *dev, int index)
|
||||||
struct ieee80211_tx_rate *probe_rate,
|
|
||||||
struct ieee80211_tx_rate *rates)
|
|
||||||
{
|
{
|
||||||
int wcid = sta->wcid.idx;
|
struct {
|
||||||
u32 addr = MT_WTBL_BASE + wcid * MT_WTBL_ENTRY_SIZE;
|
u8 action;
|
||||||
bool stbc = false;
|
u8 rsv[3];
|
||||||
int n_rates = sta->n_rates;
|
} req = {
|
||||||
u8 bw, bw_prev, bw_idx = 0;
|
.action = index,
|
||||||
u16 val[4];
|
};
|
||||||
u16 probe_val;
|
|
||||||
u32 w5, w27;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000))
|
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_GET_TEMP, &req,
|
||||||
return;
|
sizeof(req), true);
|
||||||
|
|
||||||
for (i = n_rates; i < 4; i++)
|
|
||||||
rates[i] = rates[n_rates - 1];
|
|
||||||
|
|
||||||
val[0] = mt7615_mac_tx_rate_val(dev, &rates[0], stbc, &bw);
|
|
||||||
bw_prev = bw;
|
|
||||||
|
|
||||||
if (probe_rate) {
|
|
||||||
probe_val = mt7615_mac_tx_rate_val(dev, probe_rate, stbc, &bw);
|
|
||||||
if (bw)
|
|
||||||
bw_idx = 1;
|
|
||||||
else
|
|
||||||
bw_prev = 0;
|
|
||||||
} else {
|
|
||||||
probe_val = val[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
val[1] = mt7615_mac_tx_rate_val(dev, &rates[1], stbc, &bw);
|
|
||||||
if (bw_prev) {
|
|
||||||
bw_idx = 3;
|
|
||||||
bw_prev = bw;
|
|
||||||
}
|
|
||||||
|
|
||||||
val[2] = mt7615_mac_tx_rate_val(dev, &rates[2], stbc, &bw);
|
|
||||||
if (bw_prev) {
|
|
||||||
bw_idx = 5;
|
|
||||||
bw_prev = bw;
|
|
||||||
}
|
|
||||||
|
|
||||||
val[3] = mt7615_mac_tx_rate_val(dev, &rates[3], stbc, &bw);
|
|
||||||
if (bw_prev)
|
|
||||||
bw_idx = 7;
|
|
||||||
|
|
||||||
w27 = mt76_rr(dev, addr + 27 * 4);
|
|
||||||
w27 &= ~MT_WTBL_W27_CC_BW_SEL;
|
|
||||||
w27 |= FIELD_PREP(MT_WTBL_W27_CC_BW_SEL, bw);
|
|
||||||
|
|
||||||
w5 = mt76_rr(dev, addr + 5 * 4);
|
|
||||||
w5 &= ~(MT_WTBL_W5_BW_CAP | MT_WTBL_W5_CHANGE_BW_RATE);
|
|
||||||
w5 |= FIELD_PREP(MT_WTBL_W5_BW_CAP, bw) |
|
|
||||||
FIELD_PREP(MT_WTBL_W5_CHANGE_BW_RATE, bw_idx ? bw_idx - 1 : 7);
|
|
||||||
|
|
||||||
mt76_wr(dev, MT_WTBL_RIUCR0, w5);
|
|
||||||
|
|
||||||
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]));
|
|
||||||
|
|
||||||
mt76_wr(dev, MT_WTBL_RIUCR2,
|
|
||||||
FIELD_PREP(MT_WTBL_RIUCR2_RATE2_HI, val[0] >> 8) |
|
|
||||||
FIELD_PREP(MT_WTBL_RIUCR2_RATE3, val[1]) |
|
|
||||||
FIELD_PREP(MT_WTBL_RIUCR2_RATE4, val[1]) |
|
|
||||||
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_RATE7, val[3]));
|
|
||||||
|
|
||||||
mt76_wr(dev, MT_WTBL_UPDATE,
|
|
||||||
FIELD_PREP(MT_WTBL_UPDATE_WLAN_IDX, wcid) |
|
|
||||||
MT_WTBL_UPDATE_RATE_UPDATE |
|
|
||||||
MT_WTBL_UPDATE_TX_COUNT_CLEAR);
|
|
||||||
|
|
||||||
mt76_wr(dev, addr + 27 * 4, w27);
|
|
||||||
|
|
||||||
if (!(sta->wcid.tx_info & MT_WCID_TX_INFO_SET))
|
|
||||||
mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000);
|
|
||||||
|
|
||||||
sta->rate_count = 2 * MT7615_RATE_RETRY * n_rates;
|
|
||||||
sta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,28 @@ struct mt7615_mcu_txd {
|
|||||||
u32 reserved[5];
|
u32 reserved[5];
|
||||||
} __packed __aligned(4);
|
} __packed __aligned(4);
|
||||||
|
|
||||||
|
/* event table */
|
||||||
|
enum {
|
||||||
|
MCU_EVENT_TARGET_ADDRESS_LEN = 0x01,
|
||||||
|
MCU_EVENT_FW_START = 0x01,
|
||||||
|
MCU_EVENT_GENERIC = 0x01,
|
||||||
|
MCU_EVENT_ACCESS_REG = 0x02,
|
||||||
|
MCU_EVENT_MT_PATCH_SEM = 0x04,
|
||||||
|
MCU_EVENT_CH_PRIVILEGE = 0x18,
|
||||||
|
MCU_EVENT_EXT = 0xed,
|
||||||
|
MCU_EVENT_RESTART_DL = 0xef,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ext event table */
|
||||||
|
enum {
|
||||||
|
MCU_EXT_EVENT_PS_SYNC = 0x5,
|
||||||
|
MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
|
||||||
|
MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
|
||||||
|
MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
|
||||||
|
MCU_EXT_EVENT_RDD_REPORT = 0x3a,
|
||||||
|
MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
|
||||||
|
};
|
||||||
|
|
||||||
struct mt7615_mcu_rxd {
|
struct mt7615_mcu_rxd {
|
||||||
__le32 rxd[4];
|
__le32 rxd[4];
|
||||||
|
|
||||||
@ -76,11 +98,14 @@ enum {
|
|||||||
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
|
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
|
||||||
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
|
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
|
||||||
MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
|
MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
|
||||||
|
MCU_EXT_CMD_GET_TEMP = 0x2c,
|
||||||
MCU_EXT_CMD_WTBL_UPDATE = 0x32,
|
MCU_EXT_CMD_WTBL_UPDATE = 0x32,
|
||||||
|
MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
|
||||||
MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
|
MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
|
||||||
MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
|
MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
|
||||||
MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
|
MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
|
||||||
MCU_EXT_CMD_SET_RX_PATH = 0x4e,
|
MCU_EXT_CMD_SET_RX_PATH = 0x4e,
|
||||||
|
MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -264,34 +289,6 @@ struct wtbl_hdr_trans {
|
|||||||
u8 rsv;
|
u8 rsv;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
enum mt7615_cipher_type {
|
|
||||||
MT_CIPHER_NONE,
|
|
||||||
MT_CIPHER_WEP40,
|
|
||||||
MT_CIPHER_TKIP,
|
|
||||||
MT_CIPHER_TKIP_NO_MIC,
|
|
||||||
MT_CIPHER_AES_CCMP,
|
|
||||||
MT_CIPHER_WEP104,
|
|
||||||
MT_CIPHER_BIP_CMAC_128,
|
|
||||||
MT_CIPHER_WEP128,
|
|
||||||
MT_CIPHER_WAPI,
|
|
||||||
MT_CIPHER_CCMP_256 = 10,
|
|
||||||
MT_CIPHER_GCMP,
|
|
||||||
MT_CIPHER_GCMP_256,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wtbl_sec_key {
|
|
||||||
__le16 tag;
|
|
||||||
__le16 len;
|
|
||||||
u8 add; /* 0: add, 1: remove */
|
|
||||||
u8 rkv;
|
|
||||||
u8 ikv;
|
|
||||||
u8 cipher_id;
|
|
||||||
u8 key_id;
|
|
||||||
u8 key_len;
|
|
||||||
u8 rsv[2];
|
|
||||||
u8 key_material[32];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MT_BA_TYPE_INVALID,
|
MT_BA_TYPE_INVALID,
|
||||||
MT_BA_TYPE_ORIGINATOR,
|
MT_BA_TYPE_ORIGINATOR,
|
||||||
@ -375,7 +372,6 @@ struct wtbl_raw {
|
|||||||
sizeof(struct wtbl_vht) + \
|
sizeof(struct wtbl_vht) + \
|
||||||
sizeof(struct wtbl_tx_ps) + \
|
sizeof(struct wtbl_tx_ps) + \
|
||||||
sizeof(struct wtbl_hdr_trans) + \
|
sizeof(struct wtbl_hdr_trans) + \
|
||||||
sizeof(struct wtbl_sec_key) + \
|
|
||||||
sizeof(struct wtbl_ba) + \
|
sizeof(struct wtbl_ba) + \
|
||||||
sizeof(struct wtbl_bf) + \
|
sizeof(struct wtbl_bf) + \
|
||||||
sizeof(struct wtbl_smps) + \
|
sizeof(struct wtbl_smps) + \
|
||||||
|
@ -10,12 +10,13 @@
|
|||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
|
||||||
#define MT7615_MAX_INTERFACES 4
|
#define MT7615_MAX_INTERFACES 4
|
||||||
|
#define MT7615_MAX_WMM_SETS 4
|
||||||
#define MT7615_WTBL_SIZE 128
|
#define MT7615_WTBL_SIZE 128
|
||||||
#define MT7615_WTBL_RESERVED (MT7615_WTBL_SIZE - 1)
|
#define MT7615_WTBL_RESERVED (MT7615_WTBL_SIZE - 1)
|
||||||
#define MT7615_WTBL_STA (MT7615_WTBL_RESERVED - \
|
#define MT7615_WTBL_STA (MT7615_WTBL_RESERVED - \
|
||||||
MT7615_MAX_INTERFACES)
|
MT7615_MAX_INTERFACES)
|
||||||
|
|
||||||
#define MT7615_WATCHDOG_TIME 100 /* ms */
|
#define MT7615_WATCHDOG_TIME (HZ / 10)
|
||||||
#define MT7615_RATE_RETRY 2
|
#define MT7615_RATE_RETRY 2
|
||||||
|
|
||||||
#define MT7615_TX_RING_SIZE 1024
|
#define MT7615_TX_RING_SIZE 1024
|
||||||
@ -32,6 +33,9 @@
|
|||||||
#define MT7615_EEPROM_SIZE 1024
|
#define MT7615_EEPROM_SIZE 1024
|
||||||
#define MT7615_TOKEN_SIZE 4096
|
#define MT7615_TOKEN_SIZE 4096
|
||||||
|
|
||||||
|
#define MT_FRAC_SCALE 12
|
||||||
|
#define MT_FRAC(val, div) (((val) << MT_FRAC_SCALE) / (div))
|
||||||
|
|
||||||
struct mt7615_vif;
|
struct mt7615_vif;
|
||||||
struct mt7615_sta;
|
struct mt7615_sta;
|
||||||
|
|
||||||
@ -42,12 +46,21 @@ enum mt7615_hw_txq_id {
|
|||||||
MT7615_TXQ_FWDL,
|
MT7615_TXQ_FWDL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mt7615_rate_set {
|
||||||
|
struct ieee80211_tx_rate probe_rate;
|
||||||
|
struct ieee80211_tx_rate rates[4];
|
||||||
|
};
|
||||||
|
|
||||||
struct mt7615_sta {
|
struct mt7615_sta {
|
||||||
struct mt76_wcid wcid; /* must be first */
|
struct mt76_wcid wcid; /* must be first */
|
||||||
|
|
||||||
struct mt7615_vif *vif;
|
struct mt7615_vif *vif;
|
||||||
|
|
||||||
struct ieee80211_tx_rate rates[8];
|
struct ieee80211_tx_rate rates[4];
|
||||||
|
|
||||||
|
struct mt7615_rate_set rateset[2];
|
||||||
|
u32 rate_set_tsf;
|
||||||
|
|
||||||
u8 rate_count;
|
u8 rate_count;
|
||||||
u8 n_rates;
|
u8 n_rates;
|
||||||
|
|
||||||
@ -68,6 +81,22 @@ struct mt7615_dev {
|
|||||||
u32 vif_mask;
|
u32 vif_mask;
|
||||||
u32 omac_mask;
|
u32 omac_mask;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 n_pulses;
|
||||||
|
u32 period;
|
||||||
|
u16 width;
|
||||||
|
s16 power;
|
||||||
|
} radar_pattern;
|
||||||
|
u32 hw_pattern;
|
||||||
|
int dfs_state;
|
||||||
|
|
||||||
|
int false_cca_ofdm, false_cca_cck;
|
||||||
|
unsigned long last_cca_adj;
|
||||||
|
u8 mac_work_count;
|
||||||
|
s8 ofdm_sensitivity;
|
||||||
|
s8 cck_sensitivity;
|
||||||
|
bool scs_en;
|
||||||
|
|
||||||
spinlock_t token_lock;
|
spinlock_t token_lock;
|
||||||
struct idr token;
|
struct idr token;
|
||||||
};
|
};
|
||||||
@ -97,6 +126,30 @@ enum {
|
|||||||
EXT_BSSID_END
|
EXT_BSSID_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MT_HW_RDD0,
|
||||||
|
MT_HW_RDD1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MT_RX_SEL0,
|
||||||
|
MT_RX_SEL1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mt7615_rdd_cmd {
|
||||||
|
RDD_STOP,
|
||||||
|
RDD_START,
|
||||||
|
RDD_DET_MODE,
|
||||||
|
RDD_DET_STOP,
|
||||||
|
RDD_CAC_START,
|
||||||
|
RDD_CAC_END,
|
||||||
|
RDD_NORMAL_START,
|
||||||
|
RDD_DISABLE_DFS_CAL,
|
||||||
|
RDD_PULSE_DBG,
|
||||||
|
RDD_READ_PULSE,
|
||||||
|
RDD_RESUME_BF,
|
||||||
|
};
|
||||||
|
|
||||||
extern const struct ieee80211_ops mt7615_ops;
|
extern const struct ieee80211_ops mt7615_ops;
|
||||||
extern struct pci_driver mt7615_pci_driver;
|
extern struct pci_driver mt7615_pci_driver;
|
||||||
|
|
||||||
@ -115,10 +168,7 @@ int mt7615_mcu_set_dev_info(struct mt7615_dev *dev,
|
|||||||
struct ieee80211_vif *vif, bool enable);
|
struct ieee80211_vif *vif, bool enable);
|
||||||
int mt7615_mcu_set_bss_info(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
int mt7615_mcu_set_bss_info(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
||||||
int en);
|
int en);
|
||||||
int mt7615_mcu_set_wtbl_key(struct mt7615_dev *dev, int wcid,
|
void mt7615_mac_set_rates(struct mt7615_dev *dev, struct mt7615_sta *sta,
|
||||||
struct ieee80211_key_conf *key,
|
|
||||||
enum set_key_cmd cmd);
|
|
||||||
void mt7615_mcu_set_rates(struct mt7615_dev *dev, struct mt7615_sta *sta,
|
|
||||||
struct ieee80211_tx_rate *probe_rate,
|
struct ieee80211_tx_rate *probe_rate,
|
||||||
struct ieee80211_tx_rate *rates);
|
struct ieee80211_tx_rate *rates);
|
||||||
int mt7615_mcu_wtbl_bmc(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
int mt7615_mcu_wtbl_bmc(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
||||||
@ -144,6 +194,29 @@ int mt7615_mcu_set_rx_ba(struct mt7615_dev *dev,
|
|||||||
bool add);
|
bool add);
|
||||||
int mt7615_mcu_set_ht_cap(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
int mt7615_mcu_set_ht_cap(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
||||||
struct ieee80211_sta *sta);
|
struct ieee80211_sta *sta);
|
||||||
|
void mt7615_mcu_rx_event(struct mt7615_dev *dev, struct sk_buff *skb);
|
||||||
|
int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
|
||||||
|
enum mt7615_rdd_cmd cmd, u8 index,
|
||||||
|
u8 rx_sel, u8 val);
|
||||||
|
int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev);
|
||||||
|
int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev);
|
||||||
|
int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev);
|
||||||
|
|
||||||
|
static inline bool is_mt7622(struct mt76_dev *dev)
|
||||||
|
{
|
||||||
|
return mt76_chip(dev) == 0x7622;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mt7615_dfs_check_channel(struct mt7615_dev *dev)
|
||||||
|
{
|
||||||
|
enum nl80211_chan_width width = dev->mt76.chandef.width;
|
||||||
|
u32 freq = dev->mt76.chandef.chan->center_freq;
|
||||||
|
struct ieee80211_hw *hw = mt76_hw(dev);
|
||||||
|
|
||||||
|
if (hw->conf.chandef.chan->center_freq != freq ||
|
||||||
|
hw->conf.chandef.width != width)
|
||||||
|
dev->dfs_state = -1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void mt7615_irq_enable(struct mt7615_dev *dev, u32 mask)
|
static inline void mt7615_irq_enable(struct mt7615_dev *dev, u32 mask)
|
||||||
{
|
{
|
||||||
@ -155,9 +228,9 @@ static inline void mt7615_irq_disable(struct mt7615_dev *dev, u32 mask)
|
|||||||
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
|
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 mt7615_mac_tx_rate_val(struct mt7615_dev *dev,
|
void mt7615_update_channel(struct mt76_dev *mdev);
|
||||||
const struct ieee80211_tx_rate *rate,
|
void mt7615_mac_cca_stats_reset(struct mt7615_dev *dev);
|
||||||
bool stbc, u8 *bw);
|
void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable);
|
||||||
int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
||||||
struct sk_buff *skb, struct mt76_wcid *wcid,
|
struct sk_buff *skb, struct mt76_wcid *wcid,
|
||||||
struct ieee80211_sta *sta, int pid,
|
struct ieee80211_sta *sta, int pid,
|
||||||
@ -165,11 +238,15 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
|||||||
int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb);
|
int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb);
|
||||||
void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data);
|
void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data);
|
||||||
void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb);
|
void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb);
|
||||||
|
int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
|
||||||
|
struct ieee80211_key_conf *key,
|
||||||
|
enum set_key_cmd cmd);
|
||||||
|
|
||||||
int mt7615_mcu_set_eeprom(struct mt7615_dev *dev);
|
int mt7615_mcu_set_eeprom(struct mt7615_dev *dev);
|
||||||
int mt7615_mcu_init_mac(struct mt7615_dev *dev);
|
int mt7615_mcu_init_mac(struct mt7615_dev *dev);
|
||||||
int mt7615_mcu_set_rts_thresh(struct mt7615_dev *dev, u32 val);
|
int mt7615_mcu_set_rts_thresh(struct mt7615_dev *dev, u32 val);
|
||||||
int mt7615_mcu_ctrl_pm_state(struct mt7615_dev *dev, int enter);
|
int mt7615_mcu_ctrl_pm_state(struct mt7615_dev *dev, int enter);
|
||||||
|
int mt7615_mcu_get_temperature(struct mt7615_dev *dev, int index);
|
||||||
int mt7615_mcu_set_tx_power(struct mt7615_dev *dev);
|
int mt7615_mcu_set_tx_power(struct mt7615_dev *dev);
|
||||||
void mt7615_mcu_exit(struct mt7615_dev *dev);
|
void mt7615_mcu_exit(struct mt7615_dev *dev);
|
||||||
|
|
||||||
@ -193,5 +270,9 @@ void mt7615_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
|
|||||||
void mt7615_mac_work(struct work_struct *work);
|
void mt7615_mac_work(struct work_struct *work);
|
||||||
void mt7615_txp_skb_unmap(struct mt76_dev *dev,
|
void mt7615_txp_skb_unmap(struct mt76_dev *dev,
|
||||||
struct mt76_txwi_cache *txwi);
|
struct mt76_txwi_cache *txwi);
|
||||||
|
int mt76_dfs_start_rdd(struct mt7615_dev *dev, bool force);
|
||||||
|
int mt7615_dfs_init_radar_detector(struct mt7615_dev *dev);
|
||||||
|
|
||||||
|
int mt7615_init_debugfs(struct mt7615_dev *dev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,6 +81,7 @@ static int mt7615_pci_probe(struct pci_dev *pdev,
|
|||||||
.sta_add = mt7615_sta_add,
|
.sta_add = mt7615_sta_add,
|
||||||
.sta_assoc = mt7615_sta_assoc,
|
.sta_assoc = mt7615_sta_assoc,
|
||||||
.sta_remove = mt7615_sta_remove,
|
.sta_remove = mt7615_sta_remove,
|
||||||
|
.update_survey = mt7615_update_channel,
|
||||||
};
|
};
|
||||||
struct mt7615_dev *dev;
|
struct mt7615_dev *dev;
|
||||||
struct mt76_dev *mdev;
|
struct mt76_dev *mdev;
|
||||||
|
@ -71,6 +71,34 @@
|
|||||||
#define MT_WF_PHY_WF2_RFCTRL0 MT_WF_PHY(0x1900)
|
#define MT_WF_PHY_WF2_RFCTRL0 MT_WF_PHY(0x1900)
|
||||||
#define MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN BIT(9)
|
#define MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN BIT(9)
|
||||||
|
|
||||||
|
#define MT_WF_PHY_R0_B0_PHYMUX_5 MT_WF_PHY(0x0614)
|
||||||
|
|
||||||
|
#define MT_WF_PHY_R0_B0_PHYCTRL_STS0 MT_WF_PHY(0x020c)
|
||||||
|
#define MT_WF_PHYCTRL_STAT_PD_OFDM GENMASK(31, 16)
|
||||||
|
#define MT_WF_PHYCTRL_STAT_PD_CCK GENMASK(15, 0)
|
||||||
|
|
||||||
|
#define MT_WF_PHY_R0_B0_PHYCTRL_STS5 MT_WF_PHY(0x0220)
|
||||||
|
#define MT_WF_PHYCTRL_STAT_MDRDY_OFDM GENMASK(31, 16)
|
||||||
|
#define MT_WF_PHYCTRL_STAT_MDRDY_CCK GENMASK(15, 0)
|
||||||
|
|
||||||
|
#define MT_WF_PHY_B0_MIN_PRI_PWR MT_WF_PHY(0x229c)
|
||||||
|
#define MT_WF_PHY_B0_PD_OFDM_MASK GENMASK(28, 20)
|
||||||
|
#define MT_WF_PHY_B0_PD_OFDM(v) ((v) << 20)
|
||||||
|
#define MT_WF_PHY_B0_PD_BLK BIT(19)
|
||||||
|
|
||||||
|
#define MT_WF_PHY_B1_MIN_PRI_PWR MT_WF_PHY(0x084)
|
||||||
|
#define MT_WF_PHY_B1_PD_OFDM_MASK GENMASK(24, 16)
|
||||||
|
#define MT_WF_PHY_B1_PD_OFDM(v) ((v) << 16)
|
||||||
|
#define MT_WF_PHY_B1_PD_BLK BIT(25)
|
||||||
|
|
||||||
|
#define MT_WF_PHY_B0_RXTD_CCK_PD MT_WF_PHY(0x2310)
|
||||||
|
#define MT_WF_PHY_B0_PD_CCK_MASK GENMASK(8, 1)
|
||||||
|
#define MT_WF_PHY_B0_PD_CCK(v) ((v) << 1)
|
||||||
|
|
||||||
|
#define MT_WF_PHY_B1_RXTD_CCK_PD MT_WF_PHY(0x2314)
|
||||||
|
#define MT_WF_PHY_B1_PD_CCK_MASK GENMASK(31, 24)
|
||||||
|
#define MT_WF_PHY_B1_PD_CCK(v) ((v) << 24)
|
||||||
|
|
||||||
#define MT_WF_CFG_BASE 0x20200
|
#define MT_WF_CFG_BASE 0x20200
|
||||||
#define MT_WF_CFG(ofs) (MT_WF_CFG_BASE + (ofs))
|
#define MT_WF_CFG(ofs) (MT_WF_CFG_BASE + (ofs))
|
||||||
|
|
||||||
@ -97,12 +125,25 @@
|
|||||||
MT_AGG_ARxCR_LIMIT_SHIFT(_n), \
|
MT_AGG_ARxCR_LIMIT_SHIFT(_n), \
|
||||||
MT_AGG_ARxCR_LIMIT_SHIFT(_n))
|
MT_AGG_ARxCR_LIMIT_SHIFT(_n))
|
||||||
|
|
||||||
|
#define MT_AGG_ACR0 MT_WF_AGG(0x070)
|
||||||
|
#define MT_AGG_ACR1 MT_WF_AGG(0x170)
|
||||||
|
#define MT_AGG_ACR_NO_BA_RULE BIT(0)
|
||||||
|
#define MT_AGG_ACR_NO_BA_AR_RULE BIT(1)
|
||||||
|
#define MT_AGG_ACR_PKT_TIME_EN BIT(2)
|
||||||
|
#define MT_AGG_ACR_CFEND_RATE GENMASK(15, 4)
|
||||||
|
#define MT_AGG_ACR_BAR_RATE GENMASK(31, 20)
|
||||||
|
|
||||||
#define MT_AGG_SCR MT_WF_AGG(0x0fc)
|
#define MT_AGG_SCR MT_WF_AGG(0x0fc)
|
||||||
#define MT_AGG_SCR_NLNAV_MID_PTEC_DIS BIT(3)
|
#define MT_AGG_SCR_NLNAV_MID_PTEC_DIS BIT(3)
|
||||||
|
|
||||||
#define MT_WF_TMAC_BASE 0x21000
|
#define MT_WF_TMAC_BASE 0x21000
|
||||||
#define MT_WF_TMAC(ofs) (MT_WF_TMAC_BASE + (ofs))
|
#define MT_WF_TMAC(ofs) (MT_WF_TMAC_BASE + (ofs))
|
||||||
|
|
||||||
|
#define MT_TMAC_TRCR0 MT_WF_TMAC(0x09c)
|
||||||
|
#define MT_TMAC_TRCR1 MT_WF_TMAC(0x070)
|
||||||
|
#define MT_TMAC_TRCR_CCA_SEL GENMASK(31, 30)
|
||||||
|
#define MT_TMAC_TRCR_SEC_CCA_SEL GENMASK(29, 28)
|
||||||
|
|
||||||
#define MT_TMAC_CTCR0 MT_WF_TMAC(0x0f4)
|
#define MT_TMAC_CTCR0 MT_WF_TMAC(0x0f4)
|
||||||
#define MT_TMAC_CTCR0_INS_DDLMT_REFTIME GENMASK(5, 0)
|
#define MT_TMAC_CTCR0_INS_DDLMT_REFTIME GENMASK(5, 0)
|
||||||
#define MT_TMAC_CTCR0_INS_DDLMT_DENSITY GENMASK(15, 12)
|
#define MT_TMAC_CTCR0_INS_DDLMT_DENSITY GENMASK(15, 12)
|
||||||
@ -148,8 +189,15 @@
|
|||||||
#define MT_WTBL_OFF_BASE 0x23400
|
#define MT_WTBL_OFF_BASE 0x23400
|
||||||
#define MT_WTBL_OFF(n) (MT_WTBL_OFF_BASE + (n))
|
#define MT_WTBL_OFF(n) (MT_WTBL_OFF_BASE + (n))
|
||||||
|
|
||||||
|
#define MT_WTBL_W0_KEY_IDX GENMASK(24, 23)
|
||||||
|
#define MT_WTBL_W0_RX_KEY_VALID BIT(26)
|
||||||
|
#define MT_WTBL_W0_RX_IK_VALID BIT(27)
|
||||||
|
|
||||||
|
#define MT_WTBL_W2_KEY_TYPE GENMASK(7, 4)
|
||||||
|
|
||||||
#define MT_WTBL_UPDATE MT_WTBL_OFF(0x030)
|
#define MT_WTBL_UPDATE MT_WTBL_OFF(0x030)
|
||||||
#define MT_WTBL_UPDATE_WLAN_IDX GENMASK(7, 0)
|
#define MT_WTBL_UPDATE_WLAN_IDX GENMASK(7, 0)
|
||||||
|
#define MT_WTBL_UPDATE_RXINFO_UPDATE BIT(11)
|
||||||
#define MT_WTBL_UPDATE_RATE_UPDATE BIT(13)
|
#define MT_WTBL_UPDATE_RATE_UPDATE BIT(13)
|
||||||
#define MT_WTBL_UPDATE_TX_COUNT_CLEAR BIT(14)
|
#define MT_WTBL_UPDATE_TX_COUNT_CLEAR BIT(14)
|
||||||
#define MT_WTBL_UPDATE_BUSY BIT(31)
|
#define MT_WTBL_UPDATE_BUSY BIT(31)
|
||||||
@ -157,6 +205,9 @@
|
|||||||
#define MT_WTBL_ON_BASE 0x23000
|
#define MT_WTBL_ON_BASE 0x23000
|
||||||
#define MT_WTBL_ON(_n) (MT_WTBL_ON_BASE + (_n))
|
#define MT_WTBL_ON(_n) (MT_WTBL_ON_BASE + (_n))
|
||||||
|
|
||||||
|
#define MT_WTBL_RICR0 MT_WTBL_ON(0x010)
|
||||||
|
#define MT_WTBL_RICR1 MT_WTBL_ON(0x014)
|
||||||
|
|
||||||
#define MT_WTBL_RIUCR0 MT_WTBL_ON(0x020)
|
#define MT_WTBL_RIUCR0 MT_WTBL_ON(0x020)
|
||||||
|
|
||||||
#define MT_WTBL_RIUCR1 MT_WTBL_ON(0x024)
|
#define MT_WTBL_RIUCR1 MT_WTBL_ON(0x024)
|
||||||
@ -181,8 +232,32 @@
|
|||||||
#define MT_WTBL_W5_SHORT_GI_80 BIT(10)
|
#define MT_WTBL_W5_SHORT_GI_80 BIT(10)
|
||||||
#define MT_WTBL_W5_SHORT_GI_160 BIT(11)
|
#define MT_WTBL_W5_SHORT_GI_160 BIT(11)
|
||||||
#define MT_WTBL_W5_BW_CAP GENMASK(13, 12)
|
#define MT_WTBL_W5_BW_CAP GENMASK(13, 12)
|
||||||
|
#define MT_WTBL_W5_MPDU_FAIL_COUNT GENMASK(25, 23)
|
||||||
|
#define MT_WTBL_W5_MPDU_OK_COUNT GENMASK(28, 26)
|
||||||
|
#define MT_WTBL_W5_RATE_IDX GENMASK(31, 29)
|
||||||
|
|
||||||
#define MT_WTBL_W27_CC_BW_SEL GENMASK(6, 5)
|
#define MT_WTBL_W27_CC_BW_SEL GENMASK(6, 5)
|
||||||
|
|
||||||
|
#define MT_LPON_BASE 0x24200
|
||||||
|
#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_WF_MIB_BASE 0x24800
|
||||||
|
#define MT_WF_MIB(ofs) (MT_WF_MIB_BASE + (ofs))
|
||||||
|
|
||||||
|
#define MT_MIB_M0_MISC_CR MT_WF_MIB(0x00c)
|
||||||
|
#define MT_MIB_MB_SDR0(n) MT_WF_MIB(0x100 + ((n) << 4))
|
||||||
|
#define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16)
|
||||||
|
#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0)
|
||||||
|
|
||||||
|
#define MT_MIB_SDR16(n) MT_WF_MIB(0x48 + ((n) << 9))
|
||||||
|
#define MT_MIB_BUSY_MASK GENMASK(23, 0)
|
||||||
|
|
||||||
#define MT_EFUSE_BASE 0x81070000
|
#define MT_EFUSE_BASE 0x81070000
|
||||||
#define MT_EFUSE_BASE_CTRL 0x000
|
#define MT_EFUSE_BASE_CTRL 0x000
|
||||||
#define MT_EFUSE_BASE_CTRL_EMPTY BIT(30)
|
#define MT_EFUSE_BASE_CTRL_EMPTY BIT(30)
|
||||||
|
@ -10,7 +10,11 @@ config MT76x0U
|
|||||||
depends on MAC80211
|
depends on MAC80211
|
||||||
depends on USB
|
depends on USB
|
||||||
help
|
help
|
||||||
This adds support for MT7610U-based wireless USB dongles.
|
This adds support for MT7610U-based wireless USB 2.0 dongles,
|
||||||
|
which comply with IEEE 802.11ac standards and support 1x1
|
||||||
|
433Mbps PHY rate.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here.
|
||||||
|
|
||||||
config MT76x0E
|
config MT76x0E
|
||||||
tristate "MediaTek MT76x0E (PCIe) support"
|
tristate "MediaTek MT76x0E (PCIe) support"
|
||||||
@ -18,4 +22,8 @@ config MT76x0E
|
|||||||
depends on MAC80211
|
depends on MAC80211
|
||||||
depends on PCI
|
depends on PCI
|
||||||
help
|
help
|
||||||
This adds support for MT7610/MT7630-based wireless PCIe devices.
|
This adds support for MT7610/MT7630-based wireless PCIe devices,
|
||||||
|
which comply with IEEE 802.11ac standards and support 1x1
|
||||||
|
433Mbps PHY rate.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here.
|
||||||
|
@ -8,18 +8,16 @@
|
|||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include "mt76x0.h"
|
#include "mt76x0.h"
|
||||||
|
|
||||||
static int
|
static void
|
||||||
mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
|
mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
cancel_delayed_work_sync(&dev->cal_work);
|
cancel_delayed_work_sync(&dev->cal_work);
|
||||||
dev->beacon_ops->pre_tbtt_enable(dev, false);
|
mt76x02_pre_tbtt_enable(dev, false);
|
||||||
if (mt76_is_mmio(dev))
|
if (mt76_is_mmio(dev))
|
||||||
tasklet_disable(&dev->dfs_pd.dfs_tasklet);
|
tasklet_disable(&dev->dfs_pd.dfs_tasklet);
|
||||||
|
|
||||||
mt76_set_channel(&dev->mt76);
|
mt76_set_channel(&dev->mt76);
|
||||||
ret = mt76x0_phy_set_channel(dev, chandef);
|
mt76x0_phy_set_channel(dev, chandef);
|
||||||
|
|
||||||
/* channel cycle counters read-and-clear */
|
/* channel cycle counters read-and-clear */
|
||||||
mt76_rr(dev, MT_CH_IDLE);
|
mt76_rr(dev, MT_CH_IDLE);
|
||||||
@ -31,23 +29,20 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
|
|||||||
mt76x02_dfs_init_params(dev);
|
mt76x02_dfs_init_params(dev);
|
||||||
tasklet_enable(&dev->dfs_pd.dfs_tasklet);
|
tasklet_enable(&dev->dfs_pd.dfs_tasklet);
|
||||||
}
|
}
|
||||||
dev->beacon_ops->pre_tbtt_enable(dev, true);
|
mt76x02_pre_tbtt_enable(dev, true);
|
||||||
|
|
||||||
mt76_txq_schedule_all(&dev->mt76);
|
mt76_txq_schedule_all(&dev->mt76);
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
|
int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
{
|
{
|
||||||
struct mt76x02_dev *dev = hw->priv;
|
struct mt76x02_dev *dev = hw->priv;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
mutex_lock(&dev->mt76.mutex);
|
mutex_lock(&dev->mt76.mutex);
|
||||||
|
|
||||||
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
||||||
ieee80211_stop_queues(hw);
|
ieee80211_stop_queues(hw);
|
||||||
ret = mt76x0_set_channel(dev, &hw->conf.chandef);
|
mt76x0_set_channel(dev, &hw->conf.chandef);
|
||||||
ieee80211_wake_queues(hw);
|
ieee80211_wake_queues(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +64,6 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
|
|||||||
|
|
||||||
mutex_unlock(&dev->mt76.mutex);
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76x0_config);
|
EXPORT_SYMBOL_GPL(mt76x0_config);
|
||||||
|
@ -54,7 +54,7 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed);
|
|||||||
/* PHY */
|
/* PHY */
|
||||||
void mt76x0_phy_init(struct mt76x02_dev *dev);
|
void mt76x0_phy_init(struct mt76x02_dev *dev);
|
||||||
int mt76x0_phy_wait_bbp_ready(struct mt76x02_dev *dev);
|
int mt76x0_phy_wait_bbp_ready(struct mt76x02_dev *dev);
|
||||||
int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
void mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
||||||
struct cfg80211_chan_def *chandef);
|
struct cfg80211_chan_def *chandef);
|
||||||
void mt76x0_phy_set_txpower(struct mt76x02_dev *dev);
|
void mt76x0_phy_set_txpower(struct mt76x02_dev *dev);
|
||||||
void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on);
|
void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on);
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@ -80,7 +69,7 @@ static const struct ieee80211_ops mt76x0e_ops = {
|
|||||||
.sta_state = mt76_sta_state,
|
.sta_state = mt76_sta_state,
|
||||||
.set_key = mt76x02_set_key,
|
.set_key = mt76x02_set_key,
|
||||||
.conf_tx = mt76x02_conf_tx,
|
.conf_tx = mt76x02_conf_tx,
|
||||||
.sw_scan_start = mt76x02_sw_scan,
|
.sw_scan_start = mt76_sw_scan,
|
||||||
.sw_scan_complete = mt76x02_sw_scan_complete,
|
.sw_scan_complete = mt76x02_sw_scan_complete,
|
||||||
.ampdu_action = mt76x02_ampdu_action,
|
.ampdu_action = mt76x02_ampdu_action,
|
||||||
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
|
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
|
@ -230,7 +230,8 @@ mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_band)
|
mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel,
|
||||||
|
u16 rf_bw_band)
|
||||||
{
|
{
|
||||||
const struct mt76x0_freq_item *freq_item;
|
const struct mt76x0_freq_item *freq_item;
|
||||||
u16 rf_band = rf_bw_band & 0xff00;
|
u16 rf_band = rf_bw_band & 0xff00;
|
||||||
@ -252,9 +253,9 @@ mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_ban
|
|||||||
rf_band = mt76x0_frequency_plan[i].band;
|
rf_band = mt76x0_frequency_plan[i].band;
|
||||||
|
|
||||||
if (b_sdm)
|
if (b_sdm)
|
||||||
freq_item = &(mt76x0_sdm_frequency_plan[i]);
|
freq_item = &mt76x0_sdm_frequency_plan[i];
|
||||||
else
|
else
|
||||||
freq_item = &(mt76x0_frequency_plan[i]);
|
freq_item = &mt76x0_frequency_plan[i];
|
||||||
|
|
||||||
mt76x0_rf_wr(dev, MT_RF(0, 37), freq_item->pllR37);
|
mt76x0_rf_wr(dev, MT_RF(0, 37), freq_item->pllR37);
|
||||||
mt76x0_rf_wr(dev, MT_RF(0, 36), freq_item->pllR36);
|
mt76x0_rf_wr(dev, MT_RF(0, 36), freq_item->pllR36);
|
||||||
@ -359,10 +360,11 @@ mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_ban
|
|||||||
|
|
||||||
band = (rf_band & RF_G_BAND) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
|
band = (rf_band & RF_G_BAND) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
|
||||||
if (mt76x02_ext_pa_enabled(dev, band)) {
|
if (mt76x02_ext_pa_enabled(dev, band)) {
|
||||||
/*
|
/* MT_RF_MISC (offset: 0x0518)
|
||||||
MT_RF_MISC (offset: 0x0518)
|
* [2]1'b1: enable external A band PA
|
||||||
[2]1'b1: enable external A band PA, 1'b0: disable external A band PA
|
* 1'b0: disable external A band PA
|
||||||
[3]1'b1: enable external G band PA, 1'b0: disable external G band PA
|
* [3]1'b1: enable external G band PA
|
||||||
|
* 1'b0: disable external G band PA
|
||||||
*/
|
*/
|
||||||
if (rf_band & RF_A_BAND)
|
if (rf_band & RF_A_BAND)
|
||||||
mt76_set(dev, MT_RF_MISC, BIT(2));
|
mt76_set(dev, MT_RF_MISC, BIT(2));
|
||||||
@ -385,7 +387,9 @@ mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel, u16 rf_bw_ban
|
|||||||
mt76_wr(dev, MT_TX_ALC_CFG_1, mac_reg);
|
mt76_wr(dev, MT_TX_ALC_CFG_1, mac_reg);
|
||||||
} else {
|
} else {
|
||||||
mt76_wr(dev, MT_TX0_RF_GAIN_ATTEN, 0x686A7800);
|
mt76_wr(dev, MT_TX0_RF_GAIN_ATTEN, 0x686A7800);
|
||||||
/* Set Atten mode = 0 For Ext A band, Disable Tx Inc dcoc Cal. */
|
/* Set Atten mode = 0
|
||||||
|
* For Ext A band, Disable Tx Inc dcoc Cal.
|
||||||
|
*/
|
||||||
mac_reg = mt76_rr(dev, MT_TX_ALC_CFG_1);
|
mac_reg = mt76_rr(dev, MT_TX_ALC_CFG_1);
|
||||||
mac_reg &= 0x890400FF;
|
mac_reg &= 0x890400FF;
|
||||||
mt76_wr(dev, MT_TX_ALC_CFG_1, mac_reg);
|
mt76_wr(dev, MT_TX_ALC_CFG_1, mac_reg);
|
||||||
@ -490,7 +494,7 @@ mt76x0_phy_bbp_set_bw(struct mt76x02_dev *dev, enum nl80211_chan_width width)
|
|||||||
case NL80211_CHAN_WIDTH_160:
|
case NL80211_CHAN_WIDTH_160:
|
||||||
case NL80211_CHAN_WIDTH_5:
|
case NL80211_CHAN_WIDTH_5:
|
||||||
/* TODO error */
|
/* TODO error */
|
||||||
return ;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mt76x02_mcu_function_select(dev, BW_SETTING, bw);
|
mt76x02_mcu_function_select(dev, BW_SETTING, bw);
|
||||||
@ -905,7 +909,7 @@ void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76x0_phy_calibrate);
|
EXPORT_SYMBOL_GPL(mt76x0_phy_calibrate);
|
||||||
|
|
||||||
int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
void mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
||||||
struct cfg80211_chan_def *chandef)
|
struct cfg80211_chan_def *chandef)
|
||||||
{
|
{
|
||||||
u32 ext_cca_chan[4] = {
|
u32 ext_cca_chan[4] = {
|
||||||
@ -940,7 +944,6 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
|||||||
freq1 = chandef->center_freq1;
|
freq1 = chandef->center_freq1;
|
||||||
channel = chandef->chan->hw_value;
|
channel = chandef->chan->hw_value;
|
||||||
rf_bw_band = (channel <= 14) ? RF_G_BAND : RF_A_BAND;
|
rf_bw_band = (channel <= 14) ? RF_G_BAND : RF_A_BAND;
|
||||||
dev->mt76.chandef = *chandef;
|
|
||||||
|
|
||||||
switch (chandef->width) {
|
switch (chandef->width) {
|
||||||
case NL80211_CHAN_WIDTH_40:
|
case NL80211_CHAN_WIDTH_40:
|
||||||
@ -1001,7 +1004,7 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
|||||||
/* enable vco */
|
/* enable vco */
|
||||||
mt76x0_rf_set(dev, MT_RF(0, 4), BIT(7));
|
mt76x0_rf_set(dev, MT_RF(0, 4), BIT(7));
|
||||||
if (scan)
|
if (scan)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
mt76x02_init_agc_gain(dev);
|
mt76x02_init_agc_gain(dev);
|
||||||
mt76x0_phy_calibrate(dev, false);
|
mt76x0_phy_calibrate(dev, false);
|
||||||
@ -1009,8 +1012,6 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
|||||||
|
|
||||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
|
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
|
||||||
MT_CALIBRATE_INTERVAL);
|
MT_CALIBRATE_INTERVAL);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mt76x0_phy_temp_sensor(struct mt76x02_dev *dev)
|
static void mt76x0_phy_temp_sensor(struct mt76x02_dev *dev)
|
||||||
@ -1169,7 +1170,8 @@ static void mt76x0_phy_rf_init(struct mt76x02_dev *dev)
|
|||||||
|
|
||||||
if (item->bw_band == RF_BW_20)
|
if (item->bw_band == RF_BW_20)
|
||||||
mt76x0_rf_wr(dev, item->rf_bank_reg, item->value);
|
mt76x0_rf_wr(dev, item->rf_bank_reg, item->value);
|
||||||
else if (((RF_G_BAND | RF_BW_20) & item->bw_band) == (RF_G_BAND | RF_BW_20))
|
else if (((RF_G_BAND | RF_BW_20) & item->bw_band) ==
|
||||||
|
(RF_G_BAND | RF_BW_20))
|
||||||
mt76x0_rf_wr(dev, item->rf_bank_reg, item->value);
|
mt76x0_rf_wr(dev, item->rf_bank_reg, item->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1181,10 +1183,9 @@ static void mt76x0_phy_rf_init(struct mt76x02_dev *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Frequency calibration
|
||||||
Frequency calibration
|
* E1: B0.R22<6:0>: xo_cxo<6:0>
|
||||||
E1: B0.R22<6:0>: xo_cxo<6:0>
|
* E2: B0.R21<0>: xo_cxo<0>, B0.R22<7:0>: xo_cxo<8:1>
|
||||||
E2: B0.R21<0>: xo_cxo<0>, B0.R22<7:0>: xo_cxo<8:1>
|
|
||||||
*/
|
*/
|
||||||
mt76x0_rf_wr(dev, MT_RF(0, 22),
|
mt76x0_rf_wr(dev, MT_RF(0, 22),
|
||||||
min_t(u8, dev->cal.rx.freq_offset, 0xbf));
|
min_t(u8, dev->cal.rx.freq_offset, 0xbf));
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
#define RF_BW_80 8
|
#define RF_BW_80 8
|
||||||
|
|
||||||
#define MT_RF(bank, reg) ((bank) << 16 | (reg))
|
#define MT_RF(bank, reg) ((bank) << 16 | (reg))
|
||||||
#define MT_RF_BANK(offset) (offset >> 16)
|
#define MT_RF_BANK(offset) ((offset) >> 16)
|
||||||
#define MT_RF_REG(offset) (offset & 0xff)
|
#define MT_RF_REG(offset) ((offset) & 0xff)
|
||||||
|
|
||||||
#define MT_RF_VCO_BP_CLOSE_LOOP BIT(3)
|
#define MT_RF_VCO_BP_CLOSE_LOOP BIT(3)
|
||||||
#define MT_RF_VCO_BP_CLOSE_LOOP_MASK GENMASK(3, 0)
|
#define MT_RF_VCO_BP_CLOSE_LOOP_MASK GENMASK(3, 0)
|
||||||
|
@ -32,10 +32,13 @@ static struct usb_device_id mt76x0_device_table[] = {
|
|||||||
{ USB_DEVICE(0x20f4, 0x806b) }, /* TRENDnet TEW-806UBH */
|
{ USB_DEVICE(0x20f4, 0x806b) }, /* TRENDnet TEW-806UBH */
|
||||||
{ USB_DEVICE(0x7392, 0xc711) }, /* Devolo Wifi ac Stick */
|
{ USB_DEVICE(0x7392, 0xc711) }, /* Devolo Wifi ac Stick */
|
||||||
{ USB_DEVICE(0x0df6, 0x0079) }, /* Sitecom Europe B.V. ac Stick */
|
{ USB_DEVICE(0x0df6, 0x0079) }, /* Sitecom Europe B.V. ac Stick */
|
||||||
{ USB_DEVICE(0x2357, 0x0105),
|
{ USB_DEVICE(0x2357, 0x0123) }, /* TP-LINK T2UHP */
|
||||||
.driver_info = 1, }, /* TP-LINK Archer T1U */
|
/* TP-LINK Archer T1U */
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7630, 0xff, 0x2, 0xff)}, /* MT7630U */
|
{ USB_DEVICE(0x2357, 0x0105), .driver_info = 1, },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7650, 0xff, 0x2, 0xff)}, /* MT7650U */
|
/* MT7630U */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7630, 0xff, 0x2, 0xff)},
|
||||||
|
/* MT7650U */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x0E8D, 0x7650, 0xff, 0x2, 0xff)},
|
||||||
{ 0, }
|
{ 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,13 +128,14 @@ static const struct ieee80211_ops mt76x0u_ops = {
|
|||||||
.sta_state = mt76_sta_state,
|
.sta_state = mt76_sta_state,
|
||||||
.set_key = mt76x02_set_key,
|
.set_key = mt76x02_set_key,
|
||||||
.conf_tx = mt76x02_conf_tx,
|
.conf_tx = mt76x02_conf_tx,
|
||||||
.sw_scan_start = mt76x02_sw_scan,
|
.sw_scan_start = mt76_sw_scan,
|
||||||
.sw_scan_complete = mt76x02_sw_scan_complete,
|
.sw_scan_complete = mt76x02_sw_scan_complete,
|
||||||
.ampdu_action = mt76x02_ampdu_action,
|
.ampdu_action = mt76x02_ampdu_action,
|
||||||
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
|
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
|
||||||
.set_rts_threshold = mt76x02_set_rts_threshold,
|
.set_rts_threshold = mt76x02_set_rts_threshold,
|
||||||
.wake_tx_queue = mt76_wake_tx_queue,
|
.wake_tx_queue = mt76_wake_tx_queue,
|
||||||
.get_txpower = mt76_get_txpower,
|
.get_txpower = mt76_get_txpower,
|
||||||
|
.get_survey = mt76_get_survey,
|
||||||
.set_tim = mt76_set_tim,
|
.set_tim = mt76_set_tim,
|
||||||
.release_buffered_frames = mt76_release_buffered_frames,
|
.release_buffered_frames = mt76_release_buffered_frames,
|
||||||
};
|
};
|
||||||
@ -161,6 +165,13 @@ static int mt76x0u_init_hardware(struct mt76x02_dev *dev, bool reset)
|
|||||||
FIELD_PREP(MT_TXOP_TRUN_EN, 0x3f) |
|
FIELD_PREP(MT_TXOP_TRUN_EN, 0x3f) |
|
||||||
FIELD_PREP(MT_TXOP_EXT_CCA_DLY, 0x58));
|
FIELD_PREP(MT_TXOP_EXT_CCA_DLY, 0x58));
|
||||||
|
|
||||||
|
mt76_wr(dev, MT_CH_TIME_CFG,
|
||||||
|
MT_CH_TIME_CFG_TIMER_EN |
|
||||||
|
MT_CH_TIME_CFG_TX_AS_BUSY |
|
||||||
|
MT_CH_TIME_CFG_RX_AS_BUSY |
|
||||||
|
MT_CH_TIME_CFG_NAV_AS_BUSY |
|
||||||
|
MT_CH_TIME_CFG_EIFS_AS_BUSY);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,6 +211,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
|
|||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
static const struct mt76_driver_ops drv_ops = {
|
static const struct mt76_driver_ops drv_ops = {
|
||||||
|
.update_survey = mt76x02_update_channel,
|
||||||
.tx_prepare_skb = mt76x02u_tx_prepare_skb,
|
.tx_prepare_skb = mt76x02u_tx_prepare_skb,
|
||||||
.tx_complete_skb = mt76x02u_tx_complete_skb,
|
.tx_complete_skb = mt76x02u_tx_complete_skb,
|
||||||
.tx_status_data = mt76x02_tx_status_data,
|
.tx_status_data = mt76x02_tx_status_data,
|
||||||
@ -236,7 +248,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* Disable the HW, otherwise MCU fail to initalize on hot reboot */
|
/* Disable the HW, otherwise MCU fail to initialize on hot reboot */
|
||||||
mt76x0_chip_onoff(dev, false, false);
|
mt76x0_chip_onoff(dev, false, false);
|
||||||
|
|
||||||
if (!mt76x02_wait_for_mac(mdev)) {
|
if (!mt76x02_wait_for_mac(mdev)) {
|
||||||
@ -274,9 +286,9 @@ err:
|
|||||||
static void mt76x0_disconnect(struct usb_interface *usb_intf)
|
static void mt76x0_disconnect(struct usb_interface *usb_intf)
|
||||||
{
|
{
|
||||||
struct mt76x02_dev *dev = usb_get_intfdata(usb_intf);
|
struct mt76x02_dev *dev = usb_get_intfdata(usb_intf);
|
||||||
bool initalized = test_bit(MT76_STATE_INITIALIZED, &dev->mt76.state);
|
bool initialized = test_bit(MT76_STATE_INITIALIZED, &dev->mt76.state);
|
||||||
|
|
||||||
if (!initalized)
|
if (!initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ieee80211_unregister_hw(dev->mt76.hw);
|
ieee80211_unregister_hw(dev->mt76.hw);
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x02_H
|
#ifndef __MT76x02_H
|
||||||
@ -71,10 +60,15 @@ struct mt76x02_calibration {
|
|||||||
struct mt76x02_beacon_ops {
|
struct mt76x02_beacon_ops {
|
||||||
unsigned int nslots;
|
unsigned int nslots;
|
||||||
unsigned int slot_size;
|
unsigned int slot_size;
|
||||||
void (*pre_tbtt_enable) (struct mt76x02_dev *, bool);
|
void (*pre_tbtt_enable)(struct mt76x02_dev *dev, bool en);
|
||||||
void (*beacon_enable) (struct mt76x02_dev *, bool);
|
void (*beacon_enable)(struct mt76x02_dev *dev, bool en);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define mt76x02_beacon_enable(dev, enable) \
|
||||||
|
(dev)->beacon_ops->beacon_enable(dev, enable)
|
||||||
|
#define mt76x02_pre_tbtt_enable(dev, enable) \
|
||||||
|
(dev)->beacon_ops->pre_tbtt_enable(dev, enable)
|
||||||
|
|
||||||
struct mt76x02_dev {
|
struct mt76x02_dev {
|
||||||
struct mt76_dev mt76; /* must be first */
|
struct mt76_dev mt76; /* must be first */
|
||||||
|
|
||||||
@ -183,8 +177,6 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
|
|||||||
enum mt76_txq_id qid, struct mt76_wcid *wcid,
|
enum mt76_txq_id qid, struct mt76_wcid *wcid,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta,
|
||||||
struct mt76_tx_info *tx_info);
|
struct mt76_tx_info *tx_info);
|
||||||
void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
||||||
const u8 *mac);
|
|
||||||
void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
|
void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_vif *vif);
|
struct ieee80211_vif *vif);
|
||||||
void mt76x02_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);
|
void mt76x02_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);
|
||||||
@ -197,6 +189,7 @@ struct beacon_bc_data {
|
|||||||
struct sk_buff_head q;
|
struct sk_buff_head q;
|
||||||
struct sk_buff *tail[8];
|
struct sk_buff *tail[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
void mt76x02_init_beacon_config(struct mt76x02_dev *dev);
|
void mt76x02_init_beacon_config(struct mt76x02_dev *dev);
|
||||||
void mt76x02e_init_beacon_config(struct mt76x02_dev *dev);
|
void mt76x02e_init_beacon_config(struct mt76x02_dev *dev);
|
||||||
void mt76x02_resync_beacon_timer(struct mt76x02_dev *dev);
|
void mt76x02_resync_beacon_timer(struct mt76x02_dev *dev);
|
||||||
|
@ -1,19 +1,8 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
||||||
*
|
|
||||||
* 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 "mt76x02.h"
|
#include "mt76x02.h"
|
||||||
@ -115,53 +104,41 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
|
EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
|
||||||
|
|
||||||
static void
|
|
||||||
__mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev, u8 vif_idx,
|
|
||||||
bool val, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
u8 old_mask = dev->mt76.beacon_mask;
|
|
||||||
bool en;
|
|
||||||
u32 reg;
|
|
||||||
|
|
||||||
if (val) {
|
|
||||||
dev->mt76.beacon_mask |= BIT(vif_idx);
|
|
||||||
if (skb)
|
|
||||||
mt76x02_mac_set_beacon(dev, vif_idx, skb);
|
|
||||||
} else {
|
|
||||||
dev->mt76.beacon_mask &= ~BIT(vif_idx);
|
|
||||||
mt76x02_mac_set_beacon(dev, vif_idx, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!!old_mask == !!dev->mt76.beacon_mask)
|
|
||||||
return;
|
|
||||||
|
|
||||||
en = dev->mt76.beacon_mask;
|
|
||||||
|
|
||||||
reg = MT_BEACON_TIME_CFG_BEACON_TX |
|
|
||||||
MT_BEACON_TIME_CFG_TBTT_EN |
|
|
||||||
MT_BEACON_TIME_CFG_TIMER_EN;
|
|
||||||
mt76_rmw(dev, MT_BEACON_TIME_CFG, reg, reg * en);
|
|
||||||
|
|
||||||
dev->beacon_ops->beacon_enable(dev, en);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
|
void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
|
||||||
struct ieee80211_vif *vif, bool val)
|
struct ieee80211_vif *vif, bool enable)
|
||||||
{
|
{
|
||||||
u8 vif_idx = ((struct mt76x02_vif *)vif->drv_priv)->idx;
|
struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
|
||||||
struct sk_buff *skb = NULL;
|
u8 old_mask = dev->mt76.beacon_mask;
|
||||||
|
|
||||||
dev->beacon_ops->pre_tbtt_enable(dev, false);
|
mt76x02_pre_tbtt_enable(dev, false);
|
||||||
|
|
||||||
if (mt76_is_usb(dev))
|
|
||||||
skb = ieee80211_beacon_get(mt76_hw(dev), vif);
|
|
||||||
|
|
||||||
if (!dev->mt76.beacon_mask)
|
if (!dev->mt76.beacon_mask)
|
||||||
dev->tbtt_count = 0;
|
dev->tbtt_count = 0;
|
||||||
|
|
||||||
__mt76x02_mac_set_beacon_enable(dev, vif_idx, val, skb);
|
if (enable) {
|
||||||
|
dev->mt76.beacon_mask |= BIT(mvif->idx);
|
||||||
|
} else {
|
||||||
|
dev->mt76.beacon_mask &= ~BIT(mvif->idx);
|
||||||
|
mt76x02_mac_set_beacon(dev, mvif->idx, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
dev->beacon_ops->pre_tbtt_enable(dev, true);
|
if (!!old_mask == !!dev->mt76.beacon_mask)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (dev->mt76.beacon_mask)
|
||||||
|
mt76_set(dev, MT_BEACON_TIME_CFG,
|
||||||
|
MT_BEACON_TIME_CFG_BEACON_TX |
|
||||||
|
MT_BEACON_TIME_CFG_TBTT_EN |
|
||||||
|
MT_BEACON_TIME_CFG_TIMER_EN);
|
||||||
|
else
|
||||||
|
mt76_clear(dev, MT_BEACON_TIME_CFG,
|
||||||
|
MT_BEACON_TIME_CFG_BEACON_TX |
|
||||||
|
MT_BEACON_TIME_CFG_TBTT_EN |
|
||||||
|
MT_BEACON_TIME_CFG_TIMER_EN);
|
||||||
|
mt76x02_beacon_enable(dev, !!dev->mt76.beacon_mask);
|
||||||
|
|
||||||
|
out:
|
||||||
|
mt76x02_pre_tbtt_enable(dev, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -237,7 +214,8 @@ mt76x02_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mt76x02_enqueue_buffered_bc(struct mt76x02_dev *dev, struct beacon_bc_data *data,
|
mt76x02_enqueue_buffered_bc(struct mt76x02_dev *dev,
|
||||||
|
struct beacon_bc_data *data,
|
||||||
int max_nframes)
|
int max_nframes)
|
||||||
{
|
{
|
||||||
int i, nframes;
|
int i, nframes;
|
||||||
@ -281,4 +259,3 @@ void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76x02_init_beacon_config);
|
EXPORT_SYMBOL_GPL(mt76x02_init_beacon_config);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76x02.h"
|
#include "mt76x02.h"
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x02_DFS_H
|
#ifndef __MT76x02_DFS_H
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x02_DMA_H
|
#ifndef __MT76x02_DMA_H
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x02_EEPROM_H
|
#ifndef __MT76x02_EEPROM_H
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
||||||
*
|
|
||||||
* 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 "mt76x02.h"
|
#include "mt76x02.h"
|
||||||
@ -92,7 +81,6 @@ void mt76x02_mac_wcid_sync_pn(struct mt76x02_dev *dev, u8 idx,
|
|||||||
atomic64_set(&key->tx_pn, pn);
|
atomic64_set(&key->tx_pn, pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
|
int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
|
||||||
struct ieee80211_key_conf *key)
|
struct ieee80211_key_conf *key)
|
||||||
{
|
{
|
||||||
@ -353,6 +341,7 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
|
|||||||
|
|
||||||
if (wcid && wcid->sw_iv && key) {
|
if (wcid && wcid->sw_iv && key) {
|
||||||
u64 pn = atomic64_inc_return(&key->tx_pn);
|
u64 pn = atomic64_inc_return(&key->tx_pn);
|
||||||
|
|
||||||
ccmp_pn[0] = pn;
|
ccmp_pn[0] = pn;
|
||||||
ccmp_pn[1] = pn >> 8;
|
ccmp_pn[1] = pn >> 8;
|
||||||
ccmp_pn[2] = 0;
|
ccmp_pn[2] = 0;
|
||||||
@ -568,9 +557,9 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
|
|||||||
u32 stat_val, stat_cache;
|
u32 stat_val, stat_cache;
|
||||||
|
|
||||||
stat_val = stat->rate;
|
stat_val = stat->rate;
|
||||||
stat_val |= ((u32) stat->retry) << 16;
|
stat_val |= ((u32)stat->retry) << 16;
|
||||||
stat_cache = msta->status.rate;
|
stat_cache = msta->status.rate;
|
||||||
stat_cache |= ((u32) msta->status.retry) << 16;
|
stat_cache |= ((u32)msta->status.retry) << 16;
|
||||||
|
|
||||||
if (*update == 0 && stat_val == stat_cache &&
|
if (*update == 0 && stat_val == stat_cache &&
|
||||||
stat->wcid == msta->status.wcid && msta->n_frames < 32) {
|
stat->wcid == msta->status.wcid && msta->n_frames < 32) {
|
||||||
@ -718,7 +707,7 @@ mt76x02_mac_get_rssi(struct mt76x02_dev *dev, s8 rssi, int chain)
|
|||||||
int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
|
int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
|
||||||
void *rxi)
|
void *rxi)
|
||||||
{
|
{
|
||||||
struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
|
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
|
||||||
struct mt76x02_rxwi *rxwi = rxi;
|
struct mt76x02_rxwi *rxwi = rxi;
|
||||||
struct mt76x02_sta *sta;
|
struct mt76x02_sta *sta;
|
||||||
u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
|
u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76X02_MAC_H
|
#ifndef __MT76X02_MAC_H
|
||||||
@ -207,7 +196,7 @@ void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr);
|
|||||||
int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
|
int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
|
||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
|
void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
|
||||||
struct ieee80211_vif *vif, bool val);
|
struct ieee80211_vif *vif, bool enable);
|
||||||
|
|
||||||
void mt76x02_edcca_init(struct mt76x02_dev *dev);
|
void mt76x02_edcca_init(struct mt76x02_dev *dev);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@ -65,7 +54,7 @@ int mt76x02_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rxfce = (u32 *) skb->cb;
|
rxfce = (u32 *)skb->cb;
|
||||||
|
|
||||||
if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, *rxfce))
|
if (seq == FIELD_GET(MT_RX_FCE_INFO_CMD_SEQ, *rxfce))
|
||||||
check_seq = true;
|
check_seq = true;
|
||||||
@ -111,7 +100,8 @@ int mt76x02_mcu_set_radio_state(struct mt76x02_dev *dev, bool on)
|
|||||||
.level = cpu_to_le32(0),
|
.level = cpu_to_le32(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
return mt76_mcu_send_msg(dev, CMD_POWER_SAVING_OP, &msg, sizeof(msg), false);
|
return mt76_mcu_send_msg(dev, CMD_POWER_SAVING_OP, &msg, sizeof(msg),
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76x02_mcu_set_radio_state);
|
EXPORT_SYMBOL_GPL(mt76x02_mcu_set_radio_state);
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x02_MCU_H
|
#ifndef __MT76x02_MCU_H
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@ -97,7 +86,8 @@ void mt76x02e_init_beacon_config(struct mt76x02_dev *dev)
|
|||||||
dev->beacon_ops = &beacon_ops;
|
dev->beacon_ops = &beacon_ops;
|
||||||
|
|
||||||
/* Fire a pre-TBTT interrupt 8 ms before TBTT */
|
/* Fire a pre-TBTT interrupt 8 ms before TBTT */
|
||||||
mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT, 8 << 4);
|
mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT,
|
||||||
|
8 << 4);
|
||||||
mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER,
|
mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER,
|
||||||
MT_DFS_GP_INTERVAL);
|
MT_DFS_GP_INTERVAL);
|
||||||
mt76_wr(dev, MT_INT_TIMER_EN, 0);
|
mt76_wr(dev, MT_INT_TIMER_EN, 0);
|
||||||
@ -201,7 +191,7 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
tasklet_init(&dev->mt76.tx_tasklet, mt76x02_tx_tasklet,
|
tasklet_init(&dev->mt76.tx_tasklet, mt76x02_tx_tasklet,
|
||||||
(unsigned long) dev);
|
(unsigned long)dev);
|
||||||
tasklet_init(&dev->mt76.pre_tbtt_tasklet, mt76x02_pre_tbtt_tasklet,
|
tasklet_init(&dev->mt76.pre_tbtt_tasklet, mt76x02_pre_tbtt_tasklet,
|
||||||
(unsigned long)dev);
|
(unsigned long)dev);
|
||||||
|
|
||||||
@ -397,7 +387,7 @@ static void mt76x02_key_sync(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
if (!sta)
|
if (!sta)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wcid = (struct mt76_wcid *) sta->drv_priv;
|
wcid = (struct mt76_wcid *)sta->drv_priv;
|
||||||
|
|
||||||
if (wcid->hw_key_idx != key->keyidx || wcid->sw_iv)
|
if (wcid->hw_key_idx != key->keyidx || wcid->sw_iv)
|
||||||
return;
|
return;
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@ -183,7 +172,8 @@ bool mt76x02_phy_adjust_vga_gain(struct mt76x02_dev *dev)
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
u32 false_cca;
|
u32 false_cca;
|
||||||
|
|
||||||
false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1));
|
false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS,
|
||||||
|
mt76_rr(dev, MT_RX_STAT_1));
|
||||||
dev->cal.false_cca = false_cca;
|
dev->cal.false_cca = false_cca;
|
||||||
if (false_cca > 800 && dev->cal.agc_gain_adjust < limit) {
|
if (false_cca > 800 && dev->cal.agc_gain_adjust < limit) {
|
||||||
dev->cal.agc_gain_adjust += 2;
|
dev->cal.agc_gain_adjust += 2;
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x02_PHY_H
|
#ifndef __MT76x02_PHY_H
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76X02_REGS_H
|
#ifndef __MT76X02_REGS_H
|
||||||
@ -120,7 +109,7 @@
|
|||||||
#define MT_INT_RX_DONE(_n) BIT(_n)
|
#define MT_INT_RX_DONE(_n) BIT(_n)
|
||||||
#define MT_INT_RX_DONE_ALL GENMASK(1, 0)
|
#define MT_INT_RX_DONE_ALL GENMASK(1, 0)
|
||||||
#define MT_INT_TX_DONE_ALL GENMASK(13, 4)
|
#define MT_INT_TX_DONE_ALL GENMASK(13, 4)
|
||||||
#define MT_INT_TX_DONE(_n) BIT(_n + 4)
|
#define MT_INT_TX_DONE(_n) BIT((_n) + 4)
|
||||||
#define MT_INT_RX_COHERENT BIT(16)
|
#define MT_INT_RX_COHERENT BIT(16)
|
||||||
#define MT_INT_TX_COHERENT BIT(17)
|
#define MT_INT_TX_COHERENT BIT(17)
|
||||||
#define MT_INT_ANY_COHERENT BIT(18)
|
#define MT_INT_ANY_COHERENT BIT(18)
|
||||||
@ -163,7 +152,7 @@
|
|||||||
|
|
||||||
#define MT_WMM_TXOP_BASE 0x0220
|
#define MT_WMM_TXOP_BASE 0x0220
|
||||||
#define MT_WMM_TXOP(_n) (MT_WMM_TXOP_BASE + (((_n) / 2) << 2))
|
#define MT_WMM_TXOP(_n) (MT_WMM_TXOP_BASE + (((_n) / 2) << 2))
|
||||||
#define MT_WMM_TXOP_SHIFT(_n) ((_n & 1) * 16)
|
#define MT_WMM_TXOP_SHIFT(_n) (((_n) & 1) * 16)
|
||||||
#define MT_WMM_TXOP_MASK GENMASK(15, 0)
|
#define MT_WMM_TXOP_MASK GENMASK(15, 0)
|
||||||
|
|
||||||
#define MT_WMM_CTRL 0x0230 /* MT76x0 */
|
#define MT_WMM_CTRL 0x0230 /* MT76x0 */
|
||||||
@ -607,7 +596,7 @@
|
|||||||
|
|
||||||
#define MT_TX_AGG_CNT(_id) ((_id) < 8 ? \
|
#define MT_TX_AGG_CNT(_id) ((_id) < 8 ? \
|
||||||
MT_TX_AGG_CNT_BASE0 + ((_id) << 2) : \
|
MT_TX_AGG_CNT_BASE0 + ((_id) << 2) : \
|
||||||
MT_TX_AGG_CNT_BASE1 + ((_id - 8) << 2))
|
MT_TX_AGG_CNT_BASE1 + (((_id) - 8) << 2))
|
||||||
|
|
||||||
#define MT_TX_STAT_FIFO_EXT 0x1798
|
#define MT_TX_STAT_FIFO_EXT 0x1798
|
||||||
#define MT_TX_STAT_FIFO_EXT_RETRY GENMASK(7, 0)
|
#define MT_TX_STAT_FIFO_EXT_RETRY GENMASK(7, 0)
|
||||||
@ -680,17 +669,17 @@
|
|||||||
|
|
||||||
#define MT_SKEY_BASE_0 0xac00
|
#define MT_SKEY_BASE_0 0xac00
|
||||||
#define MT_SKEY_BASE_1 0xb400
|
#define MT_SKEY_BASE_1 0xb400
|
||||||
#define MT_SKEY_0(_bss, _idx) (MT_SKEY_BASE_0 + (4 * (_bss) + _idx) * 32)
|
#define MT_SKEY_0(_bss, _idx) (MT_SKEY_BASE_0 + (4 * (_bss) + (_idx)) * 32)
|
||||||
#define MT_SKEY_1(_bss, _idx) (MT_SKEY_BASE_1 + (4 * ((_bss) & 7) + _idx) * 32)
|
#define MT_SKEY_1(_bss, _idx) (MT_SKEY_BASE_1 + (4 * ((_bss) & 7) + (_idx)) * 32)
|
||||||
#define MT_SKEY(_bss, _idx) ((_bss & 8) ? MT_SKEY_1(_bss, _idx) : MT_SKEY_0(_bss, _idx))
|
#define MT_SKEY(_bss, _idx) (((_bss) & 8) ? MT_SKEY_1(_bss, _idx) : MT_SKEY_0(_bss, _idx))
|
||||||
|
|
||||||
#define MT_SKEY_MODE_BASE_0 0xb000
|
#define MT_SKEY_MODE_BASE_0 0xb000
|
||||||
#define MT_SKEY_MODE_BASE_1 0xb3f0
|
#define MT_SKEY_MODE_BASE_1 0xb3f0
|
||||||
#define MT_SKEY_MODE_0(_bss) (MT_SKEY_MODE_BASE_0 + ((_bss / 2) << 2))
|
#define MT_SKEY_MODE_0(_bss) (MT_SKEY_MODE_BASE_0 + (((_bss) / 2) << 2))
|
||||||
#define MT_SKEY_MODE_1(_bss) (MT_SKEY_MODE_BASE_1 + ((((_bss) & 7) / 2) << 2))
|
#define MT_SKEY_MODE_1(_bss) (MT_SKEY_MODE_BASE_1 + ((((_bss) & 7) / 2) << 2))
|
||||||
#define MT_SKEY_MODE(_bss) ((_bss & 8) ? MT_SKEY_MODE_1(_bss) : MT_SKEY_MODE_0(_bss))
|
#define MT_SKEY_MODE(_bss) (((_bss) & 8) ? MT_SKEY_MODE_1(_bss) : MT_SKEY_MODE_0(_bss))
|
||||||
#define MT_SKEY_MODE_MASK GENMASK(3, 0)
|
#define MT_SKEY_MODE_MASK GENMASK(3, 0)
|
||||||
#define MT_SKEY_MODE_SHIFT(_bss, _idx) (4 * ((_idx) + 4 * (_bss & 1)))
|
#define MT_SKEY_MODE_SHIFT(_bss, _idx) (4 * ((_idx) + 4 * ((_bss) & 1)))
|
||||||
|
|
||||||
#define MT_BEACON_BASE 0xc000
|
#define MT_BEACON_BASE 0xc000
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(__MT76x02_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
#if !defined(__MT76x02_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||||
@ -25,7 +14,8 @@
|
|||||||
|
|
||||||
#define MAXNAME 32
|
#define MAXNAME 32
|
||||||
#define DEV_ENTRY __array(char, wiphy_name, 32)
|
#define DEV_ENTRY __array(char, wiphy_name, 32)
|
||||||
#define DEV_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(mt76_hw(dev)->wiphy), MAXNAME)
|
#define DEV_ASSIGN strlcpy(__entry->wiphy_name, \
|
||||||
|
wiphy_name(mt76_hw(dev)->wiphy), MAXNAME)
|
||||||
#define DEV_PR_FMT "%s"
|
#define DEV_PR_FMT "%s"
|
||||||
#define DEV_PR_ARG __entry->wiphy_name
|
#define DEV_PR_ARG __entry->wiphy_name
|
||||||
|
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x02_USB_H
|
#ifndef __MT76x02_USB_H
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76x02_usb.h"
|
#include "mt76x02_usb.h"
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/module.h>
|
#include <linux/module.h>
|
||||||
@ -21,14 +10,14 @@
|
|||||||
#define CCK_RATE(_idx, _rate) { \
|
#define CCK_RATE(_idx, _rate) { \
|
||||||
.bitrate = _rate, \
|
.bitrate = _rate, \
|
||||||
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \
|
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \
|
||||||
.hw_value = (MT_PHY_TYPE_CCK << 8) | _idx, \
|
.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \
|
||||||
.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx), \
|
.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + (_idx)), \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OFDM_RATE(_idx, _rate) { \
|
#define OFDM_RATE(_idx, _rate) { \
|
||||||
.bitrate = _rate, \
|
.bitrate = _rate, \
|
||||||
.hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx, \
|
.hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
|
||||||
.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx, \
|
.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ieee80211_rate mt76x02_rates[] = {
|
struct ieee80211_rate mt76x02_rates[] = {
|
||||||
@ -61,6 +50,20 @@ static const struct ieee80211_iface_limit mt76x02_if_limits[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct ieee80211_iface_limit mt76x02u_if_limits[] = {
|
||||||
|
{
|
||||||
|
.max = 1,
|
||||||
|
.types = BIT(NL80211_IFTYPE_ADHOC)
|
||||||
|
}, {
|
||||||
|
.max = 2,
|
||||||
|
.types = BIT(NL80211_IFTYPE_STATION) |
|
||||||
|
#ifdef CONFIG_MAC80211_MESH
|
||||||
|
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||||
|
#endif
|
||||||
|
BIT(NL80211_IFTYPE_AP)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static const struct ieee80211_iface_combination mt76x02_if_comb[] = {
|
static const struct ieee80211_iface_combination mt76x02_if_comb[] = {
|
||||||
{
|
{
|
||||||
.limits = mt76x02_if_limits,
|
.limits = mt76x02_if_limits,
|
||||||
@ -75,6 +78,16 @@ static const struct ieee80211_iface_combination mt76x02_if_comb[] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct ieee80211_iface_combination mt76x02u_if_comb[] = {
|
||||||
|
{
|
||||||
|
.limits = mt76x02u_if_limits,
|
||||||
|
.n_limits = ARRAY_SIZE(mt76x02u_if_limits),
|
||||||
|
.max_interfaces = 2,
|
||||||
|
.num_different_channels = 1,
|
||||||
|
.beacon_int_infra_match = true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on,
|
mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on,
|
||||||
u8 delay_off)
|
u8 delay_off)
|
||||||
@ -151,6 +164,8 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
|
|||||||
if (mt76_is_usb(dev)) {
|
if (mt76_is_usb(dev)) {
|
||||||
hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) +
|
hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) +
|
||||||
MT_DMA_HDR_LEN;
|
MT_DMA_HDR_LEN;
|
||||||
|
wiphy->iface_combinations = mt76x02u_if_comb;
|
||||||
|
wiphy->n_iface_combinations = ARRAY_SIZE(mt76x02u_if_comb);
|
||||||
} else {
|
} else {
|
||||||
INIT_DELAYED_WORK(&dev->wdt_work, mt76x02_wdt_work);
|
INIT_DELAYED_WORK(&dev->wdt_work, mt76x02_wdt_work);
|
||||||
|
|
||||||
@ -281,7 +296,7 @@ mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif,
|
|||||||
mvif->idx = idx;
|
mvif->idx = idx;
|
||||||
mvif->group_wcid.idx = MT_VIF_WCID(idx);
|
mvif->group_wcid.idx = MT_VIF_WCID(idx);
|
||||||
mvif->group_wcid.hw_key_idx = -1;
|
mvif->group_wcid.hw_key_idx = -1;
|
||||||
mtxq = (struct mt76_txq *) vif->txq->drv_priv;
|
mtxq = (struct mt76_txq *)vif->txq->drv_priv;
|
||||||
mtxq->wcid = &mvif->group_wcid;
|
mtxq->wcid = &mvif->group_wcid;
|
||||||
|
|
||||||
mt76_txq_init(&dev->mt76, vif->txq);
|
mt76_txq_init(&dev->mt76, vif->txq);
|
||||||
@ -345,10 +360,10 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
enum ieee80211_ampdu_mlme_action action = params->action;
|
enum ieee80211_ampdu_mlme_action action = params->action;
|
||||||
struct ieee80211_sta *sta = params->sta;
|
struct ieee80211_sta *sta = params->sta;
|
||||||
struct mt76x02_dev *dev = hw->priv;
|
struct mt76x02_dev *dev = hw->priv;
|
||||||
struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv;
|
struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
|
||||||
struct ieee80211_txq *txq = sta->txq[params->tid];
|
struct ieee80211_txq *txq = sta->txq[params->tid];
|
||||||
u16 tid = params->tid;
|
u16 tid = params->tid;
|
||||||
u16 *ssn = ¶ms->ssn;
|
u16 ssn = params->ssn;
|
||||||
struct mt76_txq *mtxq;
|
struct mt76_txq *mtxq;
|
||||||
|
|
||||||
if (!txq)
|
if (!txq)
|
||||||
@ -359,7 +374,7 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case IEEE80211_AMPDU_RX_START:
|
case IEEE80211_AMPDU_RX_START:
|
||||||
mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid,
|
mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid,
|
||||||
*ssn, params->buf_size);
|
ssn, params->buf_size);
|
||||||
mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
|
mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_RX_STOP:
|
case IEEE80211_AMPDU_RX_STOP:
|
||||||
@ -375,10 +390,9 @@ int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||||||
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
case IEEE80211_AMPDU_TX_STOP_FLUSH:
|
||||||
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
|
||||||
mtxq->aggr = false;
|
mtxq->aggr = false;
|
||||||
ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
|
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_TX_START:
|
case IEEE80211_AMPDU_TX_START:
|
||||||
mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(*ssn);
|
mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
|
||||||
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_AMPDU_TX_STOP_CONT:
|
case IEEE80211_AMPDU_TX_STOP_CONT:
|
||||||
@ -434,7 +448,7 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||||||
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
|
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL;
|
msta = sta ? (struct mt76x02_sta *)sta->drv_priv : NULL;
|
||||||
wcid = msta ? &msta->wcid : &mvif->group_wcid;
|
wcid = msta ? &msta->wcid : &mvif->group_wcid;
|
||||||
|
|
||||||
if (cmd == SET_KEY) {
|
if (cmd == SET_KEY) {
|
||||||
@ -562,7 +576,7 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw,
|
|||||||
struct ieee80211_sta *sta)
|
struct ieee80211_sta *sta)
|
||||||
{
|
{
|
||||||
struct mt76x02_dev *dev = hw->priv;
|
struct mt76x02_dev *dev = hw->priv;
|
||||||
struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv;
|
struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv;
|
||||||
struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates);
|
struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates);
|
||||||
struct ieee80211_tx_rate rate = {};
|
struct ieee80211_tx_rate rate = {};
|
||||||
|
|
||||||
@ -588,15 +602,6 @@ void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad);
|
EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad);
|
||||||
|
|
||||||
void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
||||||
const u8 *mac)
|
|
||||||
{
|
|
||||||
struct mt76x02_dev *dev = hw->priv;
|
|
||||||
|
|
||||||
set_bit(MT76_SCANNING, &dev->mt76.state);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(mt76x02_sw_scan);
|
|
||||||
|
|
||||||
void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
|
void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_vif *vif)
|
struct ieee80211_vif *vif)
|
||||||
{
|
{
|
||||||
|
@ -8,8 +8,12 @@ config MT76x2E
|
|||||||
select MT76x2_COMMON
|
select MT76x2_COMMON
|
||||||
depends on MAC80211
|
depends on MAC80211
|
||||||
depends on PCI
|
depends on PCI
|
||||||
---help---
|
help
|
||||||
This adds support for MT7612/MT7602/MT7662-based wireless PCIe devices.
|
This adds support for MT7612/MT7602/MT7662-based wireless PCIe
|
||||||
|
devices, which comply with IEEE 802.11ac standards and support
|
||||||
|
2SS to 866Mbit/s PHY rate.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here.
|
||||||
|
|
||||||
config MT76x2U
|
config MT76x2U
|
||||||
tristate "MediaTek MT76x2U (USB) support"
|
tristate "MediaTek MT76x2U (USB) support"
|
||||||
@ -18,4 +22,8 @@ config MT76x2U
|
|||||||
depends on MAC80211
|
depends on MAC80211
|
||||||
depends on USB
|
depends on USB
|
||||||
help
|
help
|
||||||
This adds support for MT7612U-based wireless USB dongles.
|
This adds support for MT7612U-based wireless USB 3.0 dongles,
|
||||||
|
which comply with IEEE 802.11ac standards and support 2SS to
|
||||||
|
866Mbit/s PHY rate.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here.
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/module.h>
|
#include <linux/module.h>
|
||||||
@ -33,7 +22,7 @@ mt76x2_eeprom_get_macaddr(struct mt76x02_dev *dev)
|
|||||||
static bool
|
static bool
|
||||||
mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
|
mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse)
|
||||||
{
|
{
|
||||||
u16 *efuse_w = (u16 *) efuse;
|
u16 *efuse_w = (u16 *)efuse;
|
||||||
|
|
||||||
if (efuse_w[MT_EE_NIC_CONF_0] != 0)
|
if (efuse_w[MT_EE_NIC_CONF_0] != 0)
|
||||||
return false;
|
return false;
|
||||||
@ -372,7 +361,8 @@ mt76x2_get_power_info_2g(struct mt76x02_dev *dev,
|
|||||||
t->chain[chain].tssi_slope = data[0];
|
t->chain[chain].tssi_slope = data[0];
|
||||||
t->chain[chain].tssi_offset = data[1];
|
t->chain[chain].tssi_offset = data[1];
|
||||||
t->chain[chain].target_power = data[2];
|
t->chain[chain].target_power = data[2];
|
||||||
t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7);
|
t->chain[chain].delta =
|
||||||
|
mt76x02_sign_extend_optional(data[delta_idx], 7);
|
||||||
|
|
||||||
val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_TSSI_OFF_TXPOWER);
|
val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_TSSI_OFF_TXPOWER);
|
||||||
t->target_power = val >> 8;
|
t->target_power = val >> 8;
|
||||||
@ -423,7 +413,8 @@ mt76x2_get_power_info_5g(struct mt76x02_dev *dev,
|
|||||||
t->chain[chain].tssi_slope = data[0];
|
t->chain[chain].tssi_slope = data[0];
|
||||||
t->chain[chain].tssi_offset = data[1];
|
t->chain[chain].tssi_offset = data[1];
|
||||||
t->chain[chain].target_power = data[2];
|
t->chain[chain].target_power = data[2];
|
||||||
t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7);
|
t->chain[chain].delta =
|
||||||
|
mt76x02_sign_extend_optional(data[delta_idx], 7);
|
||||||
|
|
||||||
val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN);
|
val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN);
|
||||||
t->target_power = val & 0xff;
|
t->target_power = val & 0xff;
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x2_EEPROM_H
|
#ifndef __MT76x2_EEPROM_H
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76x2.h"
|
#include "mt76x2.h"
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76x2.h"
|
#include "mt76x2.h"
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x2_MAC_H
|
#ifndef __MT76x2_MAC_H
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x2_MCU_H
|
#ifndef __MT76x2_MCU_H
|
||||||
@ -71,7 +60,8 @@ struct mt76x2_tssi_comp {
|
|||||||
u8 offset1;
|
u8 offset1;
|
||||||
} __packed __aligned(4);
|
} __packed __aligned(4);
|
||||||
|
|
||||||
int mt76x2_mcu_tssi_comp(struct mt76x02_dev *dev, struct mt76x2_tssi_comp *tssi_data);
|
int mt76x2_mcu_tssi_comp(struct mt76x02_dev *dev,
|
||||||
|
struct mt76x2_tssi_comp *tssi_data);
|
||||||
int mt76x2_mcu_init_gain(struct mt76x02_dev *dev, u8 channel, u32 gain,
|
int mt76x2_mcu_init_gain(struct mt76x02_dev *dev, u8 channel, u32 gain,
|
||||||
bool force);
|
bool force);
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x2_H
|
#ifndef __MT76x2_H
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MT76x2U_H
|
#ifndef __MT76x2U_H
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/delay.h>
|
#include <linux/delay.h>
|
||||||
@ -336,4 +325,3 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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 "mt76x2.h"
|
#include "mt76x2.h"
|
||||||
@ -176,7 +165,7 @@ const struct ieee80211_ops mt76x2_ops = {
|
|||||||
.sta_state = mt76_sta_state,
|
.sta_state = mt76_sta_state,
|
||||||
.set_key = mt76x02_set_key,
|
.set_key = mt76x02_set_key,
|
||||||
.conf_tx = mt76x02_conf_tx,
|
.conf_tx = mt76x02_conf_tx,
|
||||||
.sw_scan_start = mt76x02_sw_scan,
|
.sw_scan_start = mt76_sw_scan,
|
||||||
.sw_scan_complete = mt76x02_sw_scan_complete,
|
.sw_scan_complete = mt76x02_sw_scan_complete,
|
||||||
.flush = mt76x2_flush,
|
.flush = mt76x2_flush,
|
||||||
.ampdu_action = mt76x02_ampdu_action,
|
.ampdu_action = mt76x02_ampdu_action,
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@ -66,7 +55,7 @@ mt76pci_load_rom_patch(struct mt76x02_dev *dev)
|
|||||||
|
|
||||||
mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET);
|
mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET);
|
||||||
|
|
||||||
cur = (__le32 *) (fw->data + sizeof(*hdr));
|
cur = (__le32 *)(fw->data + sizeof(*hdr));
|
||||||
len = fw->size - sizeof(*hdr);
|
len = fw->size - sizeof(*hdr);
|
||||||
mt76_wr_copy(dev, MT_MCU_ROM_PATCH_ADDR, cur, len);
|
mt76_wr_copy(dev, MT_MCU_ROM_PATCH_ADDR, cur, len);
|
||||||
|
|
||||||
@ -121,7 +110,7 @@ mt76pci_load_firmware(struct mt76x02_dev *dev)
|
|||||||
dev_info(dev->mt76.dev, "Build: %x\n", val);
|
dev_info(dev->mt76.dev, "Build: %x\n", val);
|
||||||
dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);
|
dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);
|
||||||
|
|
||||||
cur = (__le32 *) (fw->data + sizeof(*hdr));
|
cur = (__le32 *)(fw->data + sizeof(*hdr));
|
||||||
len = le32_to_cpu(hdr->ilm_len);
|
len = le32_to_cpu(hdr->ilm_len);
|
||||||
|
|
||||||
mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET);
|
mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET);
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/delay.h>
|
#include <linux/delay.h>
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76x2.h"
|
#include "mt76x2.h"
|
||||||
@ -25,7 +14,8 @@ mt76x2_adjust_high_lna_gain(struct mt76x02_dev *dev, int reg, s8 offset)
|
|||||||
{
|
{
|
||||||
s8 gain;
|
s8 gain;
|
||||||
|
|
||||||
gain = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, mt76_rr(dev, MT_BBP(AGC, reg)));
|
gain = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN,
|
||||||
|
mt76_rr(dev, MT_BBP(AGC, reg)));
|
||||||
gain -= offset / 2;
|
gain -= offset / 2;
|
||||||
mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_LNA_HIGH_GAIN, gain);
|
mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_LNA_HIGH_GAIN, gain);
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@ -36,6 +25,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
|
|||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
static const struct mt76_driver_ops drv_ops = {
|
static const struct mt76_driver_ops drv_ops = {
|
||||||
|
.update_survey = mt76x02_update_channel,
|
||||||
.tx_prepare_skb = mt76x02u_tx_prepare_skb,
|
.tx_prepare_skb = mt76x02u_tx_prepare_skb,
|
||||||
.tx_complete_skb = mt76x02u_tx_complete_skb,
|
.tx_complete_skb = mt76x02u_tx_complete_skb,
|
||||||
.tx_status_data = mt76x02_tx_status_data,
|
.tx_status_data = mt76x02_tx_status_data,
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/delay.h>
|
#include <linux/delay.h>
|
||||||
@ -195,6 +184,13 @@ int mt76x2u_init_hardware(struct mt76x02_dev *dev)
|
|||||||
mt76x02_phy_set_rxpath(dev);
|
mt76x02_phy_set_rxpath(dev);
|
||||||
mt76x02_phy_set_txdac(dev);
|
mt76x02_phy_set_txdac(dev);
|
||||||
|
|
||||||
|
mt76_wr(dev, MT_CH_TIME_CFG,
|
||||||
|
MT_CH_TIME_CFG_TIMER_EN |
|
||||||
|
MT_CH_TIME_CFG_TX_AS_BUSY |
|
||||||
|
MT_CH_TIME_CFG_RX_AS_BUSY |
|
||||||
|
MT_CH_TIME_CFG_NAV_AS_BUSY |
|
||||||
|
MT_CH_TIME_CFG_EIFS_AS_BUSY);
|
||||||
|
|
||||||
return mt76x2u_mac_stop(dev);
|
return mt76x2u_mac_stop(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76x2u.h"
|
#include "mt76x2u.h"
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76x2u.h"
|
#include "mt76x2u.h"
|
||||||
@ -48,7 +37,7 @@ mt76x2u_set_channel(struct mt76x02_dev *dev,
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
cancel_delayed_work_sync(&dev->cal_work);
|
cancel_delayed_work_sync(&dev->cal_work);
|
||||||
dev->beacon_ops->pre_tbtt_enable(dev, false);
|
mt76x02_pre_tbtt_enable(dev, false);
|
||||||
|
|
||||||
mutex_lock(&dev->mt76.mutex);
|
mutex_lock(&dev->mt76.mutex);
|
||||||
set_bit(MT76_RESET, &dev->mt76.state);
|
set_bit(MT76_RESET, &dev->mt76.state);
|
||||||
@ -59,12 +48,16 @@ mt76x2u_set_channel(struct mt76x02_dev *dev,
|
|||||||
|
|
||||||
err = mt76x2u_phy_set_channel(dev, chandef);
|
err = mt76x2u_phy_set_channel(dev, chandef);
|
||||||
|
|
||||||
|
/* channel cycle counters read-and-clear */
|
||||||
|
mt76_rr(dev, MT_CH_IDLE);
|
||||||
|
mt76_rr(dev, MT_CH_BUSY);
|
||||||
|
|
||||||
mt76x2_mac_resume(dev);
|
mt76x2_mac_resume(dev);
|
||||||
|
|
||||||
clear_bit(MT76_RESET, &dev->mt76.state);
|
clear_bit(MT76_RESET, &dev->mt76.state);
|
||||||
mutex_unlock(&dev->mt76.mutex);
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
|
|
||||||
dev->beacon_ops->pre_tbtt_enable(dev, true);
|
mt76x02_pre_tbtt_enable(dev, true);
|
||||||
mt76_txq_schedule_all(&dev->mt76);
|
mt76_txq_schedule_all(&dev->mt76);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -121,10 +114,11 @@ const struct ieee80211_ops mt76x2u_ops = {
|
|||||||
.bss_info_changed = mt76x02_bss_info_changed,
|
.bss_info_changed = mt76x02_bss_info_changed,
|
||||||
.configure_filter = mt76x02_configure_filter,
|
.configure_filter = mt76x02_configure_filter,
|
||||||
.conf_tx = mt76x02_conf_tx,
|
.conf_tx = mt76x02_conf_tx,
|
||||||
.sw_scan_start = mt76x02_sw_scan,
|
.sw_scan_start = mt76_sw_scan,
|
||||||
.sw_scan_complete = mt76x02_sw_scan_complete,
|
.sw_scan_complete = mt76x02_sw_scan_complete,
|
||||||
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
|
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
|
||||||
.get_txpower = mt76_get_txpower,
|
.get_txpower = mt76_get_txpower,
|
||||||
|
.get_survey = mt76_get_survey,
|
||||||
.set_tim = mt76_set_tim,
|
.set_tim = mt76_set_tim,
|
||||||
.release_buffered_frames = mt76_release_buffered_frames,
|
.release_buffered_frames = mt76_release_buffered_frames,
|
||||||
};
|
};
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/firmware.h>
|
#include <linux/firmware.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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 "mt76x2u.h"
|
#include "mt76x2u.h"
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(__MT76_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
#if !defined(__MT76_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||||
@ -25,7 +14,8 @@
|
|||||||
|
|
||||||
#define MAXNAME 32
|
#define MAXNAME 32
|
||||||
#define DEV_ENTRY __array(char, wiphy_name, 32)
|
#define DEV_ENTRY __array(char, wiphy_name, 32)
|
||||||
#define DEV_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(dev->hw->wiphy), MAXNAME)
|
#define DEV_ASSIGN strlcpy(__entry->wiphy_name, \
|
||||||
|
wiphy_name(dev->hw->wiphy), MAXNAME)
|
||||||
#define DEV_PR_FMT "%s"
|
#define DEV_PR_FMT "%s"
|
||||||
#define DEV_PR_ARG __entry->wiphy_name
|
#define DEV_PR_ARG __entry->wiphy_name
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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 "mt76.h"
|
#include "mt76.h"
|
||||||
@ -97,7 +86,7 @@ mt76_txq_get_qid(struct ieee80211_txq *txq)
|
|||||||
static void
|
static void
|
||||||
mt76_check_agg_ssn(struct mt76_txq *mtxq, struct sk_buff *skb)
|
mt76_check_agg_ssn(struct mt76_txq *mtxq, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
|
|
||||||
if (!ieee80211_is_data_qos(hdr->frame_control) ||
|
if (!ieee80211_is_data_qos(hdr->frame_control) ||
|
||||||
!ieee80211_is_data_present(hdr->frame_control))
|
!ieee80211_is_data_present(hdr->frame_control))
|
||||||
@ -217,8 +206,8 @@ mt76_tx_status_skb_get(struct mt76_dev *dev, struct mt76_wcid *wcid, int pktid,
|
|||||||
if (cb->pktid == pktid)
|
if (cb->pktid == pktid)
|
||||||
return skb;
|
return skb;
|
||||||
|
|
||||||
if (pktid >= 0 &&
|
if (pktid >= 0 && !time_after(jiffies, cb->jiffies +
|
||||||
!time_after(jiffies, cb->jiffies + MT_TX_STATUS_SKB_TIMEOUT))
|
MT_TX_STATUS_SKB_TIMEOUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
__mt76_tx_status_skb_done(dev, skb, MT_TX_CB_TXS_FAILED |
|
__mt76_tx_status_skb_done(dev, skb, MT_TX_CB_TXS_FAILED |
|
||||||
@ -260,7 +249,7 @@ mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
|||||||
struct mt76_wcid *wcid, struct sk_buff *skb)
|
struct mt76_wcid *wcid, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
struct mt76_queue *q;
|
struct mt76_queue *q;
|
||||||
int qid = skb_get_queue_mapping(skb);
|
int qid = skb_get_queue_mapping(skb);
|
||||||
|
|
||||||
@ -280,7 +269,7 @@ mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
|||||||
|
|
||||||
tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
||||||
txq = sta->txq[tid];
|
txq = sta->txq[tid];
|
||||||
mtxq = (struct mt76_txq *) txq->drv_priv;
|
mtxq = (struct mt76_txq *)txq->drv_priv;
|
||||||
|
|
||||||
if (mtxq->aggr)
|
if (mtxq->aggr)
|
||||||
mt76_check_agg_ssn(mtxq, skb);
|
mt76_check_agg_ssn(mtxq, skb);
|
||||||
@ -328,7 +317,7 @@ static void
|
|||||||
mt76_queue_ps_skb(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
mt76_queue_ps_skb(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
||||||
struct sk_buff *skb, bool last)
|
struct sk_buff *skb, bool last)
|
||||||
{
|
{
|
||||||
struct mt76_wcid *wcid = (struct mt76_wcid *) sta->drv_priv;
|
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
|
||||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
|
|
||||||
info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
|
info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
|
||||||
@ -354,7 +343,7 @@ mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
|
|||||||
spin_lock_bh(&hwq->lock);
|
spin_lock_bh(&hwq->lock);
|
||||||
for (i = 0; tids && nframes; i++, tids >>= 1) {
|
for (i = 0; tids && nframes; i++, tids >>= 1) {
|
||||||
struct ieee80211_txq *txq = sta->txq[i];
|
struct ieee80211_txq *txq = sta->txq[i];
|
||||||
struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
|
struct mt76_txq *mtxq = (struct mt76_txq *)txq->drv_priv;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
if (!(tids & 1))
|
if (!(tids & 1))
|
||||||
@ -438,8 +427,7 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_sw_queue *sq,
|
|||||||
if (probe)
|
if (probe)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (test_bit(MT76_OFFCHANNEL, &dev->state) ||
|
if (test_bit(MT76_RESET, &dev->state))
|
||||||
test_bit(MT76_RESET, &dev->state))
|
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
skb = mt76_txq_dequeue(dev, mtxq, false);
|
skb = mt76_txq_dequeue(dev, mtxq, false);
|
||||||
@ -498,8 +486,7 @@ mt76_txq_schedule_list(struct mt76_dev *dev, enum mt76_txq_id qid)
|
|||||||
if (sq->swq_queued >= 4)
|
if (sq->swq_queued >= 4)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (test_bit(MT76_OFFCHANNEL, &dev->state) ||
|
if (test_bit(MT76_RESET, &dev->state)) {
|
||||||
test_bit(MT76_RESET, &dev->state)) {
|
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -568,6 +555,13 @@ void mt76_txq_schedule_all(struct mt76_dev *dev)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mt76_txq_schedule_all);
|
EXPORT_SYMBOL_GPL(mt76_txq_schedule_all);
|
||||||
|
|
||||||
|
void mt76_tx_tasklet(unsigned long data)
|
||||||
|
{
|
||||||
|
struct mt76_dev *dev = (struct mt76_dev *)data;
|
||||||
|
|
||||||
|
mt76_txq_schedule_all(dev);
|
||||||
|
}
|
||||||
|
|
||||||
void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
||||||
bool send_bar)
|
bool send_bar)
|
||||||
{
|
{
|
||||||
@ -610,7 +604,7 @@ void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq)
|
|||||||
if (!txq)
|
if (!txq)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mtxq = (struct mt76_txq *) txq->drv_priv;
|
mtxq = (struct mt76_txq *)txq->drv_priv;
|
||||||
|
|
||||||
while ((skb = skb_dequeue(&mtxq->retry_q)) != NULL)
|
while ((skb = skb_dequeue(&mtxq->retry_q)) != NULL)
|
||||||
ieee80211_free_txskb(dev->hw, skb);
|
ieee80211_free_txskb(dev->hw, skb);
|
||||||
@ -619,7 +613,7 @@ EXPORT_SYMBOL_GPL(mt76_txq_remove);
|
|||||||
|
|
||||||
void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq)
|
void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq)
|
||||||
{
|
{
|
||||||
struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
|
struct mt76_txq *mtxq = (struct mt76_txq *)txq->drv_priv;
|
||||||
|
|
||||||
skb_queue_head_init(&mtxq->retry_q);
|
skb_queue_head_init(&mtxq->retry_q);
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/module.h>
|
#include <linux/module.h>
|
||||||
@ -95,9 +84,9 @@ static u32 __mt76u_rr(struct mt76_dev *dev, u32 addr)
|
|||||||
|
|
||||||
ret = __mt76u_vendor_request(dev, req,
|
ret = __mt76u_vendor_request(dev, req,
|
||||||
USB_DIR_IN | USB_TYPE_VENDOR,
|
USB_DIR_IN | USB_TYPE_VENDOR,
|
||||||
0, offset, usb->data, sizeof(__le32));
|
0, offset, &usb->reg_val, sizeof(__le32));
|
||||||
if (ret == sizeof(__le32))
|
if (ret == sizeof(__le32))
|
||||||
data = get_unaligned_le32(usb->data);
|
data = le32_to_cpu(usb->reg_val);
|
||||||
trace_usb_reg_rr(dev, addr, data);
|
trace_usb_reg_rr(dev, addr, data);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -131,10 +120,10 @@ static void __mt76u_wr(struct mt76_dev *dev, u32 addr, u32 val)
|
|||||||
}
|
}
|
||||||
offset = addr & ~MT_VEND_TYPE_MASK;
|
offset = addr & ~MT_VEND_TYPE_MASK;
|
||||||
|
|
||||||
put_unaligned_le32(val, usb->data);
|
usb->reg_val = cpu_to_le32(val);
|
||||||
__mt76u_vendor_request(dev, req,
|
__mt76u_vendor_request(dev, req,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR, 0,
|
USB_DIR_OUT | USB_TYPE_VENDOR, 0,
|
||||||
offset, usb->data, sizeof(__le32));
|
offset, &usb->reg_val, sizeof(__le32));
|
||||||
trace_usb_reg_wr(dev, addr, val);
|
trace_usb_reg_wr(dev, addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,12 +153,12 @@ static void mt76u_copy(struct mt76_dev *dev, u32 offset,
|
|||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
mutex_lock(&usb->usb_ctrl_mtx);
|
mutex_lock(&usb->usb_ctrl_mtx);
|
||||||
for (i = 0; i < (len / 4); i++) {
|
for (i = 0; i < DIV_ROUND_UP(len, 4); i++) {
|
||||||
put_unaligned_le32(val[i], usb->data);
|
put_unaligned(val[i], (u32 *)usb->data);
|
||||||
ret = __mt76u_vendor_request(dev, MT_VEND_MULTI_WRITE,
|
ret = __mt76u_vendor_request(dev, MT_VEND_MULTI_WRITE,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR,
|
USB_DIR_OUT | USB_TYPE_VENDOR,
|
||||||
0, offset + i * 4, usb->data,
|
0, offset + i * 4, usb->data,
|
||||||
sizeof(__le32));
|
sizeof(u32));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -309,7 +298,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76_queue *q, struct urb *urb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
urb->num_sgs = max_t(int, i, urb->num_sgs);
|
urb->num_sgs = max_t(int, i, urb->num_sgs);
|
||||||
urb->transfer_buffer_length = urb->num_sgs * q->buf_size,
|
urb->transfer_buffer_length = urb->num_sgs * q->buf_size;
|
||||||
sg_init_marker(urb->sg, urb->num_sgs);
|
sg_init_marker(urb->sg, urb->num_sgs);
|
||||||
|
|
||||||
return i ? : -ENOMEM;
|
return i ? : -ENOMEM;
|
||||||
@ -320,14 +309,13 @@ mt76u_refill_rx(struct mt76_dev *dev, struct urb *urb, int nsgs, gfp_t gfp)
|
|||||||
{
|
{
|
||||||
struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
|
struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
|
||||||
|
|
||||||
if (dev->usb.sg_en) {
|
if (dev->usb.sg_en)
|
||||||
return mt76u_fill_rx_sg(dev, q, urb, nsgs, gfp);
|
return mt76u_fill_rx_sg(dev, q, urb, nsgs, gfp);
|
||||||
} else {
|
|
||||||
urb->transfer_buffer_length = q->buf_size;
|
urb->transfer_buffer_length = q->buf_size;
|
||||||
urb->transfer_buffer = page_frag_alloc(&q->rx_page,
|
urb->transfer_buffer = page_frag_alloc(&q->rx_page, q->buf_size, gfp);
|
||||||
q->buf_size, gfp);
|
|
||||||
return urb->transfer_buffer ? 0 : -ENOMEM;
|
return urb->transfer_buffer ? 0 : -ENOMEM;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -763,13 +751,14 @@ mt76u_tx_setup_buffers(struct mt76_dev *dev, struct sk_buff *skb,
|
|||||||
if (!dev->usb.sg_en) {
|
if (!dev->usb.sg_en) {
|
||||||
urb->transfer_buffer = skb->data;
|
urb->transfer_buffer = skb->data;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
sg_init_table(urb->sg, MT_TX_SG_MAX_SIZE);
|
sg_init_table(urb->sg, MT_TX_SG_MAX_SIZE);
|
||||||
urb->num_sgs = skb_to_sgvec(skb, urb->sg, 0, skb->len);
|
urb->num_sgs = skb_to_sgvec(skb, urb->sg, 0, skb->len);
|
||||||
if (urb->num_sgs == 0)
|
if (!urb->num_sgs)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return urb->num_sgs;
|
return urb->num_sgs;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -885,7 +874,8 @@ void mt76u_stop_tx(struct mt76_dev *dev)
|
|||||||
struct mt76_queue *q;
|
struct mt76_queue *q;
|
||||||
int i, j, ret;
|
int i, j, ret;
|
||||||
|
|
||||||
ret = wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(dev), HZ/5);
|
ret = wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(dev),
|
||||||
|
HZ / 5);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
dev_err(dev->dev, "timed out waiting for pending tx\n");
|
dev_err(dev->dev, "timed out waiting for pending tx\n");
|
||||||
|
|
||||||
@ -957,7 +947,7 @@ int mt76u_init(struct mt76_dev *dev,
|
|||||||
.rr = mt76u_rr,
|
.rr = mt76u_rr,
|
||||||
.wr = mt76u_wr,
|
.wr = mt76u_wr,
|
||||||
.rmw = mt76u_rmw,
|
.rmw = mt76u_rmw,
|
||||||
.copy = mt76u_copy,
|
.write_copy = mt76u_copy,
|
||||||
.wr_rp = mt76u_wr_rp,
|
.wr_rp = mt76u_wr_rp,
|
||||||
.rd_rp = mt76u_rd_rp,
|
.rd_rp = mt76u_rd_rp,
|
||||||
.type = MT76_BUS_USB,
|
.type = MT76_BUS_USB,
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: ISC */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(__MT76_USB_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
#if !defined(__MT76_USB_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||||
@ -25,7 +14,8 @@
|
|||||||
|
|
||||||
#define MAXNAME 32
|
#define MAXNAME 32
|
||||||
#define DEV_ENTRY __array(char, wiphy_name, 32)
|
#define DEV_ENTRY __array(char, wiphy_name, 32)
|
||||||
#define DEV_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(dev->hw->wiphy), MAXNAME)
|
#define DEV_ASSIGN strlcpy(__entry->wiphy_name, \
|
||||||
|
wiphy_name(dev->hw->wiphy), MAXNAME)
|
||||||
#define DEV_PR_FMT "%s "
|
#define DEV_PR_FMT "%s "
|
||||||
#define DEV_PR_ARG __entry->wiphy_name
|
#define DEV_PR_ARG __entry->wiphy_name
|
||||||
|
|
||||||
@ -65,7 +55,7 @@ DECLARE_EVENT_CLASS(urb_transfer,
|
|||||||
TP_PROTO(struct mt76_dev *dev, struct urb *u),
|
TP_PROTO(struct mt76_dev *dev, struct urb *u),
|
||||||
TP_ARGS(dev, u),
|
TP_ARGS(dev, u),
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
DEV_ENTRY __field(unsigned, pipe) __field(u32, len)
|
DEV_ENTRY __field(unsigned int, pipe) __field(u32, len)
|
||||||
),
|
),
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
DEV_ASSIGN;
|
DEV_ASSIGN;
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
|
// SPDX-License-Identifier: ISC
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
* 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/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <linux/bitfield.h>
|
#include <linux/bitfield.h>
|
||||||
|
|
||||||
#define MT76_INCR(_var, _size) \
|
#define MT76_INCR(_var, _size) \
|
||||||
_var = (((_var) + 1) % _size)
|
(_var = (((_var) + 1) % (_size)))
|
||||||
|
|
||||||
int mt76_wcid_alloc(unsigned long *mask, int size);
|
int mt76_wcid_alloc(unsigned long *mask, int size);
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ mt76_wcid_free(unsigned long *mask, int idx)
|
|||||||
static inline void
|
static inline void
|
||||||
mt76_skb_set_moredata(struct sk_buff *skb, bool enable)
|
mt76_skb_set_moredata(struct sk_buff *skb, bool enable)
|
||||||
{
|
{
|
||||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
|
||||||
|
Loading…
Reference in New Issue
Block a user