// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
 *
 * Contact Information: wlanfae <wlanfae@realtek.com>
 */
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <linux/etherdevice.h>
#include "rtllib.h"
#include "rtl819x_BA.h"

static void activate_ba_entry(struct ba_record *ba, u16 time)
{
	ba->b_valid = true;
	if (time != 0)
		mod_timer(&ba->timer, jiffies + msecs_to_jiffies(time));
}

static void deactivate_ba_entry(struct rtllib_device *ieee, struct ba_record *ba)
{
	ba->b_valid = false;
	del_timer_sync(&ba->timer);
}

static u8 tx_ts_delete_ba(struct rtllib_device *ieee, struct tx_ts_record *ts)
{
	struct ba_record *admitted_ba = &ts->tx_admitted_ba_record;
	struct ba_record *pending_ba = &ts->tx_pending_ba_record;
	u8 send_del_ba = false;

	if (pending_ba->b_valid) {
		deactivate_ba_entry(ieee, pending_ba);
		send_del_ba = true;
	}

	if (admitted_ba->b_valid) {
		deactivate_ba_entry(ieee, admitted_ba);
		send_del_ba = true;
	}
	return send_del_ba;
}

static u8 rx_ts_delete_ba(struct rtllib_device *ieee, struct rx_ts_record *ts)
{
	struct ba_record *ba = &ts->rx_admitted_ba_record;
	u8			send_del_ba = false;

	if (ba->b_valid) {
		deactivate_ba_entry(ieee, ba);
		send_del_ba = true;
	}

	return send_del_ba;
}

void rtllib_reset_ba_entry(struct ba_record *ba)
{
	ba->b_valid                      = false;
	ba->ba_param_set.short_data      = 0;
	ba->ba_timeout_value             = 0;
	ba->dialog_token                 = 0;
	ba->ba_start_seq_ctrl.short_data = 0;
}

static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *dst,
				    struct ba_record *ba,
				    u16 status_code, u8 type)
{
	struct sk_buff *skb = NULL;
	struct ieee80211_hdr_3addr *ba_req = NULL;
	u8 *tag = NULL;
	u16 len = ieee->tx_headroom + 9;

	netdev_dbg(ieee->dev, "%s(): frame(%d) sentd to: %pM, ieee->dev:%p\n",
		   __func__, type, dst, ieee->dev);

	if (!ba) {
		netdev_warn(ieee->dev, "ba is NULL\n");
		return NULL;
	}
	skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
	if (!skb)
		return NULL;

	memset(skb->data, 0, sizeof(struct ieee80211_hdr_3addr));

	skb_reserve(skb, ieee->tx_headroom);

	ba_req = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));

	ether_addr_copy(ba_req->addr1, dst);
	ether_addr_copy(ba_req->addr2, ieee->dev->dev_addr);

	ether_addr_copy(ba_req->addr3, ieee->current_network.bssid);
	ba_req->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);

	tag = skb_put(skb, 9);
	*tag++ = ACT_CAT_BA;
	*tag++ = type;
	*tag++ = ba->dialog_token;

	if (type == ACT_ADDBARSP) {
		put_unaligned_le16(status_code, tag);
		tag += 2;
	}

	put_unaligned_le16(ba->ba_param_set.short_data, tag);
	tag += 2;

	put_unaligned_le16(ba->ba_timeout_value, tag);
	tag += 2;

	if (type == ACT_ADDBAREQ) {
		memcpy(tag, (u8 *)&ba->ba_start_seq_ctrl, 2);
		tag += 2;
	}

#ifdef VERBOSE_DEBUG
	print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
			     __func__, skb->len);
#endif
	return skb;
}

static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst,
				    struct ba_record *ba,
				    enum tr_select TxRxSelect, u16 reason_code)
{
	union delba_param_set del_ba_param_set;
	struct sk_buff *skb = NULL;
	struct ieee80211_hdr_3addr *del_ba = NULL;
	u8 *tag = NULL;
	u16 len = 6 + ieee->tx_headroom;

