/*
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.GPL.
 *
 * BSD LICENSE
 *
 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "isci.h"
#include "host.h"
#include "phy.h"
#include "scu_event_codes.h"
#include "probe_roms.h"

/* Maximum arbitration wait time in micro-seconds */
#define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME  (700)

enum sas_linkrate sci_phy_linkrate(struct scic_sds_phy *sci_phy)
{
	return sci_phy->max_negotiated_speed;
}

/*
 * *****************************************************************************
 * * SCIC SDS PHY Internal Methods
 * ***************************************************************************** */

/**
 * This method will initialize the phy transport layer registers
 * @sci_phy:
 * @transport_layer_registers
 *
 * enum sci_status
 */
static enum sci_status scic_sds_phy_transport_layer_initialization(
	struct scic_sds_phy *sci_phy,
	struct scu_transport_layer_registers __iomem *transport_layer_registers)
{
	u32 tl_control;

	sci_phy->transport_layer_registers = transport_layer_registers;

	writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX,
		&sci_phy->transport_layer_registers->stp_rni);

	/*
	 * Hardware team recommends that we enable the STP prefetch for all
	 * transports
	 */
	tl_control = readl(&sci_phy->transport_layer_registers->control);
	tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
	writel(tl_control, &sci_phy->transport_layer_registers->control);

	return SCI_SUCCESS;
}

/**
 * This method will initialize the phy link layer registers
 * @sci_phy:
 * @link_layer_registers:
 *
 * enum sci_status
 */
static enum sci_status
scic_sds_phy_link_layer_initialization(struct scic_sds_phy *sci_phy,
				       struct scu_link_layer_registers __iomem *link_layer_registers)
{
	struct scic_sds_controller *scic =
		sci_phy->owning_port->owning_controller;
	int phy_idx = sci_phy->phy_index;
	struct sci_phy_user_params *phy_user =
		&scic->user_parameters.sds1.phys[phy_idx];
	struct sci_phy_oem_params *phy_oem =
		&scic->oem_parameters.sds1.phys[phy_idx];
	u32 phy_configuration;
	struct scic_phy_cap phy_cap;
	u32 parity_check = 0;
	u32 parity_count = 0;
	u32 llctl, link_rate;
	u32 clksm_value = 0;

	sci_phy->link_layer_registers = link_layer_registers;

	/* Set our IDENTIFY frame data */
	#define SCI_END_DEVICE 0x01

	writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) |
	       SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) |
	       SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
	       SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
	       SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE),
	       &sci_phy->link_layer_registers->transmit_identification);

	/* Write the device SAS Address */
	writel(0xFEDCBA98,
	       &sci_phy->link_layer_registers->sas_device_name_high);
	writel(phy_idx, &sci_phy->link_layer_registers->sas_device_name_low);

	/* Write the source SAS Address */
	writel(phy_oem->sas_address.high,
		&sci_phy->link_layer_registers->source_sas_address_high);
	writel(phy_oem->sas_address.low,
		&sci_phy->link_layer_registers->source_sas_address_low);

	/* Clear and Set the PHY Identifier */
	writel(0, &sci_phy->link_layer_registers->identify_frame_phy_id);
	writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx),
		&sci_phy->link_layer_registers->identify_frame_phy_id);

	/* Change the initial state of the phy configuration register */
	phy_configuration =
		readl(&sci_phy->link_layer_registers->phy_configuration);

	/* Hold OOB state machine in reset */
	phy_configuration |=  SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
	writel(phy_configuration,
		&sci_phy->link_layer_registers->phy_configuration);

	/* Configure the SNW capabilities */
	phy_cap.all = 0;
	phy_cap.start = 1;
	phy_cap.gen3_no_ssc = 1;
	phy_cap.gen2_no_ssc = 1;
	phy_cap.gen1_no_ssc = 1;
	if (scic->oem_parameters.sds1.controller.do_enable_ssc == true) {
		phy_cap.gen3_ssc = 1;
		phy_cap.gen2_ssc = 1;
		phy_cap.gen1_ssc = 1;
	}

	/*
	 * The SAS specification indicates that the phy_capabilities that
	 * are transmitted shall have an even parity.  Calculate the parity. */
	parity_check = phy_cap.all;
	while (parity_check != 0) {
		if (parity_check & 0x1)
			parity_count++;
		parity_check >>= 1;
	}

	/*
	 * If parity indicates there are an odd number of bits set, then
	 * set the parity bit to 1 in the phy capabilities. */
	if ((parity_count % 2) != 0)
		phy_cap.parity = 1;

	writel(phy_cap.all, &sci_phy->link_layer_registers->phy_capabilities);

	/* Set the enable spinup period but disable the ability to send
	 * notify enable spinup
	 */
	writel(SCU_ENSPINUP_GEN_VAL(COUNT,
			phy_user->notify_enable_spin_up_insertion_frequency),
		&sci_phy->link_layer_registers->notify_enable_spinup_control);

	/* Write the ALIGN Insertion Ferequency for connected phy and
	 * inpendent of connected state
	 */
	clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
			phy_user->in_connection_align_insertion_frequency);

	clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
			phy_user->align_insertion_frequency);

	writel(clksm_value, &sci_phy->link_layer_registers->clock_skew_management);

	/* @todo Provide a way to write this register correctly */
	writel(0x02108421,
		&sci_phy->link_layer_registers->afe_lookup_table_control);

	llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
		(u8)scic->user_parameters.sds1.no_outbound_task_timeout);

	switch(phy_user->max_speed_generation) {
	case SCIC_SDS_PARM_GEN3_SPEED:
		link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3;
		break;
	case SCIC_SDS_PARM_GEN2_SPEED:
		link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
		break;
	default:
		link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
		break;
	}
	llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
	writel(llctl, &sci_phy->link_layer_registers->link_layer_control);

	if (is_a0() || is_a2()) {
		/* Program the max ARB time for the PHY to 700us so we inter-operate with
		 * the PMC expander which shuts down PHYs if the expander PHY generates too
		 * many breaks.  This time value will guarantee that the initiator PHY will
		 * generate the break.
		 */
		writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
			&sci_phy->link_layer_registers->maximum_arbitration_wait_timer_timeout);
	}

	/*
	 * Set the link layer hang detection to 500ms (0x1F4) from its default
	 * value of 128ms.  Max value is 511 ms.
	 */
	writel(0x1F4, &sci_phy->link_layer_registers->link_layer_hang_detection_timeout);

	/* We can exit the initial state to the stopped state */
	sci_change_state(&sci_phy->sm, SCI_PHY_STOPPED);

	return SCI_SUCCESS;
}

