/*
 * Aic94xx SAS/SATA DDB management
 *
 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
 *
 * This file is licensed under GPLv2.
 *
 * This file is part of the aic94xx driver.
 *
 * The aic94xx driver is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 *
 * The aic94xx driver is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the aic94xx driver; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * $Id: //depot/aic94xx/aic94xx_dev.c#21 $
 */

#include "aic94xx.h"
#include "aic94xx_hwi.h"
#include "aic94xx_reg.h"
#include "aic94xx_sas.h"

#define FIND_FREE_DDB(_ha) find_first_zero_bit((_ha)->hw_prof.ddb_bitmap, \
					       (_ha)->hw_prof.max_ddbs)
#define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
#define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)

static inline int asd_get_ddb(struct asd_ha_struct *asd_ha)
{
	unsigned long flags;
	int ddb, i;

	spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
	ddb = FIND_FREE_DDB(asd_ha);
	if (ddb >= asd_ha->hw_prof.max_ddbs) {
		ddb = -ENOMEM;
		spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
		goto out;
	}
	SET_DDB(ddb, asd_ha);
	spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);

	for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4)
		asd_ddbsite_write_dword(asd_ha, ddb, i, 0);
out:
	return ddb;
}

#define INIT_CONN_TAG   offsetof(struct asd_ddb_ssp_smp_target_port, init_conn_tag)
#define DEST_SAS_ADDR   offsetof(struct asd_ddb_ssp_smp_target_port, dest_sas_addr)
#define SEND_QUEUE_HEAD offsetof(struct asd_ddb_ssp_smp_target_port, send_queue_head)
#define DDB_TYPE        offsetof(struct asd_ddb_ssp_smp_target_port, ddb_type)
#define CONN_MASK       offsetof(struct asd_ddb_ssp_smp_target_port, conn_mask)
#define DDB_TARG_FLAGS  offsetof(struct asd_ddb_ssp_smp_target_port, flags)
#define DDB_TARG_FLAGS2 offsetof(struct asd_ddb_stp_sata_target_port, flags2)
#define EXEC_QUEUE_TAIL offsetof(struct asd_ddb_ssp_smp_target_port, exec_queue_tail)
#define SEND_QUEUE_TAIL offsetof(struct asd_ddb_ssp_smp_target_port, send_queue_tail)
#define SISTER_DDB      offsetof(struct asd_ddb_ssp_smp_target_port, sister_ddb)
#define MAX_CCONN       offsetof(struct asd_ddb_ssp_smp_target_port, max_concurrent_conn)
#define NUM_CTX         offsetof(struct asd_ddb_ssp_smp_target_port, num_contexts)
#define ATA_CMD_SCBPTR  offsetof(struct asd_ddb_stp_sata_target_port, ata_cmd_scbptr)
#define SATA_TAG_ALLOC_MASK offsetof(struct asd_ddb_stp_sata_target_port, sata_tag_alloc_mask)
#define NUM_SATA_TAGS   offsetof(struct asd_ddb_stp_sata_target_port, num_sata_tags)
#define SATA_STATUS     offsetof(struct asd_ddb_stp_sata_target_port, sata_status)
#define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr)
#define ITNL_TIMEOUT    offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout)

static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
{
	unsigned long flags;

	if (!ddb || ddb >= 0xFFFF)
		return;
	asd_ddbsite_write_byte(asd_ha, ddb, DDB_TYPE, DDB_TYPE_UNUSED);
	spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
	CLEAR_DDB(ddb, asd_ha);
	spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
}

static inline void asd_set_ddb_type(struct domain_device *dev)
{
	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
	int ddb = (int) (unsigned long) dev->lldd_dev;

	if (dev->dev_type == SATA_PM_PORT)
		asd_ddbsite_write_byte(asd_ha,ddb, DDB_TYPE, DDB_TYPE_PM_PORT);
	else if (dev->tproto)
		asd_ddbsite_write_byte(asd_ha,ddb, DDB_TYPE, DDB_TYPE_TARGET);
	else
		asd_ddbsite_write_byte(asd_ha,ddb,DDB_TYPE,DDB_TYPE_INITIATOR);
}

static int asd_init_sata_tag_ddb(struct domain_device *dev)
{
	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
	int ddb, i;

	ddb = asd_get_ddb(asd_ha);
	if (ddb < 0)
		return ddb;

	for (i = 0; i < sizeof(struct asd_ddb_sata_tag); i += 2)
		asd_ddbsite_write_word(asd_ha, ddb, i, 0xFFFF);

	asd_ddbsite_write_word(asd_ha, (int) (unsigned long) dev->lldd_dev,
			       SISTER_DDB, ddb);
	return 0;
}

