Skip to content

Commit

Permalink
mt76x02u: implement pre TBTT work for USB
Browse files Browse the repository at this point in the history
Program beacons data and PS buffered frames on TBTT work for USB.
We do not have MT_TXQ_PSD queue available via USB endpoints. The way
we can send PS broadcast frames in timely manner before PS stations go
sleep again is program them in beacon data area. Hardware do not modify
those frames since TXWI is properly configured. mt76x02_mac_set_beacon()
already handle this and free no longer used frames.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
Stanislaw Gruszka authored and nbd168 committed Mar 24, 2019
1 parent 5ac5289 commit e284cc2
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
2 changes: 2 additions & 0 deletions mt76x02_beacon.c
Expand Up @@ -38,6 +38,7 @@ const u16 mt76x02_beacon_offsets[16] = {
0xc000,
0xc000,
};
EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets);

static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
{
Expand Down Expand Up @@ -134,6 +135,7 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
bcn_idx - 1);
return 0;
}
EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);

static void
__mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev, u8 vif_idx,
Expand Down
36 changes: 33 additions & 3 deletions mt76x02_usb_core.c
Expand Up @@ -165,9 +165,32 @@ 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;

if (!dev->beacon_mask)
return;

mt76x02_resync_beacon_timer(dev);

ieee80211_iterate_active_interfaces(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt76x02_update_beacon_iter, dev);

nbeacons = hweight8(dev->beacon_mask);
mt76x02_enqueue_buffered_bc(dev, &data, 8 - nbeacons);

for (i = nbeacons; i < 8; 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);
}

mt76x02u_restart_pre_tbtt_timer(dev);
}

Expand All @@ -191,13 +214,20 @@ static void mt76x02u_pre_tbtt_enable(struct mt76x02_dev *dev, bool en)

static void mt76x02u_beacon_enable(struct mt76x02_dev *dev, bool en)
{
int i;

if (WARN_ON_ONCE(!dev->beacon_int))
return;

if (en)
if (en) {
mt76x02u_start_pre_tbtt_timer(dev);

/* Nothing to do on disable as timer is already stopped */
} else {
/* Timer is already stopped, only clean up
* PS buffered frames if any.
*/
for (i = 0; i < 8; i++)
mt76x02_mac_set_beacon(dev, i, NULL);
}
}

void mt76x02u_init_beacon_config(struct mt76x02_dev *dev)
Expand Down

0 comments on commit e284cc2

Please sign in to comment.