static void phy_sata_timeout(unsigned long data)
{
	struct sci_timer *tmr = (struct sci_timer *)data;
	struct scic_sds_phy *sci_phy = container_of(tmr, typeof(*sci_phy), sata_timer);
	struct isci_host *ihost = scic_to_ihost(sci_phy->owning_port->owning_controller);
	unsigned long flags;

	spin_lock_irqsave(&ihost->scic_lock, flags);

	if (tmr->cancel)
		goto done;

	dev_dbg(sciphy_to_dev(sci_phy),
		 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
		 "timeout.\n",
		 __func__,
		 sci_phy);

	sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
done:
	spin_unlock_irqrestore(&ihost->scic_lock, flags);
}

/**
 * This method returns the port currently containing this phy. If the phy is
 *    currently contained by the dummy port, then the phy is considered to not
 *    be part of a port.
 * @sci_phy: This parameter specifies the phy for which to retrieve the
 *    containing port.
 *
 * This method returns a handle to a port that contains the supplied phy.
 * NULL This value is returned if the phy is not part of a real
 * port (i.e. it's contained in the dummy port). !NULL All other
 * values indicate a handle/pointer to the port containing the phy.
 */
struct scic_sds_port *phy_get_non_dummy_port(
	struct scic_sds_phy *sci_phy)
{
	if (scic_sds_port_get_index(sci_phy->owning_port) == SCIC_SDS_DUMMY_PORT)
		return NULL;

	return sci_phy->owning_port;
}

/**
 * This method will assign a port to the phy object.
 * @out]: sci_phy This parameter specifies the phy for which to assign a port
 *    object.
 *
 *
 */
void scic_sds_phy_set_port(
	struct scic_sds_phy *sci_phy,
	struct scic_sds_port *sci_port)
{
	sci_phy->owning_port = sci_port;

	if (sci_phy->bcn_received_while_port_unassigned) {
		sci_phy->bcn_received_while_port_unassigned = false;
		scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy);
	}
}

/**
 * This method will initialize the constructed phy
 * @sci_phy:
 * @link_layer_registers:
 *
 * enum sci_status
 */
enum sci_status scic_sds_phy_initialize(
	struct scic_sds_phy *sci_phy,
	struct scu_transport_layer_registers __iomem *transport_layer_registers,
	struct scu_link_layer_registers __iomem *link_layer_registers)
{
	/* Perfrom the initialization of the TL hardware */
	scic_sds_phy_transport_layer_initialization(
			sci_phy,
			transport_layer_registers);

	/* Perofrm the initialization of the PE hardware */
	scic_sds_phy_link_layer_initialization(sci_phy, link_layer_registers);

	/*
	 * There is nothing that needs to be done in this state just
	 * transition to the stopped state. */
	sci_change_state(&sci_phy->sm, SCI_PHY_STOPPED);

	return SCI_SUCCESS;
}

/**
 * This method assigns the direct attached device ID for this phy.
 *
 * @sci_phy The phy for which the direct attached device id is to
 *       be assigned.
 * @device_id The direct attached device ID to assign to the phy.
 *       This will either be the RNi for the device or an invalid RNi if there
 *       is no current device assigned to the phy.
 */
void scic_sds_phy_setup_transport(
	struct scic_sds_phy *sci_phy,
	u32 device_id)
{
	u32 tl_control;

	writel(device_id, &sci_phy->transport_layer_registers->stp_rni);

	/*
	 * The read should guarantee that the first write gets posted
	 * before the next write
	 */
	tl_control = readl(&sci_phy->transport_layer_registers->control);
	tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
	writel(tl_control, &sci_phy->transport_layer_registers->control);
}