static inline int asd_init_sata(struct domain_device *dev)
{
	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
	int ddb = (int) (unsigned long) dev->lldd_dev;
	u32 qdepth = 0;
	int res = 0;

	asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF);
	if ((dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM_PORT) &&
	    dev->sata_dev.identify_device &&
	    dev->sata_dev.identify_device[10] != 0) {
		u16 w75 = le16_to_cpu(dev->sata_dev.identify_device[75]);
		u16 w76 = le16_to_cpu(dev->sata_dev.identify_device[76]);

		if (w76 & 0x100) /* NCQ? */
			qdepth = (w75 & 0x1F) + 1;
		asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK,
					(1<<qdepth)-1);
		asd_ddbsite_write_byte(asd_ha, ddb, NUM_SATA_TAGS, qdepth);
	}
	if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM ||
	    dev->dev_type == SATA_PM_PORT) {
		struct dev_to_host_fis *fis = (struct dev_to_host_fis *)
			dev->frame_rcvd;
		asd_ddbsite_write_byte(asd_ha, ddb, SATA_STATUS, fis->status);
	}
	asd_ddbsite_write_word(asd_ha, ddb, NCQ_DATA_SCB_PTR, 0xFFFF);
	if (qdepth > 0)
		res = asd_init_sata_tag_ddb(dev);
	return res;
}

static int asd_init_target_ddb(struct domain_device *dev)
{
	int ddb, i;
	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
	u8 flags = 0;

	ddb = asd_get_ddb(asd_ha);
	if (ddb < 0)
		return ddb;

	dev->lldd_dev = (void *) (unsigned long) ddb;

	asd_ddbsite_write_byte(asd_ha, ddb, 0, DDB_TP_CONN_TYPE);
	asd_ddbsite_write_byte(asd_ha, ddb, 1, 0);
	asd_ddbsite_write_word(asd_ha, ddb, INIT_CONN_TAG, 0xFFFF);
	for (i = 0; i < SAS_ADDR_SIZE; i++)
		asd_ddbsite_write_byte(asd_ha, ddb, DEST_SAS_ADDR+i,
				       dev->sas_addr[i]);
	asd_ddbsite_write_word(asd_ha, ddb, SEND_QUEUE_HEAD, 0xFFFF);
	asd_set_ddb_type(dev);
	asd_ddbsite_write_byte(asd_ha, ddb, CONN_MASK, dev->port->phy_mask);
	if (dev->port->oob_mode != SATA_OOB_MODE) {
		flags |= OPEN_REQUIRED;
		if ((dev->dev_type == SATA_DEV) ||
		    (dev->tproto & SAS_PROTO_STP)) {
			struct smp_resp *rps_resp = &dev->sata_dev.rps_resp;
			if (rps_resp->frame_type == SMP_RESPONSE &&
			    rps_resp->function == SMP_REPORT_PHY_SATA &&
			    rps_resp->result == SMP_RESP_FUNC_ACC) {
				if (rps_resp->rps.affil_valid)
					flags |= STP_AFFIL_POL;
				if (rps_resp->rps.affil_supp)
					flags |= SUPPORTS_AFFIL;
			}
		} else {
			flags |= CONCURRENT_CONN_SUPP;
			if (!dev->parent &&
			    (dev->dev_type == EDGE_DEV ||
			     dev->dev_type == FANOUT_DEV))
				asd_ddbsite_write_byte(asd_ha, ddb, MAX_CCONN,
						       4);
			else
				asd_ddbsite_write_byte(asd_ha, ddb, MAX_CCONN,
						       dev->pathways);
			asd_ddbsite_write_byte(asd_ha, ddb, NUM_CTX, 1);
		}
	}
	if (dev->dev_type == SATA_PM)
		flags |= SATA_MULTIPORT;
	asd_ddbsite_write_byte(asd_ha, ddb, DDB_TARG_FLAGS, flags);

	flags = 0;
	if (dev->tproto & SAS_PROTO_STP)
		flags |= STP_CL_POL_NO_TX;
	asd_ddbsite_write_byte(asd_ha, ddb, DDB_TARG_FLAGS2, flags);

	asd_ddbsite_write_word(asd_ha, ddb, EXEC_QUEUE_TAIL, 0xFFFF);
	asd_ddbsite_write_word(asd_ha, ddb, SEND_QUEUE_TAIL, 0xFFFF);
	asd_ddbsite_write_word(asd_ha, ddb, SISTER_DDB, 0xFFFF);

	if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTO_STP)) {
		i = asd_init_sata(dev);
		if (i < 0) {
			asd_free_ddb(asd_ha, ddb);
			return i;
		}
	}

	if (dev->dev_type == SAS_END_DEV) {
		struct sas_end_device *rdev = rphy_to_end_device(dev->rphy);
		if (rdev->I_T_nexus_loss_timeout > 0)
			asd_ddbsite_write_word(asd_ha, ddb, ITNL_TIMEOUT,
					       min(rdev->I_T_nexus_loss_timeout,
						   (u16)ITNL_TIMEOUT_CONST));
		else
			asd_ddbsite_write_word(asd_ha, ddb, ITNL_TIMEOUT,
					       (u16)ITNL_TIMEOUT_CONST);
	}
	return 0;
}

