// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2018-2019  Realtek Corporation
 */

#include "main.h"
#include "reg.h"
#include "fw.h"
#include "ps.h"
#include "mac.h"
#include "coex.h"
#include "debug.h"

static int rtw_ips_pwr_up(struct rtw_dev *rtwdev)
{
	int ret;

	ret = rtw_core_start(rtwdev);
	if (ret)
		rtw_err(rtwdev, "leave idle state failed\n");

	rtw_set_channel(rtwdev);
	clear_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags);

	return ret;
}

int rtw_enter_ips(struct rtw_dev *rtwdev)
{
	set_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags);

	rtw_coex_ips_notify(rtwdev, COEX_IPS_ENTER);

	rtw_core_stop(rtwdev);
	rtw_hci_link_ps(rtwdev, true);

	return 0;
}

static void rtw_restore_port_cfg_iter(void *data, u8 *mac,
				      struct ieee80211_vif *vif)
{
	struct rtw_dev *rtwdev = data;
	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
	u32 config = ~0;

	rtw_vif_port_config(rtwdev, rtwvif, config);
}

int rtw_leave_ips(struct rtw_dev *rtwdev)
{
	int ret;

	rtw_hci_link_ps(rtwdev, false);

	ret = rtw_ips_pwr_up(rtwdev);
	if (ret) {
		rtw_err(rtwdev, "failed to leave ips state\n");
		return ret;
	}

	rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev);

	rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE);

	return 0;
}

void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter)
{
	u8 request, confirm, polling;
	u8 polling_cnt;
	u8 retry_cnt = 0;

	for (retry_cnt = 0; retry_cnt < 3; retry_cnt++) {
		request = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
		confirm = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr);

		/* toggle to request power mode, others remain 0 */
		request ^= request | BIT_RPWM_TOGGLE;
		if (!enter) {
			request |= POWER_MODE_ACK;
		} else {
			request |= POWER_MODE_LCLK;
			if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG)
				request |= POWER_MODE_PG;
		}

		rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, request);

		if (enter)
			return;

		/* check confirm power mode has left power save state */
		for (polling_cnt = 0; polling_cnt < 50; polling_cnt++) {
			polling = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr);
			if ((polling ^ confirm) & BIT_RPWM_TOGGLE)
				return;
			udelay(100);
		}

		/* in case of fw/hw missed the request, retry */
		rtw_warn(rtwdev, "failed to leave deep PS, retry=%d\n",
			 retry_cnt);
	}

	/* Hit here means that driver failed to change hardware power mode to
	 * active state after retry 3 times. If the power state is locked at
	 * Deep sleep, most of the hardware circuits is not working, even
	 * register read/write. It should be treated as fatal error and
	 * requires an entire analysis about the firmware/hardware
	 */
	WARN(1, "Hardware power state locked\n");
}
EXPORT_SYMBOL(rtw_power_mode_change);

static void __rtw_leave_lps_deep(struct rtw_dev *rtwdev)
{
	rtw_hci_deep_ps(rtwdev, false);
}

static void rtw_fw_leave_lps_state_check(struct rtw_dev *rtwdev)
{
	int i;

	/* Driver needs to wait for firmware to leave LPS state
	 * successfully. Firmware will send null packet to inform AP,
	 * and see if AP sends an ACK back, then firmware will restore
	 * the REG_TCR register.
	 *
	 * If driver does not wait for firmware, null packet with
	 * PS bit could be sent due to incorrect REG_TCR setting.
	 *
	 * In our test, 100ms should be enough for firmware to finish
	 * the flow. If REG_TCR Register is still incorrect after 100ms,
	 * just modify it directly, and throw a warn message.
	 */
	for (i = 0 ; i < LEAVE_LPS_TRY_CNT; i++) {
		if (rtw_read32_mask(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN) == 0)
			return;
		msleep(20);
	}

	rtw_write32_mask(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN, 0);
	rtw_warn(rtwdev, "firmware failed to restore hardware setting\n");
}

static void rtw_leave_lps_core(struct rtw_dev *rtwdev)
{
	struct rtw_lps_conf *conf = &rtwdev->lps_conf;

	conf->state = RTW_ALL_ON;
	conf->awake_interval = 1;
	conf->rlbm = 0;
	conf->smart_ps = 0;

	rtw_hci_link_ps(rtwdev, false);
	rtw_fw_set_pwr_mode(rtwdev);
	rtw_fw_leave_lps_state_check(rtwdev);

	clear_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags);

	rtw_coex_lps_notify(rtwdev, COEX_LPS_DISABLE);
}

static void __rtw_enter_lps_deep(struct rtw_dev *rtwdev)
{
	if (rtwdev->lps_conf.deep_mode == LPS_DEEP_MODE_NONE)
		return;

	if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) {
		rtw_dbg(rtwdev, RTW_DBG_PS,
			"Should enter LPS before entering deep PS\n");
		return;
	}

	if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG)
		rtw_fw_set_pg_info(rtwdev);

	rtw_hci_deep_ps(rtwdev, true);
}

static void rtw_enter_lps_core(struct rtw_dev *rtwdev)
{
	struct rtw_lps_conf *conf = &rtwdev->lps_conf;

	conf->state = RTW_RF_OFF;
	conf->awake_interval = 1;
	conf->rlbm = 1;
	conf->smart_ps = 2;

	rtw_coex_lps_notify(rtwdev, COEX_LPS_ENABLE);

	rtw_fw_set_pwr_mode(rtwdev);
	rtw_hci_link_ps(rtwdev, true);

	set_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags);
}

static void __rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id)
{
	struct rtw_lps_conf *conf = &rtwdev->lps_conf;

	if (test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags))
		return;

	conf->mode = RTW_MODE_LPS;
	conf->port_id = port_id;

	rtw_enter_lps_core(rtwdev);
}

static void __rtw_leave_lps(struct rtw_dev *rtwdev)
{
	struct rtw_lps_conf *conf = &rtwdev->lps_conf;

	if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) {
		rtw_dbg(rtwdev, RTW_DBG_PS,
			"Should leave deep PS before leaving LPS\n");
		__rtw_leave_lps_deep(rtwdev);
	}

	if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags))
		return;

	conf->mode = RTW_MODE_ACTIVE;

	rtw_leave_lps_core(rtwdev);
}

void rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id)
{
	lockdep_assert_held(&rtwdev->mutex);

	if (rtwdev->coex.stat.wl_force_lps_ctrl)
		return;

	__rtw_enter_lps(rtwdev, port_id);
	__rtw_enter_lps_deep(rtwdev);
}

void rtw_leave_lps(struct rtw_dev *rtwdev)
{
	lockdep_assert_held(&rtwdev->mutex);

	__rtw_leave_lps_deep(rtwdev);
	__rtw_leave_lps(rtwdev);
}

void rtw_leave_lps_deep(struct rtw_dev *rtwdev)
{
	lockdep_assert_held(&rtwdev->mutex);

	__rtw_leave_lps_deep(rtwdev);
}