/**
 *
 * @sci_phy: The phy object to be suspended.
 *
 * This function will perform the register reads/writes to suspend the SCU
 * hardware protocol engine. none
 */
static void scic_sds_phy_suspend(
	struct scic_sds_phy *sci_phy)
{
	u32 scu_sas_pcfg_value;

	scu_sas_pcfg_value =
		readl(&sci_phy->link_layer_registers->phy_configuration);
	scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
	writel(scu_sas_pcfg_value,
		&sci_phy->link_layer_registers->phy_configuration);

	scic_sds_phy_setup_transport(
			sci_phy,
			SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
}

void scic_sds_phy_resume(struct scic_sds_phy *sci_phy)
{
	u32 scu_sas_pcfg_value;

	scu_sas_pcfg_value =
		readl(&sci_phy->link_layer_registers->phy_configuration);
	scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
	writel(scu_sas_pcfg_value,
		&sci_phy->link_layer_registers->phy_configuration);
}

void scic_sds_phy_get_sas_address(struct scic_sds_phy *sci_phy,
				  struct sci_sas_address *sas_address)
{
	sas_address->high = readl(&sci_phy->link_layer_registers->source_sas_address_high);
	sas_address->low = readl(&sci_phy->link_layer_registers->source_sas_address_low);
}

void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy *sci_phy,
					   struct sci_sas_address *sas_address)
{
	struct sas_identify_frame *iaf;
	struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);

	iaf = &iphy->frame_rcvd.iaf;
	memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE);
}

void scic_sds_phy_get_protocols(struct scic_sds_phy *sci_phy,
				struct scic_phy_proto *protocols)
{
	protocols->all =
		(u16)(readl(&sci_phy->
			link_layer_registers->transmit_identification) &
				0x0000FFFF);
}

enum sci_status scic_sds_phy_start(struct scic_sds_phy *sci_phy)
{
	enum scic_sds_phy_states state = sci_phy->sm.current_state_id;

