2
0
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:
Kalle Valo 2019-09-06 11:59:32 +03:00
commit a18da8f619
98 changed files with 1871 additions and 1519 deletions

View File

@ -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);

View File

@ -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"

View File

@ -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;
} }

View File

@ -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

View File

@ -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>

View File

@ -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);

View File

@ -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"

View File

@ -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,

View File

@ -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);

View File

@ -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.

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */ // SPDX-License-Identifier: ISC
#include "mt7603.h" #include "mt7603.h"

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */ // SPDX-License-Identifier: ISC
#include "mt7603.h" #include "mt7603.h"

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */ // SPDX-License-Identifier: ISC
#include "mt7603.h" #include "mt7603.h"

View File

@ -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 |

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */ // SPDX-License-Identifier: ISC
#include "mt7603.h" #include "mt7603.h"
#include "eeprom.h" #include "eeprom.h"

View File

@ -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;

View File

@ -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);
} }

View File

@ -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 = &params->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,

View File

@ -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"

View File

@ -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;

View File

@ -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>

View File

@ -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);

View File

@ -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.

View File

@ -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

View 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;
}

View File

@ -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 |

View File

@ -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,

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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 = &params->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,
}; };

View File

@ -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;
} }

View File

@ -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) + \

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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>

View File

@ -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));

View File

@ -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)

View File

@ -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);

View File

@ -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>

View File

@ -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);

View File

@ -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);

View File

@ -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>

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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"

View File

@ -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>

View File

@ -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 = &params->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)
{ {

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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>

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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;
} }

View File

@ -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,

View File

@ -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);

View File

@ -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>

View File

@ -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);
} }

View File

@ -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,

View File

@ -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);
} }

View File

@ -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"

View File

@ -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,
}; };

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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>

View File

@ -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;

View File

@ -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>

View File

@ -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);