	if (net_ratelimit())
		netdev_dbg(ieee->dev, "%s(): reason_code(%d) sentd to: %pM\n",
			   __func__, reason_code, dst);

	memset(&del_ba_param_set, 0, 2);

	del_ba_param_set.field.initiator = (TxRxSelect == TX_DIR) ? 1 : 0;
	del_ba_param_set.field.tid	= ba->ba_param_set.field.tid;

	skb = dev_alloc_skb(len + sizeof(struct ieee80211_hdr_3addr));
	if (!skb)
		return NULL;

	skb_reserve(skb, ieee->tx_headroom);

	del_ba = skb_put(skb, sizeof(struct ieee80211_hdr_3addr));

	ether_addr_copy(del_ba->addr1, dst);
	ether_addr_copy(del_ba->addr2, ieee->dev->dev_addr);
	ether_addr_copy(del_ba->addr3, ieee->current_network.bssid);
	del_ba->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION);

	tag = skb_put(skb, 6);

	*tag++ = ACT_CAT_BA;
	*tag++ = ACT_DELBA;

	put_unaligned_le16(del_ba_param_set.short_data, tag);
	tag += 2;

	put_unaligned_le16(reason_code, tag);
	tag += 2;

#ifdef VERBOSE_DEBUG
	print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
			     __func__, skb->len);
#endif
	return skb;
}

static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst,
				 struct ba_record *ba)
{
	struct sk_buff *skb;

	skb = rtllib_ADDBA(ieee, dst, ba, 0, ACT_ADDBAREQ);

	if (skb)
		softmac_mgmt_xmit(skb, ieee);
	else
		netdev_dbg(ieee->dev, "Failed to generate ADDBAReq packet.\n");
}

static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst,
				 struct ba_record *ba, u16 status_code)
{
	struct sk_buff *skb;

	skb = rtllib_ADDBA(ieee, dst, ba, status_code, ACT_ADDBARSP);
	if (skb)
		softmac_mgmt_xmit(skb, ieee);
	else
		netdev_dbg(ieee->dev, "Failed to generate ADDBARsp packet.\n");
}

static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst,
			      struct ba_record *ba, enum tr_select TxRxSelect,
			      u16 reason_code)
{
	struct sk_buff *skb;

	skb = rtllib_DELBA(ieee, dst, ba, TxRxSelect, reason_code);
	if (skb)
		softmac_mgmt_xmit(skb, ieee);
	else
		netdev_dbg(ieee->dev, "Failed to generate DELBA packet.\n");
}

int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb)
{
	struct ieee80211_hdr_3addr *req = NULL;
	u16 rc = 0;
	u8 *dst = NULL, *dialog_token = NULL, *tag = NULL;
	struct ba_record *ba = NULL;
	union ba_param_set *ba_param_set = NULL;
	u16 *ba_timeout_value = NULL;
	union sequence_control *ba_start_seq_ctrl = NULL;
	struct rx_ts_record *ts = NULL;

	if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
		netdev_warn(ieee->dev, "Invalid skb len in BAREQ(%d / %d)\n",
			    (int)skb->len,
			    (int)(sizeof(struct ieee80211_hdr_3addr) + 9));
		return -1;
	}

#ifdef VERBOSE_DEBUG
	print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, __func__,
			     skb->data, skb->len);