	if (state != SCI_PHY_STOPPED) {
		dev_dbg(sciphy_to_dev(sci_phy),
			 "%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

	sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
	return SCI_SUCCESS;
}

enum sci_status scic_sds_phy_stop(struct scic_sds_phy *sci_phy)
{
	enum scic_sds_phy_states state = sci_phy->sm.current_state_id;

	switch (state) {
	case SCI_PHY_SUB_INITIAL:
	case SCI_PHY_SUB_AWAIT_OSSP_EN:
	case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
	case SCI_PHY_SUB_AWAIT_SAS_POWER:
	case SCI_PHY_SUB_AWAIT_SATA_POWER:
	case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
	case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
	case SCI_PHY_SUB_FINAL:
	case SCI_PHY_READY:
		break;
	default:
		dev_dbg(sciphy_to_dev(sci_phy),
			"%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

	sci_change_state(&sci_phy->sm, SCI_PHY_STOPPED);
	return SCI_SUCCESS;
}

enum sci_status scic_sds_phy_reset(struct scic_sds_phy *sci_phy)
{
	enum scic_sds_phy_states state = sci_phy->sm.current_state_id;

	if (state != SCI_PHY_READY) {
		dev_dbg(sciphy_to_dev(sci_phy),
			"%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

	sci_change_state(&sci_phy->sm, SCI_PHY_RESETTING);
	return SCI_SUCCESS;
}

enum sci_status scic_sds_phy_consume_power_handler(struct scic_sds_phy *sci_phy)
{
	enum scic_sds_phy_states state = sci_phy->sm.current_state_id;

	switch (state) {
	case SCI_PHY_SUB_AWAIT_SAS_POWER: {
		u32 enable_spinup;

		enable_spinup = readl(&sci_phy->link_layer_registers->notify_enable_spinup_control);
		enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
		writel(enable_spinup, &sci_phy->link_layer_registers->notify_enable_spinup_control);

		/* Change state to the final state this substate machine has run to completion */
		sci_change_state(&sci_phy->sm, SCI_PHY_SUB_FINAL);

		return SCI_SUCCESS;
	}
	case SCI_PHY_SUB_AWAIT_SATA_POWER: {
		u32 scu_sas_pcfg_value;

		/* Release the spinup hold state and reset the OOB state machine */
		scu_sas_pcfg_value =
			readl(&sci_phy->link_layer_registers->phy_configuration);
		scu_sas_pcfg_value &=
			~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
		scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
		writel(scu_sas_pcfg_value,
			&sci_phy->link_layer_registers->phy_configuration);

		/* Now restart the OOB operation */
		scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
		scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
		writel(scu_sas_pcfg_value,
			&sci_phy->link_layer_registers->phy_configuration);

		/* Change state to the final state this substate machine has run to completion */
		sci_change_state(&sci_phy->sm, SCI_PHY_SUB_AWAIT_SATA_PHY_EN);

		return SCI_SUCCESS;
	}
	default:
		dev_dbg(sciphy_to_dev(sci_phy),
			"%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

/*
 * *****************************************************************************
 * * SCIC SDS PHY HELPER FUNCTIONS
 * ***************************************************************************** */


/**
 *
 * @sci_phy: The phy object that received SAS PHY DETECTED.
 *
 * This method continues the link training for the phy as if it were a SAS PHY
 * instead of a SATA PHY. This is done because the completion queue had a SAS
 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
 * none
 */
static void scic_sds_phy_start_sas_link_training(
	struct scic_sds_phy *sci_phy)
{
	u32 phy_control;

	phy_control =
		readl(&sci_phy->link_layer_registers->phy_configuration);
	phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
	writel(phy_control,
		&sci_phy->link_layer_registers->phy_configuration);

	sci_change_state(&sci_phy->sm, SCI_PHY_SUB_AWAIT_SAS_SPEED_EN);

	sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
}

/**
 *
 * @sci_phy: The phy object that received a SATA SPINUP HOLD event
 *
 * This method continues the link training for the phy as if it were a SATA PHY
 * instead of a SAS PHY.  This is done because the completion queue had a SATA
 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
 */
static void scic_sds_phy_start_sata_link_training(
	struct scic_sds_phy *sci_phy)
{
	sci_change_state(&sci_phy->sm, SCI_PHY_SUB_AWAIT_SATA_POWER);

	sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
}

/**
 * scic_sds_phy_complete_link_training - perform processing common to
 *    all protocols upon completion of link training.
 * @sci_phy: This parameter specifies the phy object for which link training
 *    has completed.
 * @max_link_rate: This parameter specifies the maximum link rate to be
 *    associated with this phy.
 * @next_state: This parameter specifies the next state for the phy's starting
 *    sub-state machine.
 *
 */
static void scic_sds_phy_complete_link_training(
	struct scic_sds_phy *sci_phy,
	enum sas_linkrate max_link_rate,
	u32 next_state)
{
	sci_phy->max_negotiated_speed = max_link_rate;

	sci_change_state(&sci_phy->sm, next_state);
}

enum sci_status scic_sds_phy_event_handler(struct scic_sds_phy *sci_phy,
					   u32 event_code)
{
	enum scic_sds_phy_states state = sci_phy->sm.current_state_id;

	switch (state) {
	case SCI_PHY_SUB_AWAIT_OSSP_EN:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_SAS_PHY_DETECTED:
			scic_sds_phy_start_sas_link_training(sci_phy);
			sci_phy->is_in_link_training = true;
			break;
		case SCU_EVENT_SATA_SPINUP_HOLD:
			scic_sds_phy_start_sata_link_training(sci_phy);
			sci_phy->is_in_link_training = true;
			break;
		default:
			dev_dbg(sciphy_to_dev(sci_phy),
				"%s: PHY starting substate machine received "
				"unexpected event_code %x\n",
				__func__,
				event_code);
			return SCI_FAILURE;
		}
		return SCI_SUCCESS;
	case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_SAS_PHY_DETECTED:
			/*
			 * Why is this being reported again by the controller?
			 * We would re-enter this state so just stay here */
			break;
		case SCU_EVENT_SAS_15:
		case SCU_EVENT_SAS_15_SSC:
			scic_sds_phy_complete_link_training(
				sci_phy,
				SAS_LINK_RATE_1_5_GBPS,
				SCI_PHY_SUB_AWAIT_IAF_UF);
			break;
		case SCU_EVENT_SAS_30:
		case SCU_EVENT_SAS_30_SSC:
			scic_sds_phy_complete_link_training(
				sci_phy,
				SAS_LINK_RATE_3_0_GBPS,
				SCI_PHY_SUB_AWAIT_IAF_UF);
			break;
		case SCU_EVENT_SAS_60:
		case SCU_EVENT_SAS_60_SSC:
			scic_sds_phy_complete_link_training(
				sci_phy,
				SAS_LINK_RATE_6_0_GBPS,
				SCI_PHY_SUB_AWAIT_IAF_UF);
			break;
		case SCU_EVENT_SATA_SPINUP_HOLD:
			/*
			 * We were doing SAS PHY link training and received a SATA PHY event
			 * continue OOB/SN as if this were a SATA PHY */
			scic_sds_phy_start_sata_link_training(sci_phy);
			break;
		case SCU_EVENT_LINK_FAILURE:
			/* Link failure change state back to the starting state */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;
		default:
			dev_warn(sciphy_to_dev(sci_phy),
				 "%s: PHY starting substate machine received "
				 "unexpected event_code %x\n",
				 __func__, event_code);

			return SCI_FAILURE;
			break;
		}
		return SCI_SUCCESS;
	case SCI_PHY_SUB_AWAIT_IAF_UF:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_SAS_PHY_DETECTED:
			/* Backup the state machine */
			scic_sds_phy_start_sas_link_training(sci_phy);
			break;
		case SCU_EVENT_SATA_SPINUP_HOLD:
			/* We were doing SAS PHY link training and received a
			 * SATA PHY event continue OOB/SN as if this were a
			 * SATA PHY
			 */
			scic_sds_phy_start_sata_link_training(sci_phy);
			break;
		case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
		case SCU_EVENT_LINK_FAILURE:
		case SCU_EVENT_HARD_RESET_RECEIVED:
			/* Start the oob/sn state machine over again */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;
		default:
			dev_warn(sciphy_to_dev(sci_phy),
				 "%s: PHY starting substate machine received "
				 "unexpected event_code %x\n",
				 __func__, event_code);
			return SCI_FAILURE;
		}
		return SCI_SUCCESS;
	case SCI_PHY_SUB_AWAIT_SAS_POWER:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_LINK_FAILURE:
			/* Link failure change state back to the starting state */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;
		default:
			dev_warn(sciphy_to_dev(sci_phy),
				"%s: PHY starting substate machine received unexpected "
				"event_code %x\n",
				__func__,
				event_code);
			return SCI_FAILURE;
		}
		return SCI_SUCCESS;
	case SCI_PHY_SUB_AWAIT_SATA_POWER:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_LINK_FAILURE:
			/* Link failure change state back to the starting state */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;
		case SCU_EVENT_SATA_SPINUP_HOLD:
			/* These events are received every 10ms and are
			 * expected while in this state
			 */
			break;

		case SCU_EVENT_SAS_PHY_DETECTED:
			/* There has been a change in the phy type before OOB/SN for the
			 * SATA finished start down the SAS link traning path.
			 */
			scic_sds_phy_start_sas_link_training(sci_phy);
			break;

		default:
			dev_warn(sciphy_to_dev(sci_phy),
				 "%s: PHY starting substate machine received "
				 "unexpected event_code %x\n",
				 __func__, event_code);

			return SCI_FAILURE;
		}
		return SCI_SUCCESS;
	case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_LINK_FAILURE:
			/* Link failure change state back to the starting state */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;
		case SCU_EVENT_SATA_SPINUP_HOLD:
			/* These events might be received since we dont know how many may be in
			 * the completion queue while waiting for power
			 */
			break;
		case SCU_EVENT_SATA_PHY_DETECTED:
			sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;

			/* We have received the SATA PHY notification change state */
			sci_change_state(&sci_phy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
			break;
		case SCU_EVENT_SAS_PHY_DETECTED:
			/* There has been a change in the phy type before OOB/SN for the
			 * SATA finished start down the SAS link traning path.
			 */
			scic_sds_phy_start_sas_link_training(sci_phy);
			break;
		default:
			dev_warn(sciphy_to_dev(sci_phy),
				 "%s: PHY starting substate machine received "
				 "unexpected event_code %x\n",
				 __func__,
				 event_code);

			return SCI_FAILURE;;
		}
		return SCI_SUCCESS;
	case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_SATA_PHY_DETECTED:
			/*
			 * The hardware reports multiple SATA PHY detected events
			 * ignore the extras */
			break;
		case SCU_EVENT_SATA_15:
		case SCU_EVENT_SATA_15_SSC:
			scic_sds_phy_complete_link_training(
				sci_phy,
				SAS_LINK_RATE_1_5_GBPS,
				SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
			break;
		case SCU_EVENT_SATA_30:
		case SCU_EVENT_SATA_30_SSC:
			scic_sds_phy_complete_link_training(
				sci_phy,
				SAS_LINK_RATE_3_0_GBPS,
				SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
			break;
		case SCU_EVENT_SATA_60:
		case SCU_EVENT_SATA_60_SSC:
			scic_sds_phy_complete_link_training(
				sci_phy,
				SAS_LINK_RATE_6_0_GBPS,
				SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
			break;
		case SCU_EVENT_LINK_FAILURE:
			/* Link failure change state back to the starting state */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;
		case SCU_EVENT_SAS_PHY_DETECTED:
			/*
			 * There has been a change in the phy type before OOB/SN for the
			 * SATA finished start down the SAS link traning path. */
			scic_sds_phy_start_sas_link_training(sci_phy);
			break;
		default:
			dev_warn(sciphy_to_dev(sci_phy),
				 "%s: PHY starting substate machine received "
				 "unexpected event_code %x\n",
				 __func__, event_code);

			return SCI_FAILURE;
		}

		return SCI_SUCCESS;
	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_SATA_PHY_DETECTED:
			/* Backup the state machine */
			sci_change_state(&sci_phy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
			break;

		case SCU_EVENT_LINK_FAILURE:
			/* Link failure change state back to the starting state */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;

		default:
			dev_warn(sciphy_to_dev(sci_phy),
				 "%s: PHY starting substate machine received "
				 "unexpected event_code %x\n",
				 __func__,
				 event_code);

			return SCI_FAILURE;
		}
		return SCI_SUCCESS;
	case SCI_PHY_READY:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_LINK_FAILURE:
			/* Link failure change state back to the starting state */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;
		case SCU_EVENT_BROADCAST_CHANGE:
			/* Broadcast change received. Notify the port. */
			if (phy_get_non_dummy_port(sci_phy) != NULL)
				scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy);
			else
				sci_phy->bcn_received_while_port_unassigned = true;
			break;
		default:
			dev_warn(sciphy_to_dev(sci_phy),
				 "%sP SCIC PHY 0x%p ready state machine received "
				 "unexpected event_code %x\n",
				 __func__, sci_phy, event_code);
			return SCI_FAILURE_INVALID_STATE;
		}
		return SCI_SUCCESS;
	case SCI_PHY_RESETTING:
		switch (scu_get_event_code(event_code)) {
		case SCU_EVENT_HARD_RESET_TRANSMITTED:
			/* Link failure change state back to the starting state */
			sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
			break;
		default:
			dev_warn(sciphy_to_dev(sci_phy),
				 "%s: SCIC PHY 0x%p resetting state machine received "
				 "unexpected event_code %x\n",
				 __func__, sci_phy, event_code);

			return SCI_FAILURE_INVALID_STATE;
			break;
		}
		return SCI_SUCCESS;
	default:
		dev_dbg(sciphy_to_dev(sci_phy),
			"%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}

enum sci_status scic_sds_phy_frame_handler(struct scic_sds_phy *sci_phy,
					   u32 frame_index)
{
	enum scic_sds_phy_states state = sci_phy->sm.current_state_id;
	struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
	enum sci_status result;

	switch (state) {
	case SCI_PHY_SUB_AWAIT_IAF_UF: {
		u32 *frame_words;
		struct sas_identify_frame iaf;
		struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);

		result = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control,
								       frame_index,
								       (void **)&frame_words);

		if (result != SCI_SUCCESS)
			return result;

		sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
		if (iaf.frame_type == 0) {
			u32 state;

			memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
			if (iaf.smp_tport) {
				/* We got the IAF for an expander PHY go to the final
				 * state since there are no power requirements for
				 * expander phys.
				 */
				state = SCI_PHY_SUB_FINAL;
			} else {
				/* We got the IAF we can now go to the await spinup
				 * semaphore state
				 */
				state = SCI_PHY_SUB_AWAIT_SAS_POWER;
			}
			sci_change_state(&sci_phy->sm, state);
			result = SCI_SUCCESS;
		} else
			dev_warn(sciphy_to_dev(sci_phy),
				"%s: PHY starting substate machine received "
				"unexpected frame id %x\n",
				__func__, frame_index);

		scic_sds_controller_release_frame(scic, frame_index);
		return result;
	}
	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: {
		struct dev_to_host_fis *frame_header;
		u32 *fis_frame_data;
		struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);

		result = scic_sds_unsolicited_frame_control_get_header(
			&(scic_sds_phy_get_controller(sci_phy)->uf_control),
			frame_index,
			(void **)&frame_header);

		if (result != SCI_SUCCESS)
			return result;

		if ((frame_header->fis_type == FIS_REGD2H) &&
		    !(frame_header->status & ATA_BUSY)) {
			scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control,
								      frame_index,
								      (void **)&fis_frame_data);

			scic_sds_controller_copy_sata_response(&iphy->frame_rcvd.fis,
							       frame_header,
							       fis_frame_data);

			/* got IAF we can now go to the await spinup semaphore state */
			sci_change_state(&sci_phy->sm, SCI_PHY_SUB_FINAL);

			result = SCI_SUCCESS;
		} else
			dev_warn(sciphy_to_dev(sci_phy),
				 "%s: PHY starting substate machine received "
				 "unexpected frame id %x\n",
				 __func__, frame_index);

		/* Regardless of the result we are done with this frame with it */
		scic_sds_controller_release_frame(scic, frame_index);

		return result;
	}
	default:
		dev_dbg(sciphy_to_dev(sci_phy),
			"%s: in wrong state: %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
	
}

static void scic_sds_phy_starting_initial_substate_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	/* This is just an temporary state go off to the starting state */
	sci_change_state(&sci_phy->sm, SCI_PHY_SUB_AWAIT_OSSP_EN);
}

static void scic_sds_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);
	struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;

	scic_sds_controller_power_control_queue_insert(scic, sci_phy);
}

static void scic_sds_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);
	struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;

