summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02.h3
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c34
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c20
4 files changed, 22 insertions, 37 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 7570d0e2c021..0d817a142e76 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -69,6 +69,8 @@ struct mt76x02_calibration {
};
struct mt76x02_beacon_ops {
+ unsigned int nslots;
+ unsigned int slot_size;
void (*pre_tbtt_enable) (struct mt76x02_dev *, bool);
void (*beacon_enable) (struct mt76x02_dev *, bool);
};
@@ -194,7 +196,6 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info, u32 changed);
-extern const u16 mt76x02_beacon_offsets[16];
struct beacon_bc_data {
struct mt76x02_dev *dev;
struct sk_buff_head q;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index c0be90988f82..0c232d02f189 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -18,36 +18,14 @@
#include "mt76x02.h"
-const u16 mt76x02_beacon_offsets[16] = {
- /* 1024 byte per beacon */
- 0xc000,
- 0xc400,
- 0xc800,
- 0xcc00,
- 0xd000,
- 0xd400,
- 0xd800,
- 0xdc00,
- /* BSS idx 8-15 not used for beacons */
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
-};
-EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets);
-
static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
{
- u16 val, base = MT_BEACON_BASE;
u32 regs[4] = {};
+ u16 val;
int i;
- for (i = 0; i < 16; i++) {
- val = mt76x02_beacon_offsets[i] - base;
+ for (i = 0; i < dev->beacon_ops->nslots; i++) {
+ val = i * dev->beacon_ops->slot_size;
regs[i / 4] |= (val / 64) << (8 * (i % 4));
}
@@ -58,7 +36,7 @@ static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
static int
mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
{
- int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
+ int beacon_len = dev->beacon_ops->slot_size;
struct mt76x02_txwi txwi;
if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
@@ -77,8 +55,8 @@ static int
__mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
struct sk_buff *skb)
{
- int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
- int beacon_addr = mt76x02_beacon_offsets[bcn_idx];
+ int beacon_len = dev->beacon_ops->slot_size;
+ int beacon_addr = MT_BEACON_BASE + (beacon_len * bcn_idx);
int ret = 0;
int i;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 8e8da95c128c..ca8320711bc2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -85,6 +85,8 @@ static void mt76x02e_beacon_enable(struct mt76x02_dev *dev, bool en)
void mt76x02e_init_beacon_config(struct mt76x02_dev *dev)
{
static const struct mt76x02_beacon_ops beacon_ops = {
+ .nslots = 8,
+ .slot_size = 1024,
.pre_tbtt_enable = mt76x02e_pre_tbtt_enable,
.beacon_enable = mt76x02e_beacon_enable,
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 89249621bcec..c403218533da 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -107,6 +107,13 @@ EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb);
/* Trigger pre-TBTT event 8 ms before TBTT */
#define PRE_TBTT_USEC 8000
+
+/* Beacon SRAM memory is limited to 8kB. We need to send PS buffered frames
+ * (which can be 1500 bytes big) via beacon memory. That make limit of number
+ * of slots to 5. TODO: dynamically calculate offsets in beacon SRAM.
+ */
+#define N_BCN_SLOTS 5
+
static void mt76x02u_start_pre_tbtt_timer(struct mt76x02_dev *dev)
{
u64 time;
@@ -164,7 +171,6 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
{
struct mt76x02_dev *dev =
container_of(work, struct mt76x02_dev, pre_tbtt_work);
- int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
struct beacon_bc_data data = {};
struct sk_buff *skb;
int i, nbeacons;
@@ -179,14 +185,10 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
mt76x02_update_beacon_iter, dev);
nbeacons = hweight8(dev->beacon_mask);
- mt76x02_enqueue_buffered_bc(dev, &data, 8 - nbeacons);
+ mt76x02_enqueue_buffered_bc(dev, &data, N_BCN_SLOTS - nbeacons);
- for (i = nbeacons; i < 8; i++) {
+ for (i = nbeacons; i < N_BCN_SLOTS; i++) {
skb = __skb_dequeue(&data.q);
- if (skb && skb->len >= beacon_len) {
- dev_kfree_skb(skb);
- skb = NULL;
- }
mt76x02_mac_set_beacon(dev, i, skb);
}
@@ -224,7 +226,7 @@ static void mt76x02u_beacon_enable(struct mt76x02_dev *dev, bool en)
/* Timer is already stopped, only clean up
* PS buffered frames if any.
*/
- for (i = 0; i < 8; i++)
+ for (i = 0; i < N_BCN_SLOTS; i++)
mt76x02_mac_set_beacon(dev, i, NULL);
}
}
@@ -232,6 +234,8 @@ static void mt76x02u_beacon_enable(struct mt76x02_dev *dev, bool en)
void mt76x02u_init_beacon_config(struct mt76x02_dev *dev)
{
static const struct mt76x02_beacon_ops beacon_ops = {
+ .nslots = N_BCN_SLOTS,
+ .slot_size = (8192 / N_BCN_SLOTS) & ~63,
.pre_tbtt_enable = mt76x02u_pre_tbtt_enable,
.beacon_enable = mt76x02u_beacon_enable,
};