#endif

	req = (struct ieee80211_hdr_3addr *)skb->data;
	tag = (u8 *)req;
	dst = (u8 *)(&req->addr2[0]);
	tag += sizeof(struct ieee80211_hdr_3addr);
	dialog_token = tag + 2;
	ba_param_set = (union ba_param_set *)(tag + 3);
	ba_timeout_value = (u16 *)(tag + 5);
	ba_start_seq_ctrl = (union sequence_control *)(req + 7);

	if (!ieee->current_network.qos_data.active ||
	    !ieee->ht_info->current_ht_support ||
	    (ieee->ht_info->iot_action & HT_IOT_ACT_REJECT_ADDBA_REQ)) {
		rc = ADDBA_STATUS_REFUSED;
		netdev_warn(ieee->dev,
			    "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n",
			    ieee->current_network.qos_data.active,
			    ieee->ht_info->current_ht_support);
		goto OnADDBAReq_Fail;
	}
	if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
		   (u8)(ba_param_set->field.tid), RX_DIR, true)) {
		rc = ADDBA_STATUS_REFUSED;
		netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
		goto OnADDBAReq_Fail;
	}
	ba = &ts->rx_admitted_ba_record;

	if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) {
		rc = ADDBA_STATUS_INVALID_PARAM;
		netdev_warn(ieee->dev, "%s(): BA Policy is not correct\n",
			    __func__);
		goto OnADDBAReq_Fail;
	}

	rtllib_FlushRxTsPendingPkts(ieee, ts);

	deactivate_ba_entry(ieee, ba);
	ba->dialog_token = *dialog_token;
	ba->ba_param_set = *ba_param_set;
	ba->ba_timeout_value = *ba_timeout_value;
	ba->ba_start_seq_ctrl = *ba_start_seq_ctrl;

	if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) ||
	   (ieee->ht_info->iot_action & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT))
		ba->ba_param_set.field.buffer_size = 1;
	else
		ba->ba_param_set.field.buffer_size = 32;

	activate_ba_entry(ba, 0);
	rtllib_send_ADDBARsp(ieee, dst, ba, ADDBA_STATUS_SUCCESS);

	return 0;

OnADDBAReq_Fail:
	{
		struct ba_record BA;

		BA.ba_param_set = *ba_param_set;
		BA.ba_timeout_value = *ba_timeout_value;
		BA.dialog_token = *dialog_token;
		BA.ba_param_set.field.ba_policy = BA_POLICY_IMMEDIATE;
		rtllib_send_ADDBARsp(ieee, dst, &BA, rc);
		return 0;
	}
}