	scic_sds_controller_power_control_queue_remove(scic, sci_phy);
}

static void scic_sds_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);
	struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;

	scic_sds_controller_power_control_queue_insert(scic, sci_phy);
}

static void scic_sds_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);
	struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;

	scic_sds_controller_power_control_queue_remove(scic, sci_phy);
}

static void scic_sds_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	sci_mod_timer(&sci_phy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
}

static void scic_sds_phy_starting_await_sata_phy_substate_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	sci_del_timer(&sci_phy->sata_timer);
}

static void scic_sds_phy_starting_await_sata_speed_substate_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	sci_mod_timer(&sci_phy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
}

static void scic_sds_phy_starting_await_sata_speed_substate_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	sci_del_timer(&sci_phy->sata_timer);
}

static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	if (scic_sds_port_link_detected(sci_phy->owning_port, sci_phy)) {

		/*
		 * Clear the PE suspend condition so we can actually
		 * receive SIG FIS
		 * The hardware will not respond to the XRDY until the PE
		 * suspend condition is cleared.
		 */
		scic_sds_phy_resume(sci_phy);

		sci_mod_timer(&sci_phy->sata_timer,
			      SCIC_SDS_SIGNATURE_FIS_TIMEOUT);
	} else
		sci_phy->is_in_link_training = false;
}

