// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
 * This file contains the main functions related to Initiator Node Attributes.
 *
 * (c) Copyright 2007-2013 Datera, Inc.
 *
 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
 *
 ******************************************************************************/

#include <target/target_core_base.h>

#include <target/iscsi/iscsi_target_core.h>
#include "iscsi_target_device.h"
#include "iscsi_target_tpg.h"
#include "iscsi_target_util.h"
#include "iscsi_target_nodeattrib.h"

static inline char *iscsit_na_get_initiatorname(
	struct iscsi_node_acl *nacl)
{
	struct se_node_acl *se_nacl = &nacl->se_node_acl;

	return &se_nacl->initiatorname[0];
}

void iscsit_set_default_node_attribues(
	struct iscsi_node_acl *acl,
	struct iscsi_portal_group *tpg)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;

	a->dataout_timeout = NA_DATAOUT_TIMEOUT;
	a->dataout_timeout_retries = NA_DATAOUT_TIMEOUT_RETRIES;
	a->nopin_timeout = NA_NOPIN_TIMEOUT;
	a->nopin_response_timeout = NA_NOPIN_RESPONSE_TIMEOUT;
	a->random_datain_pdu_offsets = NA_RANDOM_DATAIN_PDU_OFFSETS;
	a->random_datain_seq_offsets = NA_RANDOM_DATAIN_SEQ_OFFSETS;
	a->random_r2t_offsets = NA_RANDOM_R2T_OFFSETS;
	a->default_erl = tpg->tpg_attrib.default_erl;
}

int iscsit_na_dataout_timeout(
	struct iscsi_node_acl *acl,
	u32 dataout_timeout)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;

	if (dataout_timeout > NA_DATAOUT_TIMEOUT_MAX) {
		pr_err("Requested DataOut Timeout %u larger than"
			" maximum %u\n", dataout_timeout,
			NA_DATAOUT_TIMEOUT_MAX);
		return -EINVAL;
	} else if (dataout_timeout < NA_DATAOUT_TIMEOUT_MIX) {
		pr_err("Requested DataOut Timeout %u smaller than"
			" minimum %u\n", dataout_timeout,
			NA_DATAOUT_TIMEOUT_MIX);
		return -EINVAL;
	}

	a->dataout_timeout = dataout_timeout;
	pr_debug("Set DataOut Timeout to %u for Initiator Node"
		" %s\n", a->dataout_timeout, iscsit_na_get_initiatorname(acl));

	return 0;
}

int iscsit_na_dataout_timeout_retries(
	struct iscsi_node_acl *acl,
	u32 dataout_timeout_retries)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;

	if (dataout_timeout_retries > NA_DATAOUT_TIMEOUT_RETRIES_MAX) {
		pr_err("Requested DataOut Timeout Retries %u larger"
			" than maximum %u", dataout_timeout_retries,
				NA_DATAOUT_TIMEOUT_RETRIES_MAX);
		return -EINVAL;
	} else if (dataout_timeout_retries < NA_DATAOUT_TIMEOUT_RETRIES_MIN) {
		pr_err("Requested DataOut Timeout Retries %u smaller"
			" than minimum %u", dataout_timeout_retries,
				NA_DATAOUT_TIMEOUT_RETRIES_MIN);
		return -EINVAL;
	}

	a->dataout_timeout_retries = dataout_timeout_retries;
	pr_debug("Set DataOut Timeout Retries to %u for"
		" Initiator Node %s\n", a->dataout_timeout_retries,
		iscsit_na_get_initiatorname(acl));

	return 0;
}

int iscsit_na_nopin_timeout(
	struct iscsi_node_acl *acl,
	u32 nopin_timeout)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;
	struct iscsi_session *sess;
	struct iscsi_conn *conn;
	struct se_node_acl *se_nacl = &a->nacl->se_node_acl;
	struct se_session *se_sess;
	u32 orig_nopin_timeout = a->nopin_timeout;

	if (nopin_timeout > NA_NOPIN_TIMEOUT_MAX) {
		pr_err("Requested NopIn Timeout %u larger than maximum"
			" %u\n", nopin_timeout, NA_NOPIN_TIMEOUT_MAX);
		return -EINVAL;
	} else if ((nopin_timeout < NA_NOPIN_TIMEOUT_MIN) &&
		   (nopin_timeout != 0)) {
		pr_err("Requested NopIn Timeout %u smaller than"
			" minimum %u and not 0\n", nopin_timeout,
			NA_NOPIN_TIMEOUT_MIN);
		return -EINVAL;
	}

	a->nopin_timeout = nopin_timeout;
	pr_debug("Set NopIn Timeout to %u for Initiator"
		" Node %s\n", a->nopin_timeout,
		iscsit_na_get_initiatorname(acl));
	/*
	 * Reenable disabled nopin_timeout timer for all iSCSI connections.
	 */
	if (!orig_nopin_timeout) {
		spin_lock_bh(&se_nacl->nacl_sess_lock);
		se_sess = se_nacl->nacl_sess;
		if (se_sess) {
			sess = se_sess->fabric_sess_ptr;

			spin_lock(&sess->conn_lock);
			list_for_each_entry(conn, &sess->sess_conn_list,
					conn_list) {
				if (conn->conn_state !=
						TARG_CONN_STATE_LOGGED_IN)
					continue;

				spin_lock(&conn->nopin_timer_lock);
				__iscsit_start_nopin_timer(conn);
				spin_unlock(&conn->nopin_timer_lock);
			}
			spin_unlock(&sess->conn_lock);
		}
		spin_unlock_bh(&se_nacl->nacl_sess_lock);
	}

	return 0;
}