int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb)
{
	struct ieee80211_hdr_3addr *rsp = NULL;
	struct ba_record *pending_ba, *admitted_ba;
	struct tx_ts_record *ts = NULL;
	u8 *dst = NULL, *dialog_token = NULL, *tag = NULL;
	u16 *status_code = NULL, *ba_timeout_value = NULL;
	union ba_param_set *ba_param_set = NULL;
	u16			reason_code;

	if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 9) {
		netdev_warn(ieee->dev, "Invalid skb len in BARSP(%d / %d)\n",
			    (int)skb->len,
			    (int)(sizeof(struct ieee80211_hdr_3addr) + 9));
		return -1;
	}
	rsp = (struct ieee80211_hdr_3addr *)skb->data;
	tag = (u8 *)rsp;
	dst = (u8 *)(&rsp->addr2[0]);
	tag += sizeof(struct ieee80211_hdr_3addr);
	dialog_token = tag + 2;
	status_code = (u16 *)(tag + 3);
	ba_param_set = (union ba_param_set *)(tag + 5);
	ba_timeout_value = (u16 *)(tag + 7);

	if (!ieee->current_network.qos_data.active ||
	    !ieee->ht_info->current_ht_support ||
	    !ieee->ht_info->current_ampdu_enable) {
		netdev_warn(ieee->dev,
			    "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",
			    ieee->current_network.qos_data.active,
			    ieee->ht_info->current_ht_support,
			    ieee->ht_info->current_ampdu_enable);
		reason_code = DELBA_REASON_UNKNOWN_BA;
		goto OnADDBARsp_Reject;
	}

	if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
		   (u8)(ba_param_set->field.tid), TX_DIR, false)) {
		netdev_warn(ieee->dev, "%s(): can't get TS\n", __func__);
		reason_code = DELBA_REASON_UNKNOWN_BA;
		goto OnADDBARsp_Reject;
	}

	ts->add_ba_req_in_progress = false;
	pending_ba = &ts->tx_pending_ba_record;
	admitted_ba = &ts->tx_admitted_ba_record;

	if (admitted_ba->b_valid) {
		netdev_dbg(ieee->dev, "%s(): ADDBA response already admitted\n",
			   __func__);
		return -1;
	} else if (!pending_ba->b_valid ||
		   (*dialog_token != pending_ba->dialog_token)) {
		netdev_warn(ieee->dev,
			    "%s(): ADDBA Rsp. BA invalid, DELBA!\n",
			    __func__);
		reason_code = DELBA_REASON_UNKNOWN_BA;
		goto OnADDBARsp_Reject;
	} else {
		netdev_dbg(ieee->dev,
			   "%s(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n",
			   __func__, *status_code);
		deactivate_ba_entry(ieee, pending_ba);
	}

	if (*status_code == ADDBA_STATUS_SUCCESS) {
		if (ba_param_set->field.ba_policy == BA_POLICY_DELAYED) {
			ts->add_ba_req_delayed = true;
			deactivate_ba_entry(ieee, admitted_ba);
			reason_code = DELBA_REASON_END_BA;
			goto OnADDBARsp_Reject;
		}

		admitted_ba->dialog_token = *dialog_token;
		admitted_ba->ba_timeout_value = *ba_timeout_value;
		admitted_ba->ba_start_seq_ctrl = pending_ba->ba_start_seq_ctrl;
		admitted_ba->ba_param_set = *ba_param_set;
		deactivate_ba_entry(ieee, admitted_ba);
		activate_ba_entry(admitted_ba, *ba_timeout_value);
	} else {
		ts->add_ba_req_delayed = true;
		ts->disable_add_ba = true;
		reason_code = DELBA_REASON_END_BA;
		goto OnADDBARsp_Reject;
	}

	return 0;

OnADDBARsp_Reject:
	{
		struct ba_record BA;

		BA.ba_param_set = *ba_param_set;
		rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, reason_code);
		return 0;
	}
}

int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb)
{
	struct ieee80211_hdr_3addr *delba = NULL;
	union delba_param_set *del_ba_param_set = NULL;
	u8 *dst = NULL;

	if (skb->len < sizeof(struct ieee80211_hdr_3addr) + 6) {
		netdev_warn(ieee->dev, "Invalid skb len in DELBA(%d / %d)\n",
			    (int)skb->len,
			    (int)(sizeof(struct ieee80211_hdr_3addr) + 6));
		return -1;
	}

	if (!ieee->current_network.qos_data.active ||
	    !ieee->ht_info->current_ht_support) {
		netdev_warn(ieee->dev,
			    "received DELBA while QOS or HT is not supported(%d, %d)\n",
			    ieee->current_network. qos_data.active,
			    ieee->ht_info->current_ht_support);
		return -1;
	}

#ifdef VERBOSE_DEBUG
	print_hex_dump_bytes("%s: ", DUMP_PREFIX_NONE, skb->data,
			     __func__, skb->len);
#endif
	delba = (struct ieee80211_hdr_3addr *)skb->data;
	dst = (u8 *)(&delba->addr2[0]);
	del_ba_param_set = (union delba_param_set *)&delba->seq_ctrl + 2;

	if (del_ba_param_set->field.initiator == 1) {
		struct rx_ts_record *ts;

		if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
			   (u8)del_ba_param_set->field.tid, RX_DIR, false)) {
			netdev_warn(ieee->dev,
				    "%s(): can't get TS for RXTS. dst:%pM TID:%d\n",
				    __func__, dst,
				    (u8)del_ba_param_set->field.tid);
			return -1;
		}

		rx_ts_delete_ba(ieee, ts);
	} else {
		struct tx_ts_record *ts;

		if (!rtllib_get_ts(ieee, (struct ts_common_info **)&ts, dst,
			   (u8)del_ba_param_set->field.tid, TX_DIR, false)) {
			netdev_warn(ieee->dev, "%s(): can't get TS for TXTS\n",
				    __func__);
			return -1;
		}

		ts->using_ba = false;
		ts->add_ba_req_in_progress = false;
		ts->add_ba_req_delayed = false;
		del_timer_sync(&ts->ts_add_ba_timer);
		tx_ts_delete_ba(ieee, ts);
	}
	return 0;
}

void rtllib_ts_init_add_ba(struct rtllib_device *ieee, struct tx_ts_record *ts,
			   u8 policy, u8	overwrite_pending)
{
	struct ba_record *ba = &ts->tx_pending_ba_record;

	if (ba->b_valid && !overwrite_pending)
		return;

	deactivate_ba_entry(ieee, ba);

	ba->dialog_token++;
	ba->ba_param_set.field.amsdu_support = 0;
	ba->ba_param_set.field.ba_policy = policy;
	ba->ba_param_set.field.tid = ts->ts_common_info.tspec.ts_id;
	ba->ba_param_set.field.buffer_size = 32;
	ba->ba_timeout_value = 0;
	ba->ba_start_seq_ctrl.field.seq_num = (ts->tx_cur_seq + 3) % 4096;

	activate_ba_entry(ba, BA_SETUP_TIMEOUT);

	rtllib_send_ADDBAReq(ieee, ts->ts_common_info.addr, ba);
}

void rtllib_ts_init_del_ba(struct rtllib_device *ieee,
			   struct ts_common_info *ts_common_info,
			   enum tr_select TxRxSelect)
{
	if (TxRxSelect == TX_DIR) {
		struct tx_ts_record *ts =
			 (struct tx_ts_record *)ts_common_info;

		if (tx_ts_delete_ba(ieee, ts))
			rtllib_send_DELBA(ieee, ts_common_info->addr,
					  (ts->tx_admitted_ba_record.b_valid) ?
					 (&ts->tx_admitted_ba_record) :
					(&ts->tx_pending_ba_record),
					 TxRxSelect, DELBA_REASON_END_BA);
	} else if (TxRxSelect == RX_DIR) {
		struct rx_ts_record *ts =
				 (struct rx_ts_record *)ts_common_info;
		if (rx_ts_delete_ba(ieee, ts))
			rtllib_send_DELBA(ieee, ts_common_info->addr,
					  &ts->rx_admitted_ba_record,
					  TxRxSelect, DELBA_REASON_END_BA);
	}
}

void rtllib_ba_setup_timeout(struct timer_list *t)
{
	struct tx_ts_record *ts = from_timer(ts, t,
					      tx_pending_ba_record.timer);

	ts->add_ba_req_in_progress = false;
	ts->add_ba_req_delayed = true;
	ts->tx_pending_ba_record.b_valid = false;
}

void rtllib_tx_ba_inact_timeout(struct timer_list *t)
{
	struct tx_ts_record *ts = from_timer(ts, t,
					      tx_admitted_ba_record.timer);
	struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
				     tx_ts_records[ts->num]);
	tx_ts_delete_ba(ieee, ts);
	rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
			  &ts->tx_admitted_ba_record, TX_DIR,
			  DELBA_REASON_TIMEOUT);
}

void rtllib_rx_ba_inact_timeout(struct timer_list *t)
{
	struct rx_ts_record *ts = from_timer(ts, t,
					      rx_admitted_ba_record.timer);
	struct rtllib_device *ieee = container_of(ts, struct rtllib_device,
				     rx_ts_records[ts->num]);

	rx_ts_delete_ba(ieee, ts);
	rtllib_send_DELBA(ieee, ts->ts_common_info.addr,
			  &ts->rx_admitted_ba_record, RX_DIR,
			  DELBA_REASON_TIMEOUT);
}