static void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	sci_del_timer(&sci_phy->sata_timer);
}

static void scic_sds_phy_starting_final_substate_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	/* State machine has run to completion so exit out and change
	 * the base state machine to the ready state
	 */
	sci_change_state(&sci_phy->sm, SCI_PHY_READY);
}

/**
 *
 * @sci_phy: This is the struct scic_sds_phy object to stop.
 *
 * This method will stop the struct scic_sds_phy object. This does not reset the
 * protocol engine it just suspends it and places it in a state where it will
 * not cause the end device to power up. none
 */
static void scu_link_layer_stop_protocol_engine(
	struct scic_sds_phy *sci_phy)
{
	u32 scu_sas_pcfg_value;
	u32 enable_spinup_value;

	/* Suspend the protocol engine and place it in a sata spinup hold state */
	scu_sas_pcfg_value =
		readl(&sci_phy->link_layer_registers->phy_configuration);
	scu_sas_pcfg_value |=
		(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
		 SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE) |
		 SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD));
	writel(scu_sas_pcfg_value,
	       &sci_phy->link_layer_registers->phy_configuration);

	/* Disable the notify enable spinup primitives */
	enable_spinup_value = readl(&sci_phy->link_layer_registers->notify_enable_spinup_control);
	enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
	writel(enable_spinup_value, &sci_phy->link_layer_registers->notify_enable_spinup_control);
}