static int asd_init_sata_pm_table_ddb(struct domain_device *dev)
{
	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
	int ddb, i;

	ddb = asd_get_ddb(asd_ha);
	if (ddb < 0)
		return ddb;

	for (i = 0; i < 32; i += 2)
		asd_ddbsite_write_word(asd_ha, ddb, i, 0xFFFF);

	asd_ddbsite_write_word(asd_ha, (int) (unsigned long) dev->lldd_dev,
			       SISTER_DDB, ddb);

	return 0;
}

#define PM_PORT_FLAGS offsetof(struct asd_ddb_sata_pm_port, pm_port_flags)
#define PARENT_DDB    offsetof(struct asd_ddb_sata_pm_port, parent_ddb)

/**
 * asd_init_sata_pm_port_ddb -- SATA Port Multiplier Port
 * dev: pointer to domain device
 *
 * For SATA Port Multiplier Ports we need to allocate one SATA Port
 * Multiplier Port DDB and depending on whether the target on it
 * supports SATA II NCQ, one SATA Tag DDB.
 */
static int asd_init_sata_pm_port_ddb(struct domain_device *dev)
{
	int ddb, i, parent_ddb, pmtable_ddb;
	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
	u8  flags;

	ddb = asd_get_ddb(asd_ha);
	if (ddb < 0)
		return ddb;

	asd_set_ddb_type(dev);
	flags = (dev->sata_dev.port_no << 4) | PM_PORT_SET;
	asd_ddbsite_write_byte(asd_ha, ddb, PM_PORT_FLAGS, flags);
	asd_ddbsite_write_word(asd_ha, ddb, SISTER_DDB, 0xFFFF);
	asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF);
	asd_init_sata(dev);

	parent_ddb = (int) (unsigned long) dev->parent->lldd_dev;
	asd_ddbsite_write_word(asd_ha, ddb, PARENT_DDB, parent_ddb);
	pmtable_ddb = asd_ddbsite_read_word(asd_ha, parent_ddb, SISTER_DDB);
	asd_ddbsite_write_word(asd_ha, pmtable_ddb, dev->sata_dev.port_no,ddb);

	if (asd_ddbsite_read_byte(asd_ha, ddb, NUM_SATA_TAGS) > 0) {
		i = asd_init_sata_tag_ddb(dev);
		if (i < 0) {
			asd_free_ddb(asd_ha, ddb);
			return i;
		}
	}
	return 0;
}

static int asd_init_initiator_ddb(struct domain_device *dev)
{
	return -ENODEV;
}

/**
 * asd_init_sata_pm_ddb -- SATA Port Multiplier
 * dev: pointer to domain device
 *
 * For STP and direct-attached SATA Port Multipliers we need
 * one target port DDB entry and one SATA PM table DDB entry.
 */
static int asd_init_sata_pm_ddb(struct domain_device *dev)
{
	int res = 0;

	res = asd_init_target_ddb(dev);
	if (res)
		goto out;
	res = asd_init_sata_pm_table_ddb(dev);
	if (res)
		asd_free_ddb(dev->port->ha->lldd_ha,
			     (int) (unsigned long) dev->lldd_dev);
out:
	return res;
}

int asd_dev_found(struct domain_device *dev)
{
	int res = 0;

	switch (dev->dev_type) {
	case SATA_PM:
		res = asd_init_sata_pm_ddb(dev);
		break;
	case SATA_PM_PORT:
		res = asd_init_sata_pm_port_ddb(dev);
		break;
	default:
		if (dev->tproto)
			res = asd_init_target_ddb(dev);
		else
			res = asd_init_initiator_ddb(dev);
	}
	return res;
}

void asd_dev_gone(struct domain_device *dev)
{
	int ddb, sister_ddb;
	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;

	ddb = (int) (unsigned long) dev->lldd_dev;
	sister_ddb = asd_ddbsite_read_word(asd_ha, ddb, SISTER_DDB);

	if (sister_ddb != 0xFFFF)
		asd_free_ddb(asd_ha, sister_ddb);
	asd_free_ddb(asd_ha, ddb);
	dev->lldd_dev = NULL;
}