int iscsit_na_nopin_response_timeout(
	struct iscsi_node_acl *acl,
	u32 nopin_response_timeout)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;

	if (nopin_response_timeout > NA_NOPIN_RESPONSE_TIMEOUT_MAX) {
		pr_err("Requested NopIn Response Timeout %u larger"
			" than maximum %u\n", nopin_response_timeout,
				NA_NOPIN_RESPONSE_TIMEOUT_MAX);
		return -EINVAL;
	} else if (nopin_response_timeout < NA_NOPIN_RESPONSE_TIMEOUT_MIN) {
		pr_err("Requested NopIn Response Timeout %u smaller"
			" than minimum %u\n", nopin_response_timeout,
				NA_NOPIN_RESPONSE_TIMEOUT_MIN);
		return -EINVAL;
	}

	a->nopin_response_timeout = nopin_response_timeout;
	pr_debug("Set NopIn Response Timeout to %u for"
		" Initiator Node %s\n", a->nopin_timeout,
		iscsit_na_get_initiatorname(acl));

	return 0;
}

int iscsit_na_random_datain_pdu_offsets(
	struct iscsi_node_acl *acl,
	u32 random_datain_pdu_offsets)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;

	if (random_datain_pdu_offsets != 0 && random_datain_pdu_offsets != 1) {
		pr_err("Requested Random DataIN PDU Offsets: %u not"
			" 0 or 1\n", random_datain_pdu_offsets);
		return -EINVAL;
	}

	a->random_datain_pdu_offsets = random_datain_pdu_offsets;
	pr_debug("Set Random DataIN PDU Offsets to %u for"
		" Initiator Node %s\n", a->random_datain_pdu_offsets,
		iscsit_na_get_initiatorname(acl));

	return 0;
}

int iscsit_na_random_datain_seq_offsets(
	struct iscsi_node_acl *acl,
	u32 random_datain_seq_offsets)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;

	if (random_datain_seq_offsets != 0 && random_datain_seq_offsets != 1) {
		pr_err("Requested Random DataIN Sequence Offsets: %u"
			" not 0 or 1\n", random_datain_seq_offsets);
		return -EINVAL;
	}

	a->random_datain_seq_offsets = random_datain_seq_offsets;
	pr_debug("Set Random DataIN Sequence Offsets to %u for"
		" Initiator Node %s\n", a->random_datain_seq_offsets,
		iscsit_na_get_initiatorname(acl));

	return 0;
}

int iscsit_na_random_r2t_offsets(
	struct iscsi_node_acl *acl,
	u32 random_r2t_offsets)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;

	if (random_r2t_offsets != 0 && random_r2t_offsets != 1) {
		pr_err("Requested Random R2T Offsets: %u not"
			" 0 or 1\n", random_r2t_offsets);
		return -EINVAL;
	}

	a->random_r2t_offsets = random_r2t_offsets;
	pr_debug("Set Random R2T Offsets to %u for"
		" Initiator Node %s\n", a->random_r2t_offsets,
		iscsit_na_get_initiatorname(acl));

	return 0;
}

int iscsit_na_default_erl(
	struct iscsi_node_acl *acl,
	u32 default_erl)
{
	struct iscsi_node_attrib *a = &acl->node_attrib;

	if (default_erl != 0 && default_erl != 1 && default_erl != 2) {
		pr_err("Requested default ERL: %u not 0, 1, or 2\n",
				default_erl);
		return -EINVAL;
	}

	a->default_erl = default_erl;
	pr_debug("Set use ERL0 flag to %u for Initiator"
		" Node %s\n", a->default_erl,
		iscsit_na_get_initiatorname(acl));

	return 0;
}