/**
 *
 *
 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
 */
static void scu_link_layer_start_oob(
	struct scic_sds_phy *sci_phy)
{
	u32 scu_sas_pcfg_value;

	scu_sas_pcfg_value =
		readl(&sci_phy->link_layer_registers->phy_configuration);
	scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
	scu_sas_pcfg_value &=
		~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
		SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
	writel(scu_sas_pcfg_value,
	       &sci_phy->link_layer_registers->phy_configuration);
}

/**
 *
 *
 * This method will transmit a hard reset request on the specified phy. The SCU
 * hardware requires that we reset the OOB state machine and set the hard reset
 * bit in the phy configuration register. We then must start OOB over with the
 * hard reset bit set.
 */
static void scu_link_layer_tx_hard_reset(
	struct scic_sds_phy *sci_phy)
{
	u32 phy_configuration_value;

	/*
	 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
	 * to the starting state. */
	phy_configuration_value =
		readl(&sci_phy->link_layer_registers->phy_configuration);
	phy_configuration_value |=
		(SCU_SAS_PCFG_GEN_BIT(HARD_RESET) |
		 SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
	writel(phy_configuration_value,
	       &sci_phy->link_layer_registers->phy_configuration);

	/* Now take the OOB state machine out of reset */
	phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
	phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
	writel(phy_configuration_value,
	       &sci_phy->link_layer_registers->phy_configuration);
}

static void scic_sds_phy_stopped_state_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	/*
	 * @todo We need to get to the controller to place this PE in a
	 * reset state
	 */
	sci_del_timer(&sci_phy->sata_timer);

	scu_link_layer_stop_protocol_engine(sci_phy);

	if (sci_phy->sm.previous_state_id != SCI_PHY_INITIAL)
		scic_sds_controller_link_down(scic_sds_phy_get_controller(sci_phy),
					      phy_get_non_dummy_port(sci_phy),
					      sci_phy);
}

static void scic_sds_phy_starting_state_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	scu_link_layer_stop_protocol_engine(sci_phy);
	scu_link_layer_start_oob(sci_phy);

	/* We don't know what kind of phy we are going to be just yet */
	sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
	sci_phy->bcn_received_while_port_unassigned = false;

	if (sci_phy->sm.previous_state_id == SCI_PHY_READY)
		scic_sds_controller_link_down(scic_sds_phy_get_controller(sci_phy),
					      phy_get_non_dummy_port(sci_phy),
					      sci_phy);

	sci_change_state(&sci_phy->sm, SCI_PHY_SUB_INITIAL);
}

static void scic_sds_phy_ready_state_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	scic_sds_controller_link_up(scic_sds_phy_get_controller(sci_phy),
				    phy_get_non_dummy_port(sci_phy),
				    sci_phy);

}

static void scic_sds_phy_ready_state_exit(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	scic_sds_phy_suspend(sci_phy);
}

static void scic_sds_phy_resetting_state_enter(struct sci_base_state_machine *sm)
{
	struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), sm);

	/* The phy is being reset, therefore deactivate it from the port.  In
	 * the resetting state we don't notify the user regarding link up and
	 * link down notifications
	 */
	scic_sds_port_deactivate_phy(sci_phy->owning_port, sci_phy, false);

	if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
		scu_link_layer_tx_hard_reset(sci_phy);
	} else {
		/* The SCU does not need to have a discrete reset state so
		 * just go back to the starting state.
		 */
		sci_change_state(&sci_phy->sm, SCI_PHY_STARTING);
	}
}

