diff options
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, }; |