// SPDX-License-Identifier: ISC
/*
 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
 */

#include "mt76x02.h"

static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
{
	u32 regs[4] = {};
	u16 val;
	int i;

	for (i = 0; i < dev->beacon_ops->nslots; i++) {
		val = i * dev->beacon_ops->slot_size;
		regs[i / 4] |= (val / 64) << (8 * (i % 4));
	}

	for (i = 0; i < 4; i++)
		mt76_wr(dev, MT_BCN_OFFSET(i), regs[i]);
}

static int
mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
{
	int beacon_len = dev->beacon_ops->slot_size;

	if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
		return -ENOSPC;

	/* USB devices already reserve enough skb headroom for txwi's. This
	 * helps to save slow copies over USB.
	 */
	if (mt76_is_usb(&dev->mt76)) {
		struct mt76x02_txwi *txwi;

		txwi = (struct mt76x02_txwi *)(skb->data - sizeof(*txwi));
		mt76x02_mac_write_txwi(dev, txwi, skb, NULL, NULL, skb->len);
		skb_push(skb, sizeof(*txwi));
	} else {
		struct mt76x02_txwi txwi;

		mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
		mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
		offset += sizeof(txwi);
	}

	mt76_wr_copy(dev, offset, skb->data, skb->len);
	return 0;
}

void mt76x02_mac_set_beacon(struct mt76x02_dev *dev,
			    struct sk_buff *skb)
{
	int bcn_len = dev->beacon_ops->slot_size;
	int bcn_addr = MT_BEACON_BASE + (bcn_len * dev->beacon_data_count);

	if (!mt76x02_write_beacon(dev, bcn_addr, skb)) {
		if (!dev->beacon_data_count)
			dev->beacon_hang_check++;
		dev->beacon_data_count++;
	}
	dev_kfree_skb(skb);
}
EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);

void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
				   struct ieee80211_vif *vif, bool enable)
{
	struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
	u8 old_mask = dev->mt76.beacon_mask;

	mt76x02_pre_tbtt_enable(dev, false);

	if (!dev->mt76.beacon_mask)
		dev->tbtt_count = 0;

	dev->beacon_hang_check = 0;
	if (enable) {
		dev->mt76.beacon_mask |= BIT(mvif->idx);
	} else {
		dev->mt76.beacon_mask &= ~BIT(mvif->idx);
	}

	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
mt76x02_resync_beacon_timer(struct mt76x02_dev *dev)
{
	u32 timer_val = dev->mt76.beacon_int << 4;

	dev->tbtt_count++;

	/*
	 * Beacon timer drifts by 1us every tick, the timer is configured
	 * in 1/16 TU (64us) units.
	 */
	if (dev->tbtt_count < 63)
		return;

	/*
	 * The updated beacon interval takes effect after two TBTT, because
	 * at this point the original interval has already been loaded into
	 * the next TBTT_TIMER value
	 */
	if (dev->tbtt_count == 63)
		timer_val -= 1;

	mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
		       MT_BEACON_TIME_CFG_INTVAL, timer_val);

	if (dev->tbtt_count >= 64)
		dev->tbtt_count = 0;
}
EXPORT_SYMBOL_GPL(mt76x02_resync_beacon_timer);

void
mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
	struct mt76x02_dev *dev = (struct mt76x02_dev *)priv;
	struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
	struct sk_buff *skb = NULL;

	if (!(dev->mt76.beacon_mask & BIT(mvif->idx)))
		return;

	skb = ieee80211_beacon_get(mt76_hw(dev), vif, 0);
	if (!skb)
		return;

	mt76x02_mac_set_beacon(dev, skb);
}
EXPORT_SYMBOL_GPL(mt76x02_update_beacon_iter);

static void
mt76x02_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
	struct beacon_bc_data *data = priv;
	struct mt76x02_dev *dev = data->dev;
	struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
	struct ieee80211_tx_info *info;
	struct sk_buff *skb;

	if (!(dev->mt76.beacon_mask & BIT(mvif->idx)))
		return;

	skb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);
	if (!skb)
		return;

	info = IEEE80211_SKB_CB(skb);
	info->control.vif = vif;
	info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
	mt76_skb_set_moredata(skb, true);
	__skb_queue_tail(&data->q, skb);
	data->tail[mvif->idx] = skb;
}

void
mt76x02_enqueue_buffered_bc(struct mt76x02_dev *dev,
			    struct beacon_bc_data *data,
			    int max_nframes)
{
	int i, nframes;

	data->dev = dev;
	__skb_queue_head_init(&data->q);

	do {
		nframes = skb_queue_len(&data->q);
		ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
			IEEE80211_IFACE_ITER_RESUME_ALL,
			mt76x02_add_buffered_bc, data);
	} while (nframes != skb_queue_len(&data->q) &&
		 skb_queue_len(&data->q) < max_nframes);

	if (!skb_queue_len(&data->q))
		return;

	for (i = 0; i < ARRAY_SIZE(data->tail); i++) {
		if (!data->tail[i])
			continue;
		mt76_skb_set_moredata(data->tail[i], false);
	}
}
EXPORT_SYMBOL_GPL(mt76x02_enqueue_buffered_bc);

void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
{
	mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN |
					     MT_BEACON_TIME_CFG_TBTT_EN |
					     MT_BEACON_TIME_CFG_BEACON_TX));
	mt76_set(dev, MT_BEACON_TIME_CFG, MT_BEACON_TIME_CFG_SYNC_MODE);
	mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff);
	mt76x02_set_beacon_offsets(dev);
}
EXPORT_SYMBOL_GPL(mt76x02_init_beacon_config);