static const struct sci_base_state scic_sds_phy_state_table[] = {
	[SCI_PHY_INITIAL] = { },
	[SCI_PHY_STOPPED] = {
		.enter_state = scic_sds_phy_stopped_state_enter,
	},
	[SCI_PHY_STARTING] = {
		.enter_state = scic_sds_phy_starting_state_enter,
	},
	[SCI_PHY_SUB_INITIAL] = {
		.enter_state = scic_sds_phy_starting_initial_substate_enter,
	},
	[SCI_PHY_SUB_AWAIT_OSSP_EN] = { },
	[SCI_PHY_SUB_AWAIT_SAS_SPEED_EN] = { },
	[SCI_PHY_SUB_AWAIT_IAF_UF] = { },
	[SCI_PHY_SUB_AWAIT_SAS_POWER] = {
		.enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
		.exit_state  = scic_sds_phy_starting_await_sas_power_substate_exit,
	},
	[SCI_PHY_SUB_AWAIT_SATA_POWER] = {
		.enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
		.exit_state  = scic_sds_phy_starting_await_sata_power_substate_exit
	},
	[SCI_PHY_SUB_AWAIT_SATA_PHY_EN] = {
		.enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
		.exit_state  = scic_sds_phy_starting_await_sata_phy_substate_exit
	},
	[SCI_PHY_SUB_AWAIT_SATA_SPEED_EN] = {
		.enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
		.exit_state  = scic_sds_phy_starting_await_sata_speed_substate_exit
	},
	[SCI_PHY_SUB_AWAIT_SIG_FIS_UF] = {
		.enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
		.exit_state  = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
	},
	[SCI_PHY_SUB_FINAL] = {
		.enter_state = scic_sds_phy_starting_final_substate_enter,
	},
	[SCI_PHY_READY] = {
		.enter_state = scic_sds_phy_ready_state_enter,
		.exit_state = scic_sds_phy_ready_state_exit,
	},
	[SCI_PHY_RESETTING] = {
		.enter_state = scic_sds_phy_resetting_state_enter,
	},
	[SCI_PHY_FINAL] = { },
};

void scic_sds_phy_construct(struct scic_sds_phy *sci_phy,
			    struct scic_sds_port *owning_port, u8 phy_index)
{
	sci_base_state_machine_construct(&sci_phy->sm,
					 scic_sds_phy_state_table,
					 SCI_PHY_INITIAL);

	sci_base_state_machine_start(&sci_phy->sm);

	/* Copy the rest of the input data to our locals */
	sci_phy->owning_port = owning_port;
	sci_phy->phy_index = phy_index;
	sci_phy->bcn_received_while_port_unassigned = false;
	sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
	sci_phy->link_layer_registers = NULL;
	sci_phy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;

	/* Create the SIGNATURE FIS Timeout timer for this phy */
	sci_init_timer(&sci_phy->sata_timer, phy_sata_timeout);
}

void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
{
	union scic_oem_parameters oem;
	u64 sci_sas_addr;
	__be64 sas_addr;

	scic_oem_parameters_get(&ihost->sci, &oem);
	sci_sas_addr = oem.sds1.phys[index].sas_address.high;
	sci_sas_addr <<= 32;
	sci_sas_addr |= oem.sds1.phys[index].sas_address.low;
	sas_addr = cpu_to_be64(sci_sas_addr);
	memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));

	iphy->isci_port = NULL;
	iphy->sas_phy.enabled = 0;
	iphy->sas_phy.id = index;
	iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
	iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd;
	iphy->sas_phy.ha = &ihost->sas_ha;
	iphy->sas_phy.lldd_phy = iphy;
	iphy->sas_phy.enabled = 1;
	iphy->sas_phy.class = SAS;
	iphy->sas_phy.iproto = SAS_PROTOCOL_ALL;
	iphy->sas_phy.tproto = 0;
	iphy->sas_phy.type = PHY_TYPE_PHYSICAL;
	iphy->sas_phy.role = PHY_ROLE_INITIATOR;
	iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
	iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
	memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd));
}


/**
 * isci_phy_control() - This function is one of the SAS Domain Template
 *    functions. This is a phy management function.
 * @phy: This parameter specifies the sphy being controlled.
 * @func: This parameter specifies the phy control function being invoked.
 * @buf: This parameter is specific to the phy function being invoked.
 *
 * status, zero indicates success.
 */
int isci_phy_control(struct asd_sas_phy *sas_phy,
		     enum phy_func func,
		     void *buf)
{
	int ret = 0;
	struct isci_phy *iphy = sas_phy->lldd_phy;
	struct isci_port *iport = iphy->isci_port;
	struct isci_host *ihost = sas_phy->ha->lldd_ha;
	unsigned long flags;

	dev_dbg(&ihost->pdev->dev,
		"%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
		__func__, sas_phy, func, buf, iphy, iport);

	switch (func) {
	case PHY_FUNC_DISABLE:
		spin_lock_irqsave(&ihost->scic_lock, flags);
		scic_sds_phy_stop(&iphy->sci);
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
		break;

	case PHY_FUNC_LINK_RESET:
		spin_lock_irqsave(&ihost->scic_lock, flags);
		scic_sds_phy_stop(&iphy->sci);
		scic_sds_phy_start(&iphy->sci);
		spin_unlock_irqrestore(&ihost->scic_lock, flags);
		break;

	case PHY_FUNC_HARD_RESET:
		if (!iport)
			return -ENODEV;

		/* Perform the port reset. */
		ret = isci_port_perform_hard_reset(ihost, iport, iphy);

		break;

	default:
		dev_dbg(&ihost->pdev->dev,
			   "%s: phy %p; func %d NOT IMPLEMENTED!\n",
			   __func__, sas_phy, func);
		ret = -ENOSYS;
		break;
	}
	return ret;
}
