1230557Sjimharris/*- 2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license. When using or 3230557Sjimharris * redistributing this file, you may do so under either license. 4230557Sjimharris * 5230557Sjimharris * GPL LICENSE SUMMARY 6230557Sjimharris * 7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8230557Sjimharris * 9230557Sjimharris * This program is free software; you can redistribute it and/or modify 10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as 11230557Sjimharris * published by the Free Software Foundation. 12230557Sjimharris * 13230557Sjimharris * This program is distributed in the hope that it will be useful, but 14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of 15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16230557Sjimharris * General Public License for more details. 17230557Sjimharris * 18230557Sjimharris * You should have received a copy of the GNU General Public License 19230557Sjimharris * along with this program; if not, write to the Free Software 20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21230557Sjimharris * The full GNU General Public License is included in this distribution 22230557Sjimharris * in the file called LICENSE.GPL. 23230557Sjimharris * 24230557Sjimharris * BSD LICENSE 25230557Sjimharris * 26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27230557Sjimharris * All rights reserved. 28230557Sjimharris * 29230557Sjimharris * Redistribution and use in source and binary forms, with or without 30230557Sjimharris * modification, are permitted provided that the following conditions 31230557Sjimharris * are met: 32230557Sjimharris * 33230557Sjimharris * * Redistributions of source code must retain the above copyright 34230557Sjimharris * notice, this list of conditions and the following disclaimer. 35230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 36230557Sjimharris * notice, this list of conditions and the following disclaimer in 37230557Sjimharris * the documentation and/or other materials provided with the 38230557Sjimharris * distribution. 39230557Sjimharris * 40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51230557Sjimharris */ 52230557Sjimharris 53230557Sjimharris#include <sys/cdefs.h> 54230557Sjimharris__FBSDID("$FreeBSD$"); 55230557Sjimharris 56230557Sjimharris/** 57230557Sjimharris * @file 58230557Sjimharris * 59230557Sjimharris * @brief This file contains the implementation of the SCIC_SDS_PHY public and 60230557Sjimharris * protected methods. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 64230557Sjimharris#include <dev/isci/scil/scic_phy.h> 65230557Sjimharris#include <dev/isci/scil/scic_sds_phy.h> 66230557Sjimharris#include <dev/isci/scil/scic_sds_port.h> 67230557Sjimharris#include <dev/isci/scil/scic_sds_controller_registers.h> 68230557Sjimharris#include <dev/isci/scil/scic_sds_phy_registers.h> 69230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h> 70230557Sjimharris#include <dev/isci/scil/scic_sds_remote_node_context.h> 71230557Sjimharris#include <dev/isci/scil/sci_util.h> 72230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h> 73230557Sjimharris#include <dev/isci/scil/scu_event_codes.h> 74230557Sjimharris#include <dev/isci/scil/sci_base_state.h> 75230557Sjimharris#include <dev/isci/scil/intel_ata.h> 76230557Sjimharris#include <dev/isci/scil/intel_sata.h> 77230557Sjimharris#include <dev/isci/scil/sci_base_state_machine.h> 78230557Sjimharris#include <dev/isci/scil/scic_sds_port_registers.h> 79230557Sjimharris 80230557Sjimharris#define SCIC_SDS_PHY_MIN_TIMER_COUNT (SCI_MAX_PHYS) 81230557Sjimharris#define SCIC_SDS_PHY_MAX_TIMER_COUNT (SCI_MAX_PHYS) 82230557Sjimharris 83230557Sjimharris// Maximum arbitration wait time in micro-seconds 84230557Sjimharris#define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700) 85230557Sjimharris 86230557Sjimharris#define AFE_REGISTER_WRITE_DELAY 10 87230557Sjimharris 88230557Sjimharris//***************************************************************************** 89230557Sjimharris//* SCIC SDS PHY Internal Methods 90230557Sjimharris//***************************************************************************** 91230557Sjimharris 92230557Sjimharris/** 93230557Sjimharris * @brief This method will initialize the phy transport layer registers 94230557Sjimharris * 95230557Sjimharris * @param[in] this_phy 96230557Sjimharris * @param[in] transport_layer_registers 97230557Sjimharris * 98230557Sjimharris * @return SCI_STATUS 99230557Sjimharris */ 100230557Sjimharrisstatic 101230557SjimharrisSCI_STATUS scic_sds_phy_transport_layer_initialization( 102230557Sjimharris SCIC_SDS_PHY_T *this_phy, 103230557Sjimharris SCU_TRANSPORT_LAYER_REGISTERS_T *transport_layer_registers 104230557Sjimharris) 105230557Sjimharris{ 106230557Sjimharris U32 tl_control; 107230557Sjimharris 108230557Sjimharris SCIC_LOG_TRACE(( 109230557Sjimharris sci_base_object_get_logger(this_phy), 110230557Sjimharris SCIC_LOG_OBJECT_PHY, 111230557Sjimharris "scic_sds_phy_link_layer_initialization(this_phy:0x%x, link_layer_registers:0x%x)\n", 112230557Sjimharris this_phy, transport_layer_registers 113230557Sjimharris )); 114230557Sjimharris 115230557Sjimharris this_phy->transport_layer_registers = transport_layer_registers; 116230557Sjimharris 117230557Sjimharris SCU_STPTLDARNI_WRITE(this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX); 118230557Sjimharris 119230557Sjimharris // Hardware team recommends that we enable the STP prefetch for all transports 120230557Sjimharris tl_control = SCU_TLCR_READ(this_phy); 121230557Sjimharris tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH); 122230557Sjimharris SCU_TLCR_WRITE(this_phy, tl_control); 123230557Sjimharris 124230557Sjimharris return SCI_SUCCESS; 125230557Sjimharris} 126230557Sjimharris 127230557Sjimharris/** 128230557Sjimharris * @brief This method will initialize the phy link layer registers 129230557Sjimharris * 130230557Sjimharris * @param[in] this_phy 131230557Sjimharris * @param[in] link_layer_registers 132230557Sjimharris * 133230557Sjimharris * @return SCI_STATUS 134230557Sjimharris */ 135230557Sjimharrisstatic 136230557SjimharrisSCI_STATUS scic_sds_phy_link_layer_initialization( 137230557Sjimharris SCIC_SDS_PHY_T *this_phy, 138230557Sjimharris SCU_LINK_LAYER_REGISTERS_T *link_layer_registers 139230557Sjimharris) 140230557Sjimharris{ 141230557Sjimharris U32 phy_configuration; 142230557Sjimharris SAS_CAPABILITIES_T phy_capabilities; 143230557Sjimharris U32 parity_check = 0; 144230557Sjimharris U32 parity_count = 0; 145230557Sjimharris U32 link_layer_control; 146230557Sjimharris U32 phy_timer_timeout_values; 147230557Sjimharris U32 clksm_value = 0; 148230557Sjimharris 149230557Sjimharris SCIC_LOG_TRACE(( 150230557Sjimharris sci_base_object_get_logger(this_phy), 151230557Sjimharris SCIC_LOG_OBJECT_PHY, 152230557Sjimharris "scic_sds_phy_link_layer_initialization(this_phy:0x%x, link_layer_registers:0x%x)\n", 153230557Sjimharris this_phy, link_layer_registers 154230557Sjimharris )); 155230557Sjimharris 156230557Sjimharris this_phy->link_layer_registers = link_layer_registers; 157230557Sjimharris 158230557Sjimharris // Set our IDENTIFY frame data 159230557Sjimharris #define SCI_END_DEVICE 0x01 160230557Sjimharris 161230557Sjimharris SCU_SAS_TIID_WRITE( 162230557Sjimharris this_phy, 163230557Sjimharris ( SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) 164230557Sjimharris | SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) 165230557Sjimharris | SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) 166230557Sjimharris | SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) 167230557Sjimharris | SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE) ) 168230557Sjimharris ); 169230557Sjimharris 170230557Sjimharris // Write the device SAS Address 171230557Sjimharris SCU_SAS_TIDNH_WRITE(this_phy, 0xFEDCBA98); 172230557Sjimharris SCU_SAS_TIDNL_WRITE(this_phy, this_phy->phy_index); 173230557Sjimharris 174230557Sjimharris // Write the source SAS Address 175230557Sjimharris SCU_SAS_TISSAH_WRITE( 176230557Sjimharris this_phy, 177230557Sjimharris this_phy->owning_port->owning_controller->oem_parameters.sds1.phys[ 178230557Sjimharris this_phy->phy_index].sas_address.sci_format.high 179230557Sjimharris ); 180230557Sjimharris SCU_SAS_TISSAL_WRITE( 181230557Sjimharris this_phy, 182230557Sjimharris this_phy->owning_port->owning_controller->oem_parameters.sds1.phys[ 183230557Sjimharris this_phy->phy_index].sas_address.sci_format.low 184230557Sjimharris ); 185230557Sjimharris 186230557Sjimharris // Clear and Set the PHY Identifier 187230557Sjimharris SCU_SAS_TIPID_WRITE(this_phy, 0x00000000); 188230557Sjimharris SCU_SAS_TIPID_WRITE(this_phy, SCU_SAS_TIPID_GEN_VALUE(ID, this_phy->phy_index)); 189230557Sjimharris 190230557Sjimharris // Change the initial state of the phy configuration register 191230557Sjimharris phy_configuration = SCU_SAS_PCFG_READ(this_phy); 192230557Sjimharris 193230557Sjimharris // Hold OOB state machine in reset 194230557Sjimharris phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET); 195230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, phy_configuration); 196230557Sjimharris 197230557Sjimharris // Configure the SNW capabilities 198230557Sjimharris phy_capabilities.u.all = 0; 199230557Sjimharris phy_capabilities.u.bits.start = 1; 200230557Sjimharris phy_capabilities.u.bits.gen3_without_ssc_supported = 1; 201230557Sjimharris phy_capabilities.u.bits.gen2_without_ssc_supported = 1; 202230557Sjimharris phy_capabilities.u.bits.gen1_without_ssc_supported = 1; 203230557Sjimharris 204230557Sjimharris /* 205230557Sjimharris * Set up SSC settings according to version of OEM Parameters. 206230557Sjimharris */ 207230557Sjimharris { 208230557Sjimharris U8 header_version, enable_sata, enable_sas, 209230557Sjimharris sata_spread, sas_type, sas_spread; 210230557Sjimharris OEM_SSC_PARAMETERS_T ssc; 211230557Sjimharris 212230557Sjimharris header_version = this_phy->owning_port->owning_controller-> 213230557Sjimharris oem_parameters_version; 214230557Sjimharris 215230557Sjimharris ssc.bf.ssc_sata_tx_spread_level = 216230557Sjimharris this_phy->owning_port->owning_controller->oem_parameters.sds1.controller.ssc_sata_tx_spread_level; 217230557Sjimharris ssc.bf.ssc_sas_tx_spread_level = 218230557Sjimharris this_phy->owning_port->owning_controller->oem_parameters.sds1.controller.ssc_sas_tx_spread_level; 219230557Sjimharris ssc.bf.ssc_sas_tx_type = 220230557Sjimharris this_phy->owning_port->owning_controller->oem_parameters.sds1.controller.ssc_sas_tx_type; 221230557Sjimharris enable_sata = enable_sas = sata_spread = sas_type = sas_spread = 0; 222230557Sjimharris 223230557Sjimharris if (header_version == SCI_OEM_PARAM_VER_1_0) 224230557Sjimharris { 225230557Sjimharris /* 226230557Sjimharris * Version 1.0 is merely turning SSC on to default values.; 227230557Sjimharris */ 228230557Sjimharris if (ssc.do_enable_ssc != 0) 229230557Sjimharris { 230230557Sjimharris enable_sas = enable_sata = TRUE; 231230557Sjimharris sas_type = 0x0; // Downspreading 232230557Sjimharris sata_spread = 0x2; // +0 to -1419 PPM 233230557Sjimharris sas_spread = 0x2; // +0 to -1419 PPM 234230557Sjimharris } 235230557Sjimharris } 236230557Sjimharris else // header_version >= SCI_OEM_PARAM_VER_1_1 237230557Sjimharris { 238230557Sjimharris /* 239230557Sjimharris * Version 1.1 can turn on SAS and SATA independently and 240230557Sjimharris * specify spread levels. Also can specify spread type for SAS. 241230557Sjimharris */ 242230557Sjimharris if ((sata_spread = ssc.bf.ssc_sata_tx_spread_level) != 0) 243230557Sjimharris enable_sata = TRUE; // Downspreading only 244230557Sjimharris if ((sas_spread = ssc.bf.ssc_sas_tx_spread_level) != 0) 245230557Sjimharris { 246230557Sjimharris enable_sas = TRUE; 247230557Sjimharris sas_type = ssc.bf.ssc_sas_tx_type; 248230557Sjimharris } 249230557Sjimharris } 250230557Sjimharris 251230557Sjimharris if (enable_sas == TRUE) 252230557Sjimharris { 253230557Sjimharris U32 reg_val = scu_afe_register_read( 254230557Sjimharris this_phy->owning_port->owning_controller, 255230557Sjimharris scu_afe_xcvr[this_phy->phy_index]. 256230557Sjimharris afe_xcvr_control0); 257230557Sjimharris reg_val |= (0x00100000 | (((U32)sas_type) << 19)); 258230557Sjimharris scu_afe_register_write( 259230557Sjimharris this_phy->owning_port->owning_controller, 260230557Sjimharris scu_afe_xcvr[this_phy->phy_index].afe_xcvr_control0, 261230557Sjimharris reg_val); 262230557Sjimharris 263230557Sjimharris reg_val = scu_afe_register_read( 264230557Sjimharris this_phy->owning_port->owning_controller, 265230557Sjimharris scu_afe_xcvr[this_phy->phy_index]. 266230557Sjimharris afe_tx_ssc_control); 267230557Sjimharris reg_val |= (((U32)(sas_spread)) << 8); 268230557Sjimharris scu_afe_register_write( 269230557Sjimharris this_phy->owning_port->owning_controller, 270230557Sjimharris scu_afe_xcvr[this_phy->phy_index].afe_tx_ssc_control, 271230557Sjimharris reg_val); 272230557Sjimharris phy_capabilities.u.bits.gen3_with_ssc_supported = 1; 273230557Sjimharris phy_capabilities.u.bits.gen2_with_ssc_supported = 1; 274230557Sjimharris phy_capabilities.u.bits.gen1_with_ssc_supported = 1; 275230557Sjimharris } 276230557Sjimharris 277230557Sjimharris if (enable_sata == TRUE) 278230557Sjimharris { 279230557Sjimharris U32 reg_val = scu_afe_register_read( 280230557Sjimharris this_phy->owning_port->owning_controller, 281230557Sjimharris scu_afe_xcvr[this_phy->phy_index]. 282230557Sjimharris afe_tx_ssc_control); 283230557Sjimharris reg_val |= (U32)sata_spread; 284230557Sjimharris scu_afe_register_write( 285230557Sjimharris this_phy->owning_port->owning_controller, 286230557Sjimharris scu_afe_xcvr[this_phy->phy_index].afe_tx_ssc_control, 287230557Sjimharris reg_val); 288230557Sjimharris 289230557Sjimharris reg_val = scu_link_layer_register_read( 290230557Sjimharris this_phy, 291230557Sjimharris stp_control); 292230557Sjimharris reg_val |= (U32)(1 << 12); 293230557Sjimharris scu_link_layer_register_write( 294230557Sjimharris this_phy, 295230557Sjimharris stp_control, 296230557Sjimharris reg_val); 297230557Sjimharris } 298230557Sjimharris } 299230557Sjimharris 300230557Sjimharris // The SAS specification indicates that the phy_capabilities that 301230557Sjimharris // are transmitted shall have an even parity. Calculate the parity. 302230557Sjimharris parity_check = phy_capabilities.u.all; 303230557Sjimharris while (parity_check != 0) 304230557Sjimharris { 305230557Sjimharris if (parity_check & 0x1) 306230557Sjimharris parity_count++; 307230557Sjimharris parity_check >>= 1; 308230557Sjimharris } 309230557Sjimharris 310230557Sjimharris // If parity indicates there are an odd number of bits set, then 311230557Sjimharris // set the parity bit to 1 in the phy capabilities. 312230557Sjimharris if ((parity_count % 2) != 0) 313230557Sjimharris phy_capabilities.u.bits.parity = 1; 314230557Sjimharris 315230557Sjimharris SCU_SAS_PHYCAP_WRITE(this_phy, phy_capabilities.u.all); 316230557Sjimharris 317230557Sjimharris // Set the enable spinup period but disable the ability to send notify enable spinup 318230557Sjimharris SCU_SAS_ENSPINUP_WRITE( 319230557Sjimharris this_phy, 320230557Sjimharris SCU_ENSPINUP_GEN_VAL( 321230557Sjimharris COUNT, 322230557Sjimharris this_phy->owning_port->owning_controller->user_parameters.sds1. 323230557Sjimharris phys[this_phy->phy_index].notify_enable_spin_up_insertion_frequency 324230557Sjimharris ) 325230557Sjimharris ); 326230557Sjimharris 327230557Sjimharris // Write the ALIGN Insertion Ferequency for connected phy and inpendent of connected state 328230557Sjimharris clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL ( 329230557Sjimharris CONNECTED, 330230557Sjimharris this_phy->owning_port->owning_controller->user_parameters.sds1. 331230557Sjimharris phys[this_phy->phy_index].in_connection_align_insertion_frequency 332230557Sjimharris ); 333230557Sjimharris 334230557Sjimharris clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL ( 335230557Sjimharris GENERAL, 336230557Sjimharris this_phy->owning_port->owning_controller->user_parameters.sds1. 337230557Sjimharris phys[this_phy->phy_index].align_insertion_frequency 338230557Sjimharris ); 339230557Sjimharris 340230557Sjimharris SCU_SAS_CLKSM_WRITE ( this_phy, clksm_value); 341230557Sjimharris 342230557Sjimharris 343230557Sjimharris#if defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD) || defined(PBG_HBA_BETA_BUILD) 344230557Sjimharris /// @todo Provide a way to write this register correctly 345230557Sjimharris scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x02108421); 346230557Sjimharris#elif defined(PBG_BUILD) 347230557Sjimharris if ( 348230557Sjimharris (this_phy->owning_port->owning_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) 349230557Sjimharris || (this_phy->owning_port->owning_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1) 350230557Sjimharris ) 351230557Sjimharris { 352230557Sjimharris scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x04210400); 353230557Sjimharris scu_link_layer_register_write(this_phy, sas_primitive_timeout, 0x20A7C05); 354230557Sjimharris } 355230557Sjimharris else 356230557Sjimharris { 357230557Sjimharris scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x02108421); 358230557Sjimharris } 359230557Sjimharris#else 360230557Sjimharris /// @todo Provide a way to write this register correctly 361230557Sjimharris scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x0e739ce7); 362230557Sjimharris#endif 363230557Sjimharris 364230557Sjimharris link_layer_control = SCU_SAS_LLCTL_GEN_VAL( 365230557Sjimharris NO_OUTBOUND_TASK_TIMEOUT, 366230557Sjimharris (U8) this_phy->owning_port->owning_controller-> 367230557Sjimharris user_parameters.sds1.no_outbound_task_timeout 368230557Sjimharris ); 369230557Sjimharris 370230557Sjimharris#if PHY_MAX_LINK_SPEED_GENERATION == SCIC_SDS_PARM_GEN1_SPEED 371230557Sjimharris#define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 372230557Sjimharris#elif PHY_MAX_LINK_SPEED_GENERATION == SCIC_SDS_PARM_GEN2_SPEED 373230557Sjimharris#define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2 374230557Sjimharris#else 375230557Sjimharris#define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3 376230557Sjimharris#endif // PHY_MAX_LINK_SPEED_GENERATION 377230557Sjimharris 378230557Sjimharris if (this_phy->owning_port->owning_controller->user_parameters.sds1. 379230557Sjimharris phys[this_phy->phy_index].max_speed_generation == SCIC_SDS_PARM_GEN3_SPEED) 380230557Sjimharris { 381230557Sjimharris link_layer_control |= SCU_SAS_LLCTL_GEN_VAL( 382230557Sjimharris MAX_LINK_RATE, COMPILED_MAX_LINK_RATE 383230557Sjimharris ); 384230557Sjimharris } 385230557Sjimharris else if (this_phy->owning_port->owning_controller->user_parameters.sds1. 386230557Sjimharris phys[this_phy->phy_index].max_speed_generation == SCIC_SDS_PARM_GEN2_SPEED) 387230557Sjimharris { 388230557Sjimharris link_layer_control |= SCU_SAS_LLCTL_GEN_VAL( 389230557Sjimharris MAX_LINK_RATE, 390230557Sjimharris MIN( 391230557Sjimharris SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2, 392230557Sjimharris COMPILED_MAX_LINK_RATE) 393230557Sjimharris ); 394230557Sjimharris } 395230557Sjimharris else 396230557Sjimharris { 397230557Sjimharris link_layer_control |= SCU_SAS_LLCTL_GEN_VAL( 398230557Sjimharris MAX_LINK_RATE, 399230557Sjimharris MIN( 400230557Sjimharris SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1, 401230557Sjimharris COMPILED_MAX_LINK_RATE) 402230557Sjimharris ); 403230557Sjimharris } 404230557Sjimharris 405230557Sjimharris scu_link_layer_register_write( 406230557Sjimharris this_phy, link_layer_control, link_layer_control 407230557Sjimharris ); 408230557Sjimharris 409230557Sjimharris phy_timer_timeout_values = scu_link_layer_register_read( 410230557Sjimharris this_phy, 411230557Sjimharris phy_timer_timeout_values 412230557Sjimharris ); 413230557Sjimharris 414230557Sjimharris // Clear the default 0x36 (54us) RATE_CHANGE timeout value. 415230557Sjimharris phy_timer_timeout_values &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF); 416230557Sjimharris 417230557Sjimharris // Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can 418230557Sjimharris // lock with 3Gb drive when SCU max rate is set to 1.5Gb. 419230557Sjimharris phy_timer_timeout_values |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B); 420230557Sjimharris 421230557Sjimharris scu_link_layer_register_write( 422230557Sjimharris this_phy, phy_timer_timeout_values, phy_timer_timeout_values 423230557Sjimharris ); 424230557Sjimharris 425230557Sjimharris // Program the max ARB time for the PHY to 700us so we inter-operate with 426230557Sjimharris // the PMC expander which shuts down PHYs if the expander PHY generates too 427230557Sjimharris // many breaks. This time value will guarantee that the initiator PHY will 428230557Sjimharris // generate the break. 429230557Sjimharris#if defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD) 430230557Sjimharris scu_link_layer_register_write( 431230557Sjimharris this_phy, 432230557Sjimharris maximum_arbitration_wait_timer_timeout, 433230557Sjimharris SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME 434230557Sjimharris ); 435230557Sjimharris#endif // defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD) 436230557Sjimharris 437230557Sjimharris // Disable the link layer hang detection timer 438230557Sjimharris scu_link_layer_register_write( 439230557Sjimharris this_phy, link_layer_hang_detection_timeout, 0x00000000 440230557Sjimharris ); 441230557Sjimharris 442230557Sjimharris // We can exit the initial state to the stopped state 443230557Sjimharris sci_base_state_machine_change_state( 444230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 445230557Sjimharris SCI_BASE_PHY_STATE_STOPPED 446230557Sjimharris ); 447230557Sjimharris 448230557Sjimharris return SCI_SUCCESS; 449230557Sjimharris} 450230557Sjimharris 451230557Sjimharris/** 452230557Sjimharris * This function will handle the sata SIGNATURE FIS timeout condition. It 453230557Sjimharris * will restart the starting substate machine since we dont know what has 454230557Sjimharris * actually happening. 455230557Sjimharris * 456230557Sjimharris * @param[in] cookie This object is cast to the SCIC_SDS_PHY_T object. 457230557Sjimharris * 458230557Sjimharris * @return none 459230557Sjimharris */ 460230557Sjimharrisvoid scic_sds_phy_sata_timeout( SCI_OBJECT_HANDLE_T cookie) 461230557Sjimharris{ 462230557Sjimharris SCIC_SDS_PHY_T * this_phy = (SCIC_SDS_PHY_T *)cookie; 463230557Sjimharris 464230557Sjimharris SCIC_LOG_INFO(( 465230557Sjimharris sci_base_object_get_logger(this_phy), 466230557Sjimharris SCIC_LOG_OBJECT_PHY, 467230557Sjimharris "SCIC SDS Phy 0x%x did not receive signature fis before timeout.\n", 468230557Sjimharris this_phy 469230557Sjimharris )); 470230557Sjimharris 471230557Sjimharris sci_base_state_machine_stop( 472230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy)); 473230557Sjimharris 474230557Sjimharris sci_base_state_machine_change_state( 475230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 476230557Sjimharris SCI_BASE_PHY_STATE_STARTING 477230557Sjimharris ); 478230557Sjimharris} 479230557Sjimharris 480230557Sjimharris//***************************************************************************** 481230557Sjimharris//* SCIC SDS PHY External Methods 482230557Sjimharris//***************************************************************************** 483230557Sjimharris 484230557Sjimharris/** 485230557Sjimharris * @brief This method returns the object size for a phy object. 486230557Sjimharris * 487230557Sjimharris * @return U32 488230557Sjimharris */ 489230557SjimharrisU32 scic_sds_phy_get_object_size(void) 490230557Sjimharris{ 491230557Sjimharris return sizeof(SCIC_SDS_PHY_T); 492230557Sjimharris} 493230557Sjimharris 494230557Sjimharris/** 495230557Sjimharris * @brief This method returns the minimum number of timers required for a 496230557Sjimharris * phy object. 497230557Sjimharris * 498230557Sjimharris * @return U32 499230557Sjimharris */ 500230557SjimharrisU32 scic_sds_phy_get_min_timer_count(void) 501230557Sjimharris{ 502230557Sjimharris return SCIC_SDS_PHY_MIN_TIMER_COUNT; 503230557Sjimharris} 504230557Sjimharris 505230557Sjimharris/** 506230557Sjimharris * @brief This method returns the maximum number of timers required for a 507230557Sjimharris * phy object. 508230557Sjimharris * 509230557Sjimharris * @return U32 510230557Sjimharris */ 511230557SjimharrisU32 scic_sds_phy_get_max_timer_count(void) 512230557Sjimharris{ 513230557Sjimharris return SCIC_SDS_PHY_MAX_TIMER_COUNT; 514230557Sjimharris} 515230557Sjimharris 516230557Sjimharris#ifdef SCI_LOGGING 517230557Sjimharrisstatic 518230557Sjimharrisvoid scic_sds_phy_initialize_state_logging( 519230557Sjimharris SCIC_SDS_PHY_T *this_phy 520230557Sjimharris) 521230557Sjimharris{ 522230557Sjimharris sci_base_state_machine_logger_initialize( 523230557Sjimharris &this_phy->parent.state_machine_logger, 524230557Sjimharris &this_phy->parent.state_machine, 525230557Sjimharris &this_phy->parent.parent, 526230557Sjimharris scic_cb_logger_log_states, 527230557Sjimharris "SCIC_SDS_PHY_T", "base state machine", 528230557Sjimharris SCIC_LOG_OBJECT_PHY 529230557Sjimharris ); 530230557Sjimharris 531230557Sjimharris sci_base_state_machine_logger_initialize( 532230557Sjimharris &this_phy->starting_substate_machine_logger, 533230557Sjimharris &this_phy->starting_substate_machine, 534230557Sjimharris &this_phy->parent.parent, 535230557Sjimharris scic_cb_logger_log_states, 536230557Sjimharris "SCIC_SDS_PHY_T", "starting substate machine", 537230557Sjimharris SCIC_LOG_OBJECT_PHY 538230557Sjimharris ); 539230557Sjimharris} 540230557Sjimharris#endif // SCI_LOGGING 541230557Sjimharris 542230557Sjimharris#ifdef SCIC_DEBUG_ENABLED 543230557Sjimharris/** 544230557Sjimharris * Debug code to record the state transitions in the phy 545230557Sjimharris * 546230557Sjimharris * @param our_observer 547230557Sjimharris * @param the_state_machine 548230557Sjimharris */ 549230557Sjimharrisvoid scic_sds_phy_observe_state_change( 550230557Sjimharris SCI_BASE_OBSERVER_T * our_observer, 551230557Sjimharris SCI_BASE_SUBJECT_T * the_subject 552230557Sjimharris) 553230557Sjimharris{ 554230557Sjimharris SCIC_SDS_PHY_T *this_phy; 555230557Sjimharris SCI_BASE_STATE_MACHINE_T *the_state_machine; 556230557Sjimharris 557230557Sjimharris U8 transition_requestor; 558230557Sjimharris U32 base_state_id; 559230557Sjimharris U32 starting_substate_id; 560230557Sjimharris 561230557Sjimharris the_state_machine = (SCI_BASE_STATE_MACHINE_T *)the_subject; 562230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)the_state_machine->state_machine_owner; 563230557Sjimharris 564230557Sjimharris if (the_state_machine == &this_phy->parent.state_machine) 565230557Sjimharris { 566230557Sjimharris transition_requestor = 0x01; 567230557Sjimharris } 568230557Sjimharris else if (the_state_machine == &this_phy->starting_substate_machine) 569230557Sjimharris { 570230557Sjimharris transition_requestor = 0x02; 571230557Sjimharris } 572230557Sjimharris else 573230557Sjimharris { 574230557Sjimharris transition_requestor = 0xFF; 575230557Sjimharris } 576230557Sjimharris 577230557Sjimharris base_state_id = 578230557Sjimharris sci_base_state_machine_get_state(&this_phy->parent.state_machine); 579230557Sjimharris starting_substate_id = 580230557Sjimharris sci_base_state_machine_get_state(&this_phy->starting_substate_machine); 581230557Sjimharris 582230557Sjimharris this_phy->state_record.state_transition_table[ 583230557Sjimharris this_phy->state_record.index++] = ( (transition_requestor << 24) 584230557Sjimharris | ((U8)base_state_id << 8) 585230557Sjimharris | ((U8)starting_substate_id)); 586230557Sjimharris 587230557Sjimharris this_phy->state_record.index = 588230557Sjimharris this_phy->state_record.index & (MAX_STATE_TRANSITION_RECORD - 1); 589230557Sjimharris 590230557Sjimharris} 591230557Sjimharris#endif // SCIC_DEBUG_ENABLED 592230557Sjimharris 593230557Sjimharris#ifdef SCIC_DEBUG_ENABLED 594230557Sjimharris/** 595230557Sjimharris * This method initializes the state record debug information for the phy 596230557Sjimharris * object. 597230557Sjimharris * 598230557Sjimharris * @pre The state machines for the phy object must be constructed before this 599230557Sjimharris * function is called. 600230557Sjimharris * 601230557Sjimharris * @param this_phy The phy which is being initialized. 602230557Sjimharris */ 603230557Sjimharrisvoid scic_sds_phy_initialize_state_recording( 604230557Sjimharris SCIC_SDS_PHY_T *this_phy 605230557Sjimharris) 606230557Sjimharris{ 607230557Sjimharris this_phy->state_record.index = 0; 608230557Sjimharris 609230557Sjimharris sci_base_observer_initialize( 610230557Sjimharris &this_phy->state_record.base_state_observer, 611230557Sjimharris scic_sds_phy_observe_state_change, 612230557Sjimharris &this_phy->parent.state_machine.parent 613230557Sjimharris ); 614230557Sjimharris 615230557Sjimharris sci_base_observer_initialize( 616230557Sjimharris &this_phy->state_record.starting_state_observer, 617230557Sjimharris scic_sds_phy_observe_state_change, 618230557Sjimharris &this_phy->starting_substate_machine.parent 619230557Sjimharris ); 620230557Sjimharris} 621230557Sjimharris#endif // SCIC_DEBUG_ENABLED 622230557Sjimharris 623230557Sjimharris/** 624230557Sjimharris * @brief This method will construct the SCIC_SDS_PHY object 625230557Sjimharris * 626230557Sjimharris * @param[in] this_phy 627230557Sjimharris * @param[in] owning_port 628230557Sjimharris * @param[in] phy_index 629230557Sjimharris * 630230557Sjimharris * @return none 631230557Sjimharris */ 632230557Sjimharrisvoid scic_sds_phy_construct( 633230557Sjimharris SCIC_SDS_PHY_T *this_phy, 634230557Sjimharris SCIC_SDS_PORT_T *owning_port, 635230557Sjimharris U8 phy_index 636230557Sjimharris) 637230557Sjimharris{ 638230557Sjimharris // Call the base constructor first 639230557Sjimharris // Copy the logger from the port (this could be the dummy port) 640230557Sjimharris sci_base_phy_construct( 641230557Sjimharris &this_phy->parent, 642230557Sjimharris sci_base_object_get_logger(owning_port), 643230557Sjimharris scic_sds_phy_state_table 644230557Sjimharris ); 645230557Sjimharris 646230557Sjimharris // Copy the rest of the input data to our locals 647230557Sjimharris this_phy->owning_port = owning_port; 648230557Sjimharris this_phy->phy_index = phy_index; 649230557Sjimharris this_phy->bcn_received_while_port_unassigned = FALSE; 650230557Sjimharris this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN; 651230557Sjimharris this_phy->link_layer_registers = NULL; 652230557Sjimharris this_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE; 653230557Sjimharris this_phy->sata_timeout_timer = NULL; 654230557Sjimharris 655230557Sjimharris // Clear out the identification buffer data 656230557Sjimharris memset(&this_phy->phy_type, 0, sizeof(this_phy->phy_type)); 657230557Sjimharris 658230557Sjimharris // Clear out the error counter data 659230557Sjimharris memset(this_phy->error_counter, 0, sizeof(this_phy->error_counter)); 660230557Sjimharris 661240518Seadler // Initialize the substate machines 662230557Sjimharris sci_base_state_machine_construct( 663230557Sjimharris &this_phy->starting_substate_machine, 664230557Sjimharris &this_phy->parent.parent, 665230557Sjimharris scic_sds_phy_starting_substates, 666230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL 667230557Sjimharris ); 668230557Sjimharris 669230557Sjimharris #ifdef SCI_LOGGING 670230557Sjimharris scic_sds_phy_initialize_state_logging(this_phy); 671230557Sjimharris #endif // SCI_LOGGING 672230557Sjimharris 673230557Sjimharris #ifdef SCIC_DEBUG_ENABLED 674230557Sjimharris scic_sds_phy_initialize_state_recording(this_phy); 675230557Sjimharris #endif // SCIC_DEBUG_ENABLED 676230557Sjimharris} 677230557Sjimharris 678230557Sjimharris/** 679230557Sjimharris * @brief This method returns the port currently containing this phy. 680230557Sjimharris * If the phy is currently contained by the dummy port, then 681230557Sjimharris * the phy is considered to not be part of a port. 682230557Sjimharris * 683230557Sjimharris * @param[in] this_phy This parameter specifies the phy for which to 684230557Sjimharris * retrieve the containing port. 685230557Sjimharris * 686230557Sjimharris * @return This method returns a handle to a port that contains 687230557Sjimharris * the supplied phy. 688230557Sjimharris * @retval SCI_INVALID_HANDLE This value is returned if the phy is not 689230557Sjimharris * part of a real port (i.e. it's contained in the dummy port). 690230557Sjimharris * @retval !SCI_INVALID_HANDLE All other values indicate a handle/pointer 691230557Sjimharris * to the port containing the phy. 692230557Sjimharris */ 693230557SjimharrisSCI_PORT_HANDLE_T scic_sds_phy_get_port( 694230557Sjimharris SCIC_SDS_PHY_T *this_phy 695230557Sjimharris) 696230557Sjimharris{ 697230557Sjimharris SCIC_LOG_TRACE(( 698230557Sjimharris sci_base_object_get_logger(this_phy), 699230557Sjimharris SCIC_LOG_OBJECT_PHY, 700230557Sjimharris "scic_phy_get_port(0x%x) enter\n", 701230557Sjimharris this_phy 702230557Sjimharris )); 703230557Sjimharris 704230557Sjimharris if (scic_sds_port_get_index(this_phy->owning_port) == SCIC_SDS_DUMMY_PORT) 705230557Sjimharris return SCI_INVALID_HANDLE; 706230557Sjimharris 707230557Sjimharris return this_phy->owning_port; 708230557Sjimharris} 709230557Sjimharris 710230557Sjimharris/** 711230557Sjimharris * @brief This method will assign a port to the phy object. 712230557Sjimharris * 713230557Sjimharris * @param[in, out] this_phy This parameter specifies the phy for which 714230557Sjimharris * to assign a port object. 715230557Sjimharris * @param[in] the_port This parameter is the port to assing to the phy. 716230557Sjimharris */ 717230557Sjimharrisvoid scic_sds_phy_set_port( 718230557Sjimharris SCIC_SDS_PHY_T * this_phy, 719230557Sjimharris SCIC_SDS_PORT_T * the_port 720230557Sjimharris) 721230557Sjimharris{ 722230557Sjimharris this_phy->owning_port = the_port; 723230557Sjimharris 724230557Sjimharris if (this_phy->bcn_received_while_port_unassigned) 725230557Sjimharris { 726230557Sjimharris this_phy->bcn_received_while_port_unassigned = FALSE; 727230557Sjimharris scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy); 728230557Sjimharris } 729230557Sjimharris} 730230557Sjimharris 731230557Sjimharris/** 732230557Sjimharris * @brief This method will initialize the constructed phy 733230557Sjimharris * 734230557Sjimharris * @param[in] this_phy 735230557Sjimharris * @param[in] link_layer_registers 736230557Sjimharris * 737230557Sjimharris * @return SCI_STATUS 738230557Sjimharris */ 739230557SjimharrisSCI_STATUS scic_sds_phy_initialize( 740230557Sjimharris SCIC_SDS_PHY_T *this_phy, 741230557Sjimharris void *transport_layer_registers, 742230557Sjimharris SCU_LINK_LAYER_REGISTERS_T *link_layer_registers 743230557Sjimharris) 744230557Sjimharris{ 745230557Sjimharris SCIC_LOG_TRACE(( 746230557Sjimharris sci_base_object_get_logger(this_phy), 747230557Sjimharris SCIC_LOG_OBJECT_PHY, 748230557Sjimharris "scic_sds_phy_initialize(this_phy:0x%x, link_layer_registers:0x%x)\n", 749230557Sjimharris this_phy, link_layer_registers 750230557Sjimharris )); 751230557Sjimharris 752298931Spfg // Perform the initialization of the TL hardware 753230557Sjimharris scic_sds_phy_transport_layer_initialization(this_phy, transport_layer_registers); 754230557Sjimharris 755230557Sjimharris // Perofrm the initialization of the PE hardware 756230557Sjimharris scic_sds_phy_link_layer_initialization(this_phy, link_layer_registers); 757230557Sjimharris 758230557Sjimharris // There is nothing that needs to be done in this state just 759230557Sjimharris // transition to the stopped state. 760230557Sjimharris sci_base_state_machine_change_state( 761230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 762230557Sjimharris SCI_BASE_PHY_STATE_STOPPED 763230557Sjimharris ); 764230557Sjimharris 765230557Sjimharris return SCI_SUCCESS; 766230557Sjimharris} 767230557Sjimharris 768230557Sjimharris/** 769230557Sjimharris * This method assigns the direct attached device ID for this phy. 770230557Sjimharris * 771230557Sjimharris * @param[in] this_phy The phy for which the direct attached device id is to 772230557Sjimharris * be assigned. 773230557Sjimharris * @param[in] device_id The direct attached device ID to assign to the phy. 774230557Sjimharris * This will either be the RNi for the device or an invalid RNi if there 775230557Sjimharris * is no current device assigned to the phy. 776230557Sjimharris */ 777230557Sjimharrisvoid scic_sds_phy_setup_transport( 778230557Sjimharris SCIC_SDS_PHY_T * this_phy, 779230557Sjimharris U32 device_id 780230557Sjimharris) 781230557Sjimharris{ 782230557Sjimharris U32 tl_control; 783230557Sjimharris 784230557Sjimharris SCU_STPTLDARNI_WRITE(this_phy, device_id); 785230557Sjimharris 786230557Sjimharris // The read should guarntee that the first write gets posted 787230557Sjimharris // before the next write 788230557Sjimharris tl_control = SCU_TLCR_READ(this_phy); 789230557Sjimharris tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE); 790230557Sjimharris SCU_TLCR_WRITE(this_phy, tl_control); 791230557Sjimharris} 792230557Sjimharris 793230557Sjimharris/** 794230557Sjimharris * This function will perform the register reads/writes to suspend the SCU 795230557Sjimharris * hardware protocol engine. 796230557Sjimharris * 797230557Sjimharris * @param[in,out] this_phy The phy object to be suspended. 798230557Sjimharris * 799230557Sjimharris * @return none 800230557Sjimharris */ 801230557Sjimharrisvoid scic_sds_phy_suspend( 802230557Sjimharris SCIC_SDS_PHY_T * this_phy 803230557Sjimharris) 804230557Sjimharris{ 805230557Sjimharris U32 scu_sas_pcfg_value; 806230557Sjimharris 807230557Sjimharris scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy); 808230557Sjimharris scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE); 809230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value); 810230557Sjimharris 811230557Sjimharris scic_sds_phy_setup_transport( 812230557Sjimharris this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 813230557Sjimharris ); 814230557Sjimharris} 815230557Sjimharris 816230557Sjimharris/** 817230557Sjimharris * This function will perform the register reads/writes required to resume the 818230557Sjimharris * SCU hardware protocol engine. 819230557Sjimharris * 820230557Sjimharris * @param[in,out] this_phy The phy object to resume. 821230557Sjimharris * 822230557Sjimharris * @return none 823230557Sjimharris */ 824230557Sjimharrisvoid scic_sds_phy_resume( 825230557Sjimharris SCIC_SDS_PHY_T * this_phy 826230557Sjimharris) 827230557Sjimharris{ 828230557Sjimharris U32 scu_sas_pcfg_value; 829230557Sjimharris 830230557Sjimharris scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy); 831230557Sjimharris 832230557Sjimharris scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE); 833230557Sjimharris 834230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value); 835230557Sjimharris} 836230557Sjimharris 837230557Sjimharris/** 838230557Sjimharris * @brief This method returns the local sas address assigned to this phy. 839230557Sjimharris * 840230557Sjimharris * @param[in] this_phy This parameter specifies the phy for which 841230557Sjimharris * to retrieve the local SAS address. 842230557Sjimharris * @param[out] sas_address This parameter specifies the location into 843230557Sjimharris * which to copy the local SAS address. 844230557Sjimharris * 845230557Sjimharris * @return none 846230557Sjimharris */ 847230557Sjimharrisvoid scic_sds_phy_get_sas_address( 848230557Sjimharris SCIC_SDS_PHY_T *this_phy, 849230557Sjimharris SCI_SAS_ADDRESS_T *sas_address 850230557Sjimharris) 851230557Sjimharris{ 852230557Sjimharris SCIC_LOG_TRACE(( 853230557Sjimharris sci_base_object_get_logger(this_phy), 854230557Sjimharris SCIC_LOG_OBJECT_PHY, 855230557Sjimharris "scic_sds_phy_get_sas_address(this_phy:0x%x, sas_address:0x%x)\n", 856230557Sjimharris this_phy, sas_address 857230557Sjimharris )); 858230557Sjimharris 859230557Sjimharris sas_address->high = SCU_SAS_TISSAH_READ(this_phy); 860230557Sjimharris sas_address->low = SCU_SAS_TISSAL_READ(this_phy); 861230557Sjimharris} 862230557Sjimharris 863230557Sjimharris/** 864230557Sjimharris * @brief This method returns the remote end-point (i.e. attached) 865230557Sjimharris * sas address assigned to this phy. 866230557Sjimharris * 867230557Sjimharris * @param[in] this_phy This parameter specifies the phy for which 868230557Sjimharris * to retrieve the remote end-point SAS address. 869230557Sjimharris * @param[out] sas_address This parameter specifies the location into 870230557Sjimharris * which to copy the remote end-point SAS address. 871230557Sjimharris * 872230557Sjimharris * @return none 873230557Sjimharris */ 874230557Sjimharrisvoid scic_sds_phy_get_attached_sas_address( 875230557Sjimharris SCIC_SDS_PHY_T *this_phy, 876230557Sjimharris SCI_SAS_ADDRESS_T *sas_address 877230557Sjimharris) 878230557Sjimharris{ 879230557Sjimharris SCIC_LOG_TRACE(( 880230557Sjimharris sci_base_object_get_logger(this_phy), 881230557Sjimharris SCIC_LOG_OBJECT_PHY, 882230557Sjimharris "scic_sds_phy_get_attached_sas_address(0x%x, 0x%x) enter\n", 883230557Sjimharris this_phy, sas_address 884230557Sjimharris )); 885230557Sjimharris 886230557Sjimharris sas_address->high 887230557Sjimharris = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high; 888230557Sjimharris sas_address->low 889230557Sjimharris = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low; 890230557Sjimharris} 891230557Sjimharris 892230557Sjimharris/** 893230557Sjimharris * @brief This method returns the supported protocols assigned to 894230557Sjimharris * this phy 895230557Sjimharris * 896230557Sjimharris * @param[in] this_phy 897230557Sjimharris * @param[out] protocols 898230557Sjimharris */ 899230557Sjimharrisvoid scic_sds_phy_get_protocols( 900230557Sjimharris SCIC_SDS_PHY_T *this_phy, 901230557Sjimharris SCI_SAS_IDENTIFY_ADDRESS_FRAME_PROTOCOLS_T * protocols 902230557Sjimharris) 903230557Sjimharris{ 904230557Sjimharris U32 tiid_value = SCU_SAS_TIID_READ(this_phy); 905230557Sjimharris 906230557Sjimharris //Check each bit of this register. please refer to 907230557Sjimharris //SAS Transmit Identification Register (SAS_TIID). 908230557Sjimharris if (tiid_value & 0x2) 909230557Sjimharris protocols->u.bits.smp_target = 1; 910230557Sjimharris 911230557Sjimharris if (tiid_value & 0x4) 912230557Sjimharris protocols->u.bits.stp_target = 1; 913230557Sjimharris 914230557Sjimharris if (tiid_value & 0x8) 915230557Sjimharris protocols->u.bits.ssp_target = 1; 916230557Sjimharris 917230557Sjimharris if (tiid_value & 0x200) 918230557Sjimharris protocols->u.bits.smp_initiator = 1; 919230557Sjimharris 920230557Sjimharris if ((tiid_value & 0x400)) 921230557Sjimharris protocols->u.bits.stp_initiator = 1; 922230557Sjimharris 923230557Sjimharris if (tiid_value & 0x800) 924230557Sjimharris protocols->u.bits.ssp_initiator = 1; 925230557Sjimharris 926230557Sjimharris SCIC_LOG_TRACE(( 927230557Sjimharris sci_base_object_get_logger(this_phy), 928230557Sjimharris SCIC_LOG_OBJECT_PHY, 929230557Sjimharris "scic_sds_phy_get_protocols(this_phy:0x%x, protocols:0x%x)\n", 930230557Sjimharris this_phy, protocols->u.all 931230557Sjimharris )); 932230557Sjimharris} 933230557Sjimharris 934230557Sjimharris/** 935230557Sjimharris * This method returns the supported protocols for the attached phy. If this 936230557Sjimharris * is a SAS phy the protocols are returned from the identify address frame. 937230557Sjimharris * If this is a SATA phy then protocols are made up and the target phy is an 938230557Sjimharris * STP target phy. 939230557Sjimharris * 940230557Sjimharris * @note The caller will get the entire set of bits for the protocol value. 941230557Sjimharris * 942230557Sjimharris * @param[in] this_phy The parameter is the phy object for which the attached 943230557Sjimharris * phy protcols are to be returned. 944230557Sjimharris * @param[out] protocols The parameter is the returned protocols for the 945230557Sjimharris * attached phy. 946230557Sjimharris */ 947230557Sjimharrisvoid scic_sds_phy_get_attached_phy_protocols( 948230557Sjimharris SCIC_SDS_PHY_T *this_phy, 949230557Sjimharris SCI_SAS_IDENTIFY_ADDRESS_FRAME_PROTOCOLS_T * protocols 950230557Sjimharris) 951230557Sjimharris{ 952230557Sjimharris SCIC_LOG_TRACE(( 953230557Sjimharris sci_base_object_get_logger(this_phy), 954230557Sjimharris SCIC_LOG_OBJECT_PHY, 955230557Sjimharris "scic_sds_phy_get_attached_phy_protocols(this_phy:0x%x, protocols:0x%x[0x%x])\n", 956230557Sjimharris this_phy, protocols, protocols->u.all 957230557Sjimharris )); 958230557Sjimharris 959230557Sjimharris protocols->u.all = 0; 960230557Sjimharris 961230557Sjimharris if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) 962230557Sjimharris { 963230557Sjimharris protocols->u.all = 964230557Sjimharris this_phy->phy_type.sas.identify_address_frame_buffer.protocols.u.all; 965230557Sjimharris } 966230557Sjimharris else if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) 967230557Sjimharris { 968230557Sjimharris protocols->u.bits.stp_target = 1; 969230557Sjimharris } 970230557Sjimharris} 971230557Sjimharris 972230557Sjimharris 973230557Sjimharris/** 974230557Sjimharris * @brief This method release resources in for a scic phy. 975230557Sjimharris * 976230557Sjimharris * @param[in] controller This parameter specifies the core controller, one of 977230557Sjimharris * its phy's resources are to be released. 978249586Sgabor * @param[in] this_phy This parameter specifies the phy whose resource is to 979230557Sjimharris * be released. 980230557Sjimharris */ 981230557Sjimharrisvoid scic_sds_phy_release_resource( 982230557Sjimharris SCIC_SDS_CONTROLLER_T * controller, 983230557Sjimharris SCIC_SDS_PHY_T * this_phy 984230557Sjimharris) 985230557Sjimharris{ 986230557Sjimharris SCIC_LOG_TRACE(( 987230557Sjimharris sci_base_object_get_logger(this_phy), 988230557Sjimharris SCIC_LOG_OBJECT_PHY, 989230557Sjimharris "scic_sds_phy_release_resource(0x%x, 0x%x)\n", 990230557Sjimharris controller, this_phy 991230557Sjimharris )); 992230557Sjimharris 993230557Sjimharris //Currently, the only resource to be released is a timer. 994230557Sjimharris if (this_phy->sata_timeout_timer != NULL) 995230557Sjimharris { 996230557Sjimharris scic_cb_timer_destroy(controller, this_phy->sata_timeout_timer); 997230557Sjimharris this_phy->sata_timeout_timer = NULL; 998230557Sjimharris } 999230557Sjimharris} 1000230557Sjimharris 1001230557Sjimharris 1002230557Sjimharris//***************************************************************************** 1003230557Sjimharris//* SCIC SDS PHY Handler Redirects 1004230557Sjimharris//***************************************************************************** 1005230557Sjimharris 1006230557Sjimharris/** 1007230557Sjimharris * @brief This method will attempt to reset the phy. This 1008230557Sjimharris * request is only valid when the phy is in an ready 1009230557Sjimharris * state 1010230557Sjimharris * 1011230557Sjimharris * @param[in] this_phy 1012230557Sjimharris * 1013230557Sjimharris * @return SCI_STATUS 1014230557Sjimharris */ 1015230557SjimharrisSCI_STATUS scic_sds_phy_reset( 1016230557Sjimharris SCIC_SDS_PHY_T * this_phy 1017230557Sjimharris) 1018230557Sjimharris{ 1019230557Sjimharris SCIC_LOG_TRACE(( 1020230557Sjimharris sci_base_object_get_logger(this_phy), 1021230557Sjimharris SCIC_LOG_OBJECT_PHY, 1022230557Sjimharris "scic_sds_phy_reset(this_phy:0x%08x)\n", 1023230557Sjimharris this_phy 1024230557Sjimharris )); 1025230557Sjimharris 1026230557Sjimharris return this_phy->state_handlers->parent.reset_handler( 1027230557Sjimharris &this_phy->parent 1028230557Sjimharris ); 1029230557Sjimharris} 1030230557Sjimharris 1031230557Sjimharris/** 1032298931Spfg * @brief This method will process the event code received. 1033230557Sjimharris * 1034230557Sjimharris * @param[in] this_phy 1035230557Sjimharris * @param[in] event_code 1036230557Sjimharris * 1037230557Sjimharris * @return SCI_STATUS 1038230557Sjimharris */ 1039230557SjimharrisSCI_STATUS scic_sds_phy_event_handler( 1040230557Sjimharris SCIC_SDS_PHY_T *this_phy, 1041230557Sjimharris U32 event_code 1042230557Sjimharris) 1043230557Sjimharris{ 1044230557Sjimharris SCIC_LOG_TRACE(( 1045230557Sjimharris sci_base_object_get_logger(this_phy), 1046230557Sjimharris SCIC_LOG_OBJECT_PHY, 1047230557Sjimharris "scic_sds_phy_event_handler(this_phy:0x%08x, event_code:%x)\n", 1048230557Sjimharris this_phy, event_code 1049230557Sjimharris )); 1050230557Sjimharris 1051230557Sjimharris return this_phy->state_handlers->event_handler(this_phy, event_code); 1052230557Sjimharris} 1053230557Sjimharris 1054230557Sjimharris/** 1055298931Spfg * @brief This method will process the frame index received. 1056230557Sjimharris * 1057230557Sjimharris * @param[in] this_phy 1058230557Sjimharris * @param[in] frame_index 1059230557Sjimharris * 1060230557Sjimharris * @return SCI_STATUS 1061230557Sjimharris */ 1062230557SjimharrisSCI_STATUS scic_sds_phy_frame_handler( 1063230557Sjimharris SCIC_SDS_PHY_T *this_phy, 1064230557Sjimharris U32 frame_index 1065230557Sjimharris) 1066230557Sjimharris{ 1067230557Sjimharris SCIC_LOG_TRACE(( 1068230557Sjimharris sci_base_object_get_logger(this_phy), 1069230557Sjimharris SCIC_LOG_OBJECT_PHY, 1070230557Sjimharris "scic_sds_phy_frame_handler(this_phy:0x%08x, frame_index:%d)\n", 1071230557Sjimharris this_phy, frame_index 1072230557Sjimharris )); 1073230557Sjimharris 1074230557Sjimharris return this_phy->state_handlers->frame_handler(this_phy, frame_index); 1075230557Sjimharris} 1076230557Sjimharris 1077230557Sjimharris/** 1078230557Sjimharris * @brief This method will give the phy permission to consume power 1079230557Sjimharris * 1080230557Sjimharris * @param[in] this_phy 1081230557Sjimharris * 1082230557Sjimharris * @return SCI_STATUS 1083230557Sjimharris */ 1084230557SjimharrisSCI_STATUS scic_sds_phy_consume_power_handler( 1085230557Sjimharris SCIC_SDS_PHY_T *this_phy 1086230557Sjimharris) 1087230557Sjimharris{ 1088230557Sjimharris SCIC_LOG_TRACE(( 1089230557Sjimharris sci_base_object_get_logger(this_phy), 1090230557Sjimharris SCIC_LOG_OBJECT_PHY, 1091230557Sjimharris "scic_sds_phy_consume_power_handler(this_phy:0x%08x)\n", 1092230557Sjimharris this_phy 1093230557Sjimharris )); 1094230557Sjimharris 1095230557Sjimharris return this_phy->state_handlers->consume_power_handler(this_phy); 1096230557Sjimharris} 1097230557Sjimharris 1098230557Sjimharris//***************************************************************************** 1099230557Sjimharris//* SCIC PHY Public Methods 1100230557Sjimharris//***************************************************************************** 1101230557Sjimharris 1102230557SjimharrisSCI_STATUS scic_phy_get_properties( 1103230557Sjimharris SCI_PHY_HANDLE_T phy, 1104230557Sjimharris SCIC_PHY_PROPERTIES_T * properties 1105230557Sjimharris) 1106230557Sjimharris{ 1107230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1108230557Sjimharris U8 max_speed_generation; 1109230557Sjimharris 1110230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1111230557Sjimharris 1112230557Sjimharris SCIC_LOG_TRACE(( 1113230557Sjimharris sci_base_object_get_logger(this_phy), 1114230557Sjimharris SCIC_LOG_OBJECT_PHY, 1115230557Sjimharris "scic_phy_get_properties(0x%x, 0x%x) enter\n", 1116230557Sjimharris this_phy, properties 1117230557Sjimharris )); 1118230557Sjimharris 1119230557Sjimharris if (phy == SCI_INVALID_HANDLE) 1120230557Sjimharris { 1121230557Sjimharris return SCI_FAILURE_INVALID_PHY; 1122230557Sjimharris } 1123230557Sjimharris 1124230557Sjimharris memset(properties, 0, sizeof(SCIC_PHY_PROPERTIES_T)); 1125230557Sjimharris 1126230557Sjimharris //get max link rate of this phy set by user. 1127230557Sjimharris max_speed_generation = 1128230557Sjimharris this_phy->owning_port->owning_controller->user_parameters.sds1. 1129230557Sjimharris phys[this_phy->phy_index].max_speed_generation; 1130230557Sjimharris 1131230557Sjimharris properties->negotiated_link_rate = this_phy->max_negotiated_speed; 1132230557Sjimharris 1133230557Sjimharris if (max_speed_generation == SCIC_SDS_PARM_GEN3_SPEED) 1134230557Sjimharris properties->max_link_rate = SCI_SAS_600_GB; 1135230557Sjimharris else if (max_speed_generation == SCIC_SDS_PARM_GEN2_SPEED) 1136230557Sjimharris properties->max_link_rate = SCI_SAS_300_GB; 1137230557Sjimharris else 1138230557Sjimharris properties->max_link_rate = SCI_SAS_150_GB; 1139230557Sjimharris 1140230557Sjimharris properties->index = this_phy->phy_index; 1141230557Sjimharris properties->owning_port = scic_sds_phy_get_port(this_phy); 1142230557Sjimharris 1143230557Sjimharris scic_sds_phy_get_protocols(this_phy, &properties->transmit_iaf.protocols); 1144230557Sjimharris 1145230557Sjimharris properties->transmit_iaf.sas_address.high = 1146230557Sjimharris this_phy->owning_port->owning_controller->oem_parameters.sds1. 1147230557Sjimharris phys[this_phy->phy_index].sas_address.sci_format.high; 1148230557Sjimharris 1149230557Sjimharris properties->transmit_iaf.sas_address.low = 1150230557Sjimharris this_phy->owning_port->owning_controller->oem_parameters.sds1. 1151230557Sjimharris phys[this_phy->phy_index].sas_address.sci_format.low; 1152230557Sjimharris 1153230557Sjimharris return SCI_SUCCESS; 1154230557Sjimharris} 1155230557Sjimharris 1156230557Sjimharris// --------------------------------------------------------------------------- 1157230557Sjimharris 1158230557SjimharrisSCI_STATUS scic_sas_phy_get_properties( 1159230557Sjimharris SCI_PHY_HANDLE_T phy, 1160230557Sjimharris SCIC_SAS_PHY_PROPERTIES_T * properties 1161230557Sjimharris) 1162230557Sjimharris{ 1163230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1164230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1165230557Sjimharris 1166230557Sjimharris SCIC_LOG_TRACE(( 1167230557Sjimharris sci_base_object_get_logger(this_phy), 1168230557Sjimharris SCIC_LOG_OBJECT_PHY, 1169230557Sjimharris "scic_sas_phy_get_properties(0x%x, 0x%x) enter\n", 1170230557Sjimharris this_phy, properties 1171230557Sjimharris )); 1172230557Sjimharris 1173230557Sjimharris if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) 1174230557Sjimharris { 1175230557Sjimharris memcpy( 1176230557Sjimharris &properties->received_iaf, 1177230557Sjimharris &this_phy->phy_type.sas.identify_address_frame_buffer, 1178230557Sjimharris sizeof(SCI_SAS_IDENTIFY_ADDRESS_FRAME_T) 1179230557Sjimharris ); 1180230557Sjimharris 1181230557Sjimharris properties->received_capabilities.u.all 1182230557Sjimharris = SCU_SAS_RECPHYCAP_READ(this_phy); 1183230557Sjimharris 1184230557Sjimharris return SCI_SUCCESS; 1185230557Sjimharris } 1186230557Sjimharris 1187230557Sjimharris return SCI_FAILURE; 1188230557Sjimharris} 1189230557Sjimharris 1190230557Sjimharris// --------------------------------------------------------------------------- 1191230557Sjimharris 1192230557SjimharrisSCI_STATUS scic_sata_phy_get_properties( 1193230557Sjimharris SCI_PHY_HANDLE_T phy, 1194230557Sjimharris SCIC_SATA_PHY_PROPERTIES_T * properties 1195230557Sjimharris) 1196230557Sjimharris{ 1197230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1198230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1199230557Sjimharris 1200230557Sjimharris SCIC_LOG_TRACE(( 1201230557Sjimharris sci_base_object_get_logger(this_phy), 1202230557Sjimharris SCIC_LOG_OBJECT_PHY, 1203230557Sjimharris "scic_sata_phy_get_properties(0x%x, 0x%x) enter\n", 1204230557Sjimharris this_phy, properties 1205230557Sjimharris )); 1206230557Sjimharris 1207230557Sjimharris if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) 1208230557Sjimharris { 1209230557Sjimharris memcpy( 1210230557Sjimharris &properties->signature_fis, 1211230557Sjimharris &this_phy->phy_type.sata.signature_fis_buffer, 1212230557Sjimharris sizeof(SATA_FIS_REG_D2H_T) 1213230557Sjimharris ); 1214230557Sjimharris 1215230557Sjimharris /// @todo add support for port selectors. 1216230557Sjimharris properties->is_port_selector_present = FALSE; 1217230557Sjimharris 1218230557Sjimharris return SCI_SUCCESS; 1219230557Sjimharris } 1220230557Sjimharris 1221230557Sjimharris return SCI_FAILURE; 1222230557Sjimharris} 1223230557Sjimharris 1224230557Sjimharris// --------------------------------------------------------------------------- 1225230557Sjimharris 1226230557Sjimharris#if !defined(DISABLE_PORT_SELECTORS) 1227230557Sjimharris 1228230557SjimharrisSCI_STATUS scic_sata_phy_send_port_selection_signal( 1229230557Sjimharris SCI_PHY_HANDLE_T phy 1230230557Sjimharris) 1231230557Sjimharris{ 1232230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1233230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1234230557Sjimharris 1235230557Sjimharris SCIC_LOG_TRACE(( 1236230557Sjimharris sci_base_object_get_logger(this_phy), 1237230557Sjimharris SCIC_LOG_OBJECT_PHY, 1238230557Sjimharris "scic_sata_phy_send_port_selection_signals(0x%x) enter\n", 1239230557Sjimharris this_phy 1240230557Sjimharris )); 1241230557Sjimharris 1242230557Sjimharris /// @todo To be implemented 1243230557Sjimharris ASSERT(FALSE); 1244230557Sjimharris return SCI_FAILURE; 1245230557Sjimharris} 1246230557Sjimharris 1247230557Sjimharris#endif // !defined(DISABLE_PORT_SELECTORS) 1248230557Sjimharris 1249230557Sjimharris// --------------------------------------------------------------------------- 1250230557Sjimharris 1251230557Sjimharris#if !defined(DISABLE_PHY_COUNTERS) 1252230557Sjimharris 1253230557SjimharrisSCI_STATUS scic_phy_enable_counter( 1254230557Sjimharris SCI_PHY_HANDLE_T phy, 1255230557Sjimharris SCIC_PHY_COUNTER_ID_T counter_id 1256230557Sjimharris) 1257230557Sjimharris{ 1258230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1259230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 1260230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1261230557Sjimharris 1262230557Sjimharris SCIC_LOG_TRACE(( 1263230557Sjimharris sci_base_object_get_logger(this_phy), 1264230557Sjimharris SCIC_LOG_OBJECT_PHY, 1265230557Sjimharris "scic_phy_enable_counter(0x%x, 0x%x) enter\n", 1266230557Sjimharris this_phy, counter_id 1267230557Sjimharris )); 1268230557Sjimharris 1269230557Sjimharris switch(counter_id) 1270230557Sjimharris { 1271230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT: 1272230557Sjimharris { 1273230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1274230557Sjimharris control |= (1 << SCU_ERR_CNT_RX_DONE_ACK_NAK_TIMEOUT_INDEX); 1275230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1276230557Sjimharris } 1277230557Sjimharris break; 1278230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT: 1279230557Sjimharris { 1280230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1281230557Sjimharris control |= (1 << SCU_ERR_CNT_TX_DONE_ACK_NAK_TIMEOUT_INDEX); 1282230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1283230557Sjimharris } 1284230557Sjimharris break; 1285230557Sjimharris case SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED: 1286230557Sjimharris { 1287230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1288230557Sjimharris control |= (1 << SCU_ERR_CNT_INACTIVITY_TIMER_EXPIRED_INDEX); 1289230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1290230557Sjimharris } 1291230557Sjimharris break; 1292230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT: 1293230557Sjimharris { 1294230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1295230557Sjimharris control |= (1 << SCU_ERR_CNT_RX_DONE_CREDIT_TIMEOUT_INDEX); 1296230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1297230557Sjimharris } 1298230557Sjimharris break; 1299230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT: 1300230557Sjimharris { 1301230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1302230557Sjimharris control |= (1 << SCU_ERR_CNT_TX_DONE_CREDIT_TIMEOUT_INDEX); 1303230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1304230557Sjimharris } 1305230557Sjimharris break; 1306230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED: 1307230557Sjimharris { 1308230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1309230557Sjimharris control |= (1 << SCU_ERR_CNT_RX_CREDIT_BLOCKED_RECEIVED_INDEX); 1310230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1311230557Sjimharris } 1312230557Sjimharris break; 1313230557Sjimharris 1314230557Sjimharris // These error counters are enabled by default, and cannot be 1315230557Sjimharris // disabled. Return SCI_SUCCESS to denote that they are 1316230557Sjimharris // enabled, hiding the fact that enabling the counter is 1317230557Sjimharris // a no-op. 1318230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME: 1319230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_FRAME: 1320230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_DWORD: 1321230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD: 1322230557Sjimharris case SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR: 1323230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR: 1324230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR: 1325230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME: 1326230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT: 1327230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE: 1328230557Sjimharris case SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR: 1329230557Sjimharris break; 1330230557Sjimharris 1331230557Sjimharris default: 1332230557Sjimharris status = SCI_FAILURE; 1333230557Sjimharris break; 1334230557Sjimharris } 1335230557Sjimharris return status; 1336230557Sjimharris} 1337230557Sjimharris 1338230557Sjimharris// --------------------------------------------------------------------------- 1339230557Sjimharris 1340230557SjimharrisSCI_STATUS scic_phy_disable_counter( 1341230557Sjimharris SCI_PHY_HANDLE_T phy, 1342230557Sjimharris SCIC_PHY_COUNTER_ID_T counter_id 1343230557Sjimharris) 1344230557Sjimharris{ 1345230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1346230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 1347230557Sjimharris 1348230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1349230557Sjimharris 1350230557Sjimharris SCIC_LOG_TRACE(( 1351230557Sjimharris sci_base_object_get_logger(this_phy), 1352230557Sjimharris SCIC_LOG_OBJECT_PHY, 1353230557Sjimharris "scic_phy_disable_counter(0x%x, 0x%x) enter\n", 1354230557Sjimharris this_phy, counter_id 1355230557Sjimharris )); 1356230557Sjimharris 1357230557Sjimharris switch(counter_id) 1358230557Sjimharris { 1359230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT: 1360230557Sjimharris { 1361230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1362230557Sjimharris control &= ~(1 << SCU_ERR_CNT_RX_DONE_ACK_NAK_TIMEOUT_INDEX); 1363230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1364230557Sjimharris } 1365230557Sjimharris break; 1366230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT: 1367230557Sjimharris { 1368230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1369230557Sjimharris control &= ~(1 << SCU_ERR_CNT_TX_DONE_ACK_NAK_TIMEOUT_INDEX); 1370230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1371230557Sjimharris } 1372230557Sjimharris break; 1373230557Sjimharris case SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED: 1374230557Sjimharris { 1375230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1376230557Sjimharris control &= ~(1 << SCU_ERR_CNT_INACTIVITY_TIMER_EXPIRED_INDEX); 1377230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1378230557Sjimharris } 1379230557Sjimharris break; 1380230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT: 1381230557Sjimharris { 1382230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1383230557Sjimharris control &= ~(1 << SCU_ERR_CNT_RX_DONE_CREDIT_TIMEOUT_INDEX); 1384230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1385230557Sjimharris } 1386230557Sjimharris break; 1387230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT: 1388230557Sjimharris { 1389230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1390230557Sjimharris control &= ~(1 << SCU_ERR_CNT_TX_DONE_CREDIT_TIMEOUT_INDEX); 1391230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1392230557Sjimharris } 1393230557Sjimharris break; 1394230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED: 1395230557Sjimharris { 1396230557Sjimharris U32 control = SCU_SAS_ECENCR_READ(this_phy); 1397230557Sjimharris control &= ~(1 << SCU_ERR_CNT_RX_CREDIT_BLOCKED_RECEIVED_INDEX); 1398230557Sjimharris SCU_SAS_ECENCR_WRITE(this_phy, control); 1399230557Sjimharris } 1400230557Sjimharris break; 1401230557Sjimharris 1402230557Sjimharris // These error counters cannot be disabled, so return SCI_FAILURE. 1403230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME: 1404230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_FRAME: 1405230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_DWORD: 1406230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD: 1407230557Sjimharris case SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR: 1408230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR: 1409230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR: 1410230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME: 1411230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT: 1412230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE: 1413230557Sjimharris case SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR: 1414230557Sjimharris default: 1415230557Sjimharris status = SCI_FAILURE; 1416230557Sjimharris break; 1417230557Sjimharris } 1418230557Sjimharris return status; 1419230557Sjimharris} 1420230557Sjimharris 1421230557Sjimharris// --------------------------------------------------------------------------- 1422230557Sjimharris 1423230557SjimharrisSCI_STATUS scic_phy_get_counter( 1424230557Sjimharris SCI_PHY_HANDLE_T phy, 1425230557Sjimharris SCIC_PHY_COUNTER_ID_T counter_id, 1426230557Sjimharris U32 * data 1427230557Sjimharris) 1428230557Sjimharris{ 1429230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1430230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 1431230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1432230557Sjimharris 1433230557Sjimharris SCIC_LOG_TRACE(( 1434230557Sjimharris sci_base_object_get_logger(this_phy), 1435230557Sjimharris SCIC_LOG_OBJECT_PHY, 1436230557Sjimharris "scic_phy_get_counter(0x%x, 0x%x) enter\n", 1437230557Sjimharris this_phy, counter_id 1438230557Sjimharris )); 1439230557Sjimharris 1440230557Sjimharris switch(counter_id) 1441230557Sjimharris { 1442230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME: 1443230557Sjimharris *data = scu_link_layer_register_read(this_phy, received_frame_count); 1444230557Sjimharris break; 1445230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_FRAME: 1446230557Sjimharris *data = scu_link_layer_register_read(this_phy, transmit_frame_count); 1447230557Sjimharris break; 1448230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_DWORD: 1449230557Sjimharris *data = scu_link_layer_register_read(this_phy, received_dword_count); 1450230557Sjimharris break; 1451230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD: 1452230557Sjimharris *data = scu_link_layer_register_read(this_phy, transmit_dword_count); 1453230557Sjimharris break; 1454230557Sjimharris case SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR: 1455230557Sjimharris *data = scu_link_layer_register_read(this_phy, loss_of_sync_error_count); 1456230557Sjimharris break; 1457230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR: 1458230557Sjimharris *data = scu_link_layer_register_read(this_phy, running_disparity_error_count); 1459230557Sjimharris break; 1460230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR: 1461230557Sjimharris *data = scu_link_layer_register_read(this_phy, received_frame_crc_error_count); 1462230557Sjimharris break; 1463230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT: 1464230557Sjimharris *data = this_phy->error_counter[SCU_ERR_CNT_RX_DONE_ACK_NAK_TIMEOUT_INDEX]; 1465230557Sjimharris break; 1466230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT: 1467230557Sjimharris *data = this_phy->error_counter[SCU_ERR_CNT_TX_DONE_ACK_NAK_TIMEOUT_INDEX]; 1468230557Sjimharris break; 1469230557Sjimharris case SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED: 1470230557Sjimharris *data = this_phy->error_counter[SCU_ERR_CNT_INACTIVITY_TIMER_EXPIRED_INDEX]; 1471230557Sjimharris break; 1472230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT: 1473230557Sjimharris *data = this_phy->error_counter[SCU_ERR_CNT_RX_DONE_CREDIT_TIMEOUT_INDEX]; 1474230557Sjimharris break; 1475230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT: 1476230557Sjimharris *data = this_phy->error_counter[SCU_ERR_CNT_TX_DONE_CREDIT_TIMEOUT_INDEX]; 1477230557Sjimharris break; 1478230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED: 1479230557Sjimharris *data = this_phy->error_counter[SCU_ERR_CNT_RX_CREDIT_BLOCKED_RECEIVED_INDEX]; 1480230557Sjimharris break; 1481230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME: 1482230557Sjimharris *data = scu_link_layer_register_read(this_phy, received_short_frame_count); 1483230557Sjimharris break; 1484230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT: 1485230557Sjimharris *data = scu_link_layer_register_read(this_phy, received_frame_without_credit_count); 1486230557Sjimharris break; 1487230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE: 1488230557Sjimharris *data = scu_link_layer_register_read(this_phy, received_frame_after_done_count); 1489230557Sjimharris break; 1490230557Sjimharris case SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR: 1491230557Sjimharris *data = scu_link_layer_register_read(this_phy, phy_reset_problem_count); 1492230557Sjimharris break; 1493230557Sjimharris default: 1494230557Sjimharris status = SCI_FAILURE; 1495230557Sjimharris break; 1496230557Sjimharris } 1497230557Sjimharris 1498230557Sjimharris return status; 1499230557Sjimharris} 1500230557Sjimharris 1501230557Sjimharris// --------------------------------------------------------------------------- 1502230557Sjimharris 1503230557SjimharrisSCI_STATUS scic_phy_clear_counter( 1504230557Sjimharris SCI_PHY_HANDLE_T phy, 1505230557Sjimharris SCIC_PHY_COUNTER_ID_T counter_id 1506230557Sjimharris) 1507230557Sjimharris{ 1508230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1509230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 1510230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1511230557Sjimharris 1512230557Sjimharris SCIC_LOG_TRACE(( 1513230557Sjimharris sci_base_object_get_logger(this_phy), 1514230557Sjimharris SCIC_LOG_OBJECT_PHY, 1515230557Sjimharris "scic_phy_clear_counter(0x%x, 0x%x) enter\n", 1516230557Sjimharris this_phy, counter_id 1517230557Sjimharris )); 1518230557Sjimharris 1519230557Sjimharris switch(counter_id) 1520230557Sjimharris { 1521230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME: 1522230557Sjimharris scu_link_layer_register_write(this_phy, received_frame_count, 0); 1523230557Sjimharris break; 1524230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_FRAME: 1525230557Sjimharris scu_link_layer_register_write(this_phy, transmit_frame_count, 0); 1526230557Sjimharris break; 1527230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_DWORD: 1528230557Sjimharris scu_link_layer_register_write(this_phy, received_dword_count, 0); 1529230557Sjimharris break; 1530230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD: 1531230557Sjimharris scu_link_layer_register_write(this_phy, transmit_dword_count, 0); 1532230557Sjimharris break; 1533230557Sjimharris case SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR: 1534230557Sjimharris scu_link_layer_register_write(this_phy, loss_of_sync_error_count, 0); 1535230557Sjimharris break; 1536230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR: 1537230557Sjimharris scu_link_layer_register_write(this_phy, running_disparity_error_count, 0); 1538230557Sjimharris break; 1539230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR: 1540230557Sjimharris scu_link_layer_register_write(this_phy, received_frame_crc_error_count, 0); 1541230557Sjimharris break; 1542230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT: 1543230557Sjimharris this_phy->error_counter[SCU_ERR_CNT_RX_DONE_ACK_NAK_TIMEOUT_INDEX] = 0; 1544230557Sjimharris break; 1545230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT: 1546230557Sjimharris this_phy->error_counter[SCU_ERR_CNT_TX_DONE_ACK_NAK_TIMEOUT_INDEX] = 0; 1547230557Sjimharris break; 1548230557Sjimharris case SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED: 1549230557Sjimharris this_phy->error_counter[SCU_ERR_CNT_INACTIVITY_TIMER_EXPIRED_INDEX] = 0; 1550230557Sjimharris break; 1551230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT: 1552230557Sjimharris this_phy->error_counter[SCU_ERR_CNT_RX_DONE_CREDIT_TIMEOUT_INDEX] = 0; 1553230557Sjimharris break; 1554230557Sjimharris case SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT: 1555230557Sjimharris this_phy->error_counter[SCU_ERR_CNT_TX_DONE_CREDIT_TIMEOUT_INDEX] = 0; 1556230557Sjimharris break; 1557230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED: 1558230557Sjimharris this_phy->error_counter[SCU_ERR_CNT_RX_CREDIT_BLOCKED_RECEIVED_INDEX] = 0; 1559230557Sjimharris break; 1560230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME: 1561230557Sjimharris scu_link_layer_register_write(this_phy, received_short_frame_count, 0); 1562230557Sjimharris break; 1563230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT: 1564230557Sjimharris scu_link_layer_register_write(this_phy, received_frame_without_credit_count, 0); 1565230557Sjimharris break; 1566230557Sjimharris case SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE: 1567230557Sjimharris scu_link_layer_register_write(this_phy, received_frame_after_done_count, 0); 1568230557Sjimharris break; 1569230557Sjimharris case SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR: 1570230557Sjimharris scu_link_layer_register_write(this_phy, phy_reset_problem_count, 0); 1571230557Sjimharris break; 1572230557Sjimharris default: 1573230557Sjimharris status = SCI_FAILURE; 1574230557Sjimharris } 1575230557Sjimharris 1576230557Sjimharris return status; 1577230557Sjimharris} 1578230557Sjimharris 1579230557Sjimharris#endif // !defined(DISABLE_PHY_COUNTERS) 1580230557Sjimharris 1581230557SjimharrisSCI_STATUS scic_phy_stop( 1582230557Sjimharris SCI_PHY_HANDLE_T phy 1583230557Sjimharris) 1584230557Sjimharris{ 1585230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1586230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1587230557Sjimharris 1588230557Sjimharris SCIC_LOG_TRACE(( 1589230557Sjimharris sci_base_object_get_logger(this_phy), 1590230557Sjimharris SCIC_LOG_OBJECT_PHY, 1591230557Sjimharris "scic_phy_stop(this_phy:0x%x)\n", 1592230557Sjimharris this_phy 1593230557Sjimharris )); 1594230557Sjimharris 1595230557Sjimharris return this_phy->state_handlers->parent.stop_handler(&this_phy->parent); 1596230557Sjimharris} 1597230557Sjimharris 1598230557SjimharrisSCI_STATUS scic_phy_start( 1599230557Sjimharris SCI_PHY_HANDLE_T phy 1600230557Sjimharris) 1601230557Sjimharris{ 1602230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1603230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1604230557Sjimharris 1605230557Sjimharris SCIC_LOG_TRACE(( 1606230557Sjimharris sci_base_object_get_logger(this_phy), 1607230557Sjimharris SCIC_LOG_OBJECT_PHY, 1608230557Sjimharris "scic_phy_start(this_phy:0x%x)\n", 1609230557Sjimharris this_phy 1610230557Sjimharris )); 1611230557Sjimharris 1612230557Sjimharris return this_phy->state_handlers->parent.start_handler(&this_phy->parent); 1613230557Sjimharris} 1614230557Sjimharris 1615230557Sjimharris//****************************************************************************** 1616230557Sjimharris//* PHY STATE MACHINE 1617230557Sjimharris//****************************************************************************** 1618230557Sjimharris 1619230557Sjimharris//*************************************************************************** 1620230557Sjimharris//* DEFAULT HANDLERS 1621230557Sjimharris//*************************************************************************** 1622230557Sjimharris 1623230557Sjimharris/** 1624230557Sjimharris * This is the default method for phy a start request. It will report a 1625230557Sjimharris * warning and exit. 1626230557Sjimharris * 1627230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1628230557Sjimharris * SCIC_SDS_PHY object. 1629230557Sjimharris * 1630230557Sjimharris * @return SCI_STATUS 1631230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1632230557Sjimharris */ 1633230557SjimharrisSCI_STATUS scic_sds_phy_default_start_handler( 1634230557Sjimharris SCI_BASE_PHY_T *phy 1635230557Sjimharris) 1636230557Sjimharris{ 1637230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1638230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1639230557Sjimharris 1640230557Sjimharris SCIC_LOG_WARNING(( 1641230557Sjimharris sci_base_object_get_logger(this_phy), 1642230557Sjimharris SCIC_LOG_OBJECT_PHY, 1643230557Sjimharris "SCIC Phy 0x%08x requested to start from invalid state %d\n", 1644230557Sjimharris this_phy, 1645230557Sjimharris sci_base_state_machine_get_state(&this_phy->parent.state_machine) 1646230557Sjimharris )); 1647230557Sjimharris 1648230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1649230557Sjimharris 1650230557Sjimharris} 1651230557Sjimharris 1652230557Sjimharris/** 1653230557Sjimharris * This is the default method for phy a stop request. It will report a 1654230557Sjimharris * warning and exit. 1655230557Sjimharris * 1656230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1657230557Sjimharris * SCIC_SDS_PHY object. 1658230557Sjimharris * 1659230557Sjimharris * @return SCI_STATUS 1660230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1661230557Sjimharris */ 1662230557SjimharrisSCI_STATUS scic_sds_phy_default_stop_handler( 1663230557Sjimharris SCI_BASE_PHY_T *phy 1664230557Sjimharris) 1665230557Sjimharris{ 1666230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1667230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1668230557Sjimharris 1669230557Sjimharris SCIC_LOG_WARNING(( 1670230557Sjimharris sci_base_object_get_logger(this_phy), 1671230557Sjimharris SCIC_LOG_OBJECT_PHY, 1672230557Sjimharris "SCIC Phy 0x%08x requested to stop from invalid state %d\n", 1673230557Sjimharris this_phy, 1674230557Sjimharris sci_base_state_machine_get_state(&this_phy->parent.state_machine) 1675230557Sjimharris )); 1676230557Sjimharris 1677230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1678230557Sjimharris} 1679230557Sjimharris 1680230557Sjimharris/** 1681230557Sjimharris * This is the default method for phy a reset request. It will report a 1682230557Sjimharris * warning and exit. 1683230557Sjimharris * 1684230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1685230557Sjimharris * SCIC_SDS_PHY object. 1686230557Sjimharris * 1687230557Sjimharris * @return SCI_STATUS 1688230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1689230557Sjimharris */ 1690230557SjimharrisSCI_STATUS scic_sds_phy_default_reset_handler( 1691230557Sjimharris SCI_BASE_PHY_T * phy 1692230557Sjimharris) 1693230557Sjimharris{ 1694230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1695230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1696230557Sjimharris 1697230557Sjimharris SCIC_LOG_WARNING(( 1698230557Sjimharris sci_base_object_get_logger(this_phy), 1699230557Sjimharris SCIC_LOG_OBJECT_PHY, 1700230557Sjimharris "SCIC Phy 0x%08x requested to reset from invalid state %d\n", 1701230557Sjimharris this_phy, 1702230557Sjimharris sci_base_state_machine_get_state(&this_phy->parent.state_machine) 1703230557Sjimharris )); 1704230557Sjimharris 1705230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1706230557Sjimharris} 1707230557Sjimharris 1708230557Sjimharris/** 1709230557Sjimharris * This is the default method for phy a destruct request. It will report a 1710230557Sjimharris * warning and exit. 1711230557Sjimharris * 1712230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1713230557Sjimharris * SCIC_SDS_PHY object. 1714230557Sjimharris * 1715230557Sjimharris * @return SCI_STATUS 1716230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1717230557Sjimharris */ 1718230557SjimharrisSCI_STATUS scic_sds_phy_default_destroy_handler( 1719230557Sjimharris SCI_BASE_PHY_T *phy 1720230557Sjimharris) 1721230557Sjimharris{ 1722230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1723230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1724230557Sjimharris 1725230557Sjimharris /// @todo Implement something for the default 1726230557Sjimharris SCIC_LOG_WARNING(( 1727230557Sjimharris sci_base_object_get_logger(this_phy), 1728230557Sjimharris SCIC_LOG_OBJECT_PHY, 1729230557Sjimharris "SCIC Phy 0x%08x requested to destroy from invalid state %d\n", 1730230557Sjimharris this_phy, 1731230557Sjimharris sci_base_state_machine_get_state(&this_phy->parent.state_machine) 1732230557Sjimharris )); 1733230557Sjimharris 1734230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1735230557Sjimharris} 1736230557Sjimharris 1737230557Sjimharris/** 1738230557Sjimharris * This is the default method for a phy frame handling request. It will 1739230557Sjimharris * report a warning, release the frame and exit. 1740230557Sjimharris * 1741230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1742230557Sjimharris * SCIC_SDS_PHY object. 1743230557Sjimharris * @param[in] frame_index This is the frame index that was received from the 1744230557Sjimharris * SCU hardware. 1745230557Sjimharris * 1746230557Sjimharris * @return SCI_STATUS 1747230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1748230557Sjimharris */ 1749230557SjimharrisSCI_STATUS scic_sds_phy_default_frame_handler( 1750230557Sjimharris SCIC_SDS_PHY_T *this_phy, 1751230557Sjimharris U32 frame_index 1752230557Sjimharris) 1753230557Sjimharris{ 1754230557Sjimharris SCIC_LOG_WARNING(( 1755230557Sjimharris sci_base_object_get_logger(this_phy), 1756230557Sjimharris SCIC_LOG_OBJECT_PHY, 1757298931Spfg "SCIC Phy 0x%08x received unexpected frame data %d while in state %d\n", 1758230557Sjimharris this_phy, frame_index, 1759230557Sjimharris sci_base_state_machine_get_state(&this_phy->parent.state_machine) 1760230557Sjimharris )); 1761230557Sjimharris 1762230557Sjimharris scic_sds_controller_release_frame( 1763230557Sjimharris scic_sds_phy_get_controller(this_phy), frame_index); 1764230557Sjimharris 1765230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1766230557Sjimharris} 1767230557Sjimharris 1768230557Sjimharris/** 1769230557Sjimharris * This is the default method for a phy event handler. It will report a 1770230557Sjimharris * warning and exit. 1771230557Sjimharris * 1772230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1773230557Sjimharris * SCIC_SDS_PHY object. 1774230557Sjimharris * @param[in] event_code This is the event code that was received from the SCU 1775230557Sjimharris * hardware. 1776230557Sjimharris * 1777230557Sjimharris * @return SCI_STATUS 1778230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1779230557Sjimharris */ 1780230557SjimharrisSCI_STATUS scic_sds_phy_default_event_handler( 1781230557Sjimharris SCIC_SDS_PHY_T *this_phy, 1782230557Sjimharris U32 event_code 1783230557Sjimharris) 1784230557Sjimharris{ 1785230557Sjimharris SCIC_LOG_WARNING(( 1786230557Sjimharris sci_base_object_get_logger(this_phy), 1787230557Sjimharris SCIC_LOG_OBJECT_PHY, 1788230557Sjimharris "SCIC Phy 0x%08x received unexpected event status %x while in state %d\n", 1789230557Sjimharris this_phy, event_code, 1790230557Sjimharris sci_base_state_machine_get_state(&this_phy->parent.state_machine) 1791230557Sjimharris )); 1792230557Sjimharris 1793230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1794230557Sjimharris} 1795230557Sjimharris 1796230557Sjimharris/** 1797230557Sjimharris * This is the default method for a phy consume power handler. It will report 1798230557Sjimharris * a warning and exit. 1799230557Sjimharris * 1800230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1801230557Sjimharris * SCIC_SDS_PHY object. 1802230557Sjimharris * 1803230557Sjimharris * @return SCI_STATUS 1804230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1805230557Sjimharris */ 1806230557SjimharrisSCI_STATUS scic_sds_phy_default_consume_power_handler( 1807230557Sjimharris SCIC_SDS_PHY_T *this_phy 1808230557Sjimharris) 1809230557Sjimharris{ 1810230557Sjimharris SCIC_LOG_WARNING(( 1811230557Sjimharris sci_base_object_get_logger(this_phy), 1812230557Sjimharris SCIC_LOG_OBJECT_PHY, 1813230557Sjimharris "SCIC Phy 0x%08x given unexpected permission to consume power while in state %d\n", 1814230557Sjimharris this_phy, 1815230557Sjimharris sci_base_state_machine_get_state(&this_phy->parent.state_machine) 1816230557Sjimharris )); 1817230557Sjimharris 1818230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1819230557Sjimharris} 1820230557Sjimharris 1821230557Sjimharris//****************************************************************************** 1822230557Sjimharris//* PHY STOPPED STATE HANDLERS 1823230557Sjimharris//****************************************************************************** 1824230557Sjimharris 1825230557Sjimharris/** 1826230557Sjimharris * This method takes the SCIC_SDS_PHY from a stopped state and attempts to 1827230557Sjimharris * start it. 1828230557Sjimharris * - The phy state machine is transitioned to the 1829230557Sjimharris * SCI_BASE_PHY_STATE_STARTING. 1830230557Sjimharris * 1831230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1832230557Sjimharris * SCIC_SDS_PHY object. 1833230557Sjimharris * 1834230557Sjimharris * @return SCI_STATUS 1835230557Sjimharris * @retval SCI_SUCCESS 1836230557Sjimharris */ 1837230557Sjimharrisstatic 1838230557SjimharrisSCI_STATUS scic_sds_phy_stopped_state_start_handler( 1839230557Sjimharris SCI_BASE_PHY_T *phy 1840230557Sjimharris) 1841230557Sjimharris{ 1842230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1843230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1844230557Sjimharris 1845230557Sjimharris 1846230557Sjimharris 1847230557Sjimharris // Create the SIGNATURE FIS Timeout timer for this phy 1848230557Sjimharris this_phy->sata_timeout_timer = scic_cb_timer_create( 1849230557Sjimharris scic_sds_phy_get_controller(this_phy), 1850230557Sjimharris scic_sds_phy_sata_timeout, 1851230557Sjimharris this_phy 1852230557Sjimharris ); 1853230557Sjimharris 1854230557Sjimharris if (this_phy->sata_timeout_timer != NULL) 1855230557Sjimharris { 1856230557Sjimharris sci_base_state_machine_change_state( 1857230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 1858230557Sjimharris SCI_BASE_PHY_STATE_STARTING 1859230557Sjimharris ); 1860230557Sjimharris } 1861230557Sjimharris 1862230557Sjimharris return SCI_SUCCESS; 1863230557Sjimharris} 1864230557Sjimharris 1865230557Sjimharris/** 1866230557Sjimharris * This method takes the SCIC_SDS_PHY from a stopped state and destroys it. 1867230557Sjimharris * - This function takes no action. 1868230557Sjimharris * 1869298931Spfg * @todo Shouldn't this function transition the SCI_BASE_PHY::state_machine to 1870230557Sjimharris * the SCI_BASE_PHY_STATE_FINAL? 1871230557Sjimharris * 1872230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1873230557Sjimharris * SCIC_SDS_PHY object. 1874230557Sjimharris * 1875230557Sjimharris * @return SCI_STATUS 1876230557Sjimharris * @retval SCI_SUCCESS 1877230557Sjimharris */ 1878230557Sjimharrisstatic 1879230557SjimharrisSCI_STATUS scic_sds_phy_stopped_state_destroy_handler( 1880230557Sjimharris SCI_BASE_PHY_T *phy 1881230557Sjimharris) 1882230557Sjimharris{ 1883230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1884230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1885230557Sjimharris 1886230557Sjimharris /// @todo what do we actually need to do here? 1887230557Sjimharris return SCI_SUCCESS; 1888230557Sjimharris} 1889230557Sjimharris 1890230557Sjimharris//****************************************************************************** 1891230557Sjimharris//* PHY STARTING STATE HANDLERS 1892230557Sjimharris//****************************************************************************** 1893230557Sjimharris 1894230557Sjimharris// All of these state handlers are mapped to the starting sub-state machine 1895230557Sjimharris 1896230557Sjimharris//****************************************************************************** 1897230557Sjimharris//* PHY READY STATE HANDLERS 1898230557Sjimharris//****************************************************************************** 1899230557Sjimharris 1900230557Sjimharris/** 1901230557Sjimharris * This method takes the SCIC_SDS_PHY from a ready state and attempts to stop 1902230557Sjimharris * it. 1903230557Sjimharris * - The phy state machine is transitioned to the SCI_BASE_PHY_STATE_STOPPED. 1904230557Sjimharris * 1905230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1906230557Sjimharris * SCIC_SDS_PHY object. 1907230557Sjimharris * 1908230557Sjimharris * @return SCI_STATUS 1909230557Sjimharris * @retval SCI_SUCCESS 1910230557Sjimharris */ 1911230557Sjimharrisstatic 1912230557SjimharrisSCI_STATUS scic_sds_phy_ready_state_stop_handler( 1913230557Sjimharris SCI_BASE_PHY_T *phy 1914230557Sjimharris) 1915230557Sjimharris{ 1916230557Sjimharris SCIC_SDS_PHY_T *this_phy; 1917230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1918230557Sjimharris 1919230557Sjimharris sci_base_state_machine_change_state( 1920230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 1921230557Sjimharris SCI_BASE_PHY_STATE_STOPPED 1922230557Sjimharris ); 1923230557Sjimharris 1924230557Sjimharris scic_sds_controller_link_down( 1925230557Sjimharris scic_sds_phy_get_controller(this_phy), 1926230557Sjimharris scic_sds_phy_get_port(this_phy), 1927230557Sjimharris this_phy 1928230557Sjimharris ); 1929230557Sjimharris 1930230557Sjimharris return SCI_SUCCESS; 1931230557Sjimharris} 1932230557Sjimharris 1933230557Sjimharris/** 1934230557Sjimharris * This method takes the SCIC_SDS_PHY from a ready state and attempts to reset 1935230557Sjimharris * it. 1936230557Sjimharris * - The phy state machine is transitioned to the SCI_BASE_PHY_STATE_STARTING. 1937230557Sjimharris * 1938230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 1939230557Sjimharris * SCIC_SDS_PHY object. 1940230557Sjimharris * 1941230557Sjimharris * @return SCI_STATUS 1942230557Sjimharris * @retval SCI_SUCCESS 1943230557Sjimharris */ 1944230557Sjimharrisstatic 1945230557SjimharrisSCI_STATUS scic_sds_phy_ready_state_reset_handler( 1946230557Sjimharris SCI_BASE_PHY_T * phy 1947230557Sjimharris) 1948230557Sjimharris{ 1949230557Sjimharris SCIC_SDS_PHY_T * this_phy; 1950230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 1951230557Sjimharris 1952230557Sjimharris sci_base_state_machine_change_state( 1953230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 1954230557Sjimharris SCI_BASE_PHY_STATE_RESETTING 1955230557Sjimharris ); 1956230557Sjimharris 1957230557Sjimharris return SCI_SUCCESS; 1958230557Sjimharris} 1959230557Sjimharris 1960230557Sjimharris/** 1961230557Sjimharris * This method request the SCIC_SDS_PHY handle the received event. The only 1962230557Sjimharris * event that we are interested in while in the ready state is the link 1963230557Sjimharris * failure event. 1964230557Sjimharris * - decoded event is a link failure 1965230557Sjimharris * - transition the SCIC_SDS_PHY back to the SCI_BASE_PHY_STATE_STARTING 1966230557Sjimharris * state. 1967298931Spfg * - any other event received will report a warning message 1968230557Sjimharris * 1969230557Sjimharris * @param[in] phy This is the SCIC_SDS_PHY object which has received the 1970230557Sjimharris * event. 1971230557Sjimharris * 1972230557Sjimharris * @return SCI_STATUS 1973230557Sjimharris * @retval SCI_SUCCESS if the event received is a link failure 1974230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE for any other event received. 1975230557Sjimharris */ 1976230557Sjimharrisstatic 1977230557SjimharrisSCI_STATUS scic_sds_phy_ready_state_event_handler( 1978230557Sjimharris SCIC_SDS_PHY_T *this_phy, 1979230557Sjimharris U32 event_code 1980230557Sjimharris) 1981230557Sjimharris{ 1982230557Sjimharris SCI_STATUS result = SCI_FAILURE; 1983230557Sjimharris 1984230557Sjimharris switch (scu_get_event_code(event_code)) 1985230557Sjimharris { 1986230557Sjimharris case SCU_EVENT_LINK_FAILURE: 1987230557Sjimharris // Link failure change state back to the starting state 1988230557Sjimharris sci_base_state_machine_change_state( 1989230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 1990230557Sjimharris SCI_BASE_PHY_STATE_STARTING 1991230557Sjimharris ); 1992230557Sjimharris 1993230557Sjimharris result = SCI_SUCCESS; 1994230557Sjimharris break; 1995230557Sjimharris 1996230557Sjimharris case SCU_EVENT_BROADCAST_CHANGE: 1997230557Sjimharris // Broadcast change received. Notify the port. 1998230557Sjimharris if (scic_sds_phy_get_port(this_phy) != SCI_INVALID_HANDLE) 1999230557Sjimharris scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy); 2000230557Sjimharris else 2001230557Sjimharris this_phy->bcn_received_while_port_unassigned = TRUE; 2002230557Sjimharris break; 2003230557Sjimharris 2004230557Sjimharris case SCU_EVENT_ERR_CNT(RX_CREDIT_BLOCKED_RECEIVED): 2005230557Sjimharris case SCU_EVENT_ERR_CNT(TX_DONE_CREDIT_TIMEOUT): 2006230557Sjimharris case SCU_EVENT_ERR_CNT(RX_DONE_CREDIT_TIMEOUT): 2007230557Sjimharris case SCU_EVENT_ERR_CNT(INACTIVITY_TIMER_EXPIRED): 2008230557Sjimharris case SCU_EVENT_ERR_CNT(TX_DONE_ACK_NAK_TIMEOUT): 2009230557Sjimharris case SCU_EVENT_ERR_CNT(RX_DONE_ACK_NAK_TIMEOUT): 2010230557Sjimharris { 2011230557Sjimharris U32 error_counter_index = 2012230557Sjimharris scu_get_event_specifier(event_code) >> SCU_EVENT_SPECIFIC_CODE_SHIFT; 2013230557Sjimharris 2014230557Sjimharris this_phy->error_counter[error_counter_index]++; 2015230557Sjimharris result = SCI_SUCCESS; 2016230557Sjimharris } 2017230557Sjimharris break; 2018230557Sjimharris 2019230557Sjimharris default: 2020230557Sjimharris SCIC_LOG_WARNING(( 2021230557Sjimharris sci_base_object_get_logger(this_phy), 2022230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 2023298931Spfg "SCIC PHY 0x%x ready state machine received unexpected event_code %x\n", 2024230557Sjimharris this_phy, event_code 2025230557Sjimharris )); 2026230557Sjimharris result = SCI_FAILURE_INVALID_STATE; 2027230557Sjimharris break; 2028230557Sjimharris } 2029230557Sjimharris 2030230557Sjimharris return result; 2031230557Sjimharris} 2032230557Sjimharris 2033230557Sjimharris// --------------------------------------------------------------------------- 2034230557Sjimharris 2035230557Sjimharris/** 2036230557Sjimharris * This is the resetting state event handler. 2037230557Sjimharris * 2038230557Sjimharris * @param[in] this_phy This is the SCIC_SDS_PHY object which is receiving the 2039230557Sjimharris * event. 2040230557Sjimharris * @param[in] event_code This is the event code to be processed. 2041230557Sjimharris * 2042230557Sjimharris * @return SCI_STATUS 2043230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 2044230557Sjimharris */ 2045230557Sjimharrisstatic 2046230557SjimharrisSCI_STATUS scic_sds_phy_resetting_state_event_handler( 2047230557Sjimharris SCIC_SDS_PHY_T *this_phy, 2048230557Sjimharris U32 event_code 2049230557Sjimharris) 2050230557Sjimharris{ 2051230557Sjimharris SCI_STATUS result = SCI_FAILURE; 2052230557Sjimharris 2053230557Sjimharris switch (scu_get_event_code(event_code)) 2054230557Sjimharris { 2055230557Sjimharris case SCU_EVENT_HARD_RESET_TRANSMITTED: 2056230557Sjimharris // Link failure change state back to the starting state 2057230557Sjimharris sci_base_state_machine_change_state( 2058230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 2059230557Sjimharris SCI_BASE_PHY_STATE_STARTING 2060230557Sjimharris ); 2061230557Sjimharris 2062230557Sjimharris result = SCI_SUCCESS; 2063230557Sjimharris break; 2064230557Sjimharris 2065230557Sjimharris default: 2066230557Sjimharris SCIC_LOG_WARNING(( 2067230557Sjimharris sci_base_object_get_logger(this_phy), 2068230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 2069298931Spfg "SCIC PHY 0x%x resetting state machine received unexpected event_code %x\n", 2070230557Sjimharris this_phy, event_code 2071230557Sjimharris )); 2072230557Sjimharris 2073230557Sjimharris result = SCI_FAILURE_INVALID_STATE; 2074230557Sjimharris break; 2075230557Sjimharris } 2076230557Sjimharris 2077230557Sjimharris return result; 2078230557Sjimharris} 2079230557Sjimharris 2080230557Sjimharris// --------------------------------------------------------------------------- 2081230557Sjimharris 2082230557SjimharrisSCIC_SDS_PHY_STATE_HANDLER_T 2083230557Sjimharris scic_sds_phy_state_handler_table[SCI_BASE_PHY_MAX_STATES] = 2084230557Sjimharris{ 2085230557Sjimharris // SCI_BASE_PHY_STATE_INITIAL 2086230557Sjimharris { 2087230557Sjimharris { 2088230557Sjimharris scic_sds_phy_default_start_handler, 2089230557Sjimharris scic_sds_phy_default_stop_handler, 2090230557Sjimharris scic_sds_phy_default_reset_handler, 2091230557Sjimharris scic_sds_phy_default_destroy_handler 2092230557Sjimharris }, 2093230557Sjimharris scic_sds_phy_default_frame_handler, 2094230557Sjimharris scic_sds_phy_default_event_handler, 2095230557Sjimharris scic_sds_phy_default_consume_power_handler 2096230557Sjimharris }, 2097230557Sjimharris // SCI_BASE_PHY_STATE_STOPPED 2098230557Sjimharris { 2099230557Sjimharris { 2100230557Sjimharris scic_sds_phy_stopped_state_start_handler, 2101230557Sjimharris scic_sds_phy_default_stop_handler, 2102230557Sjimharris scic_sds_phy_default_reset_handler, 2103230557Sjimharris scic_sds_phy_stopped_state_destroy_handler 2104230557Sjimharris }, 2105230557Sjimharris scic_sds_phy_default_frame_handler, 2106230557Sjimharris scic_sds_phy_default_event_handler, 2107230557Sjimharris scic_sds_phy_default_consume_power_handler 2108230557Sjimharris }, 2109230557Sjimharris // SCI_BASE_PHY_STATE_STARTING 2110230557Sjimharris { 2111230557Sjimharris { 2112230557Sjimharris scic_sds_phy_default_start_handler, 2113230557Sjimharris scic_sds_phy_default_stop_handler, 2114230557Sjimharris scic_sds_phy_default_reset_handler, 2115230557Sjimharris scic_sds_phy_default_destroy_handler 2116230557Sjimharris }, 2117230557Sjimharris scic_sds_phy_default_frame_handler, 2118230557Sjimharris scic_sds_phy_default_event_handler, 2119230557Sjimharris scic_sds_phy_default_consume_power_handler 2120230557Sjimharris }, 2121230557Sjimharris // SCI_BASE_PHY_STATE_READY 2122230557Sjimharris { 2123230557Sjimharris { 2124230557Sjimharris scic_sds_phy_default_start_handler, 2125230557Sjimharris scic_sds_phy_ready_state_stop_handler, 2126230557Sjimharris scic_sds_phy_ready_state_reset_handler, 2127230557Sjimharris scic_sds_phy_default_destroy_handler 2128230557Sjimharris }, 2129230557Sjimharris scic_sds_phy_default_frame_handler, 2130230557Sjimharris scic_sds_phy_ready_state_event_handler, 2131230557Sjimharris scic_sds_phy_default_consume_power_handler 2132230557Sjimharris }, 2133230557Sjimharris // SCI_BASE_PHY_STATE_RESETTING 2134230557Sjimharris { 2135230557Sjimharris { 2136230557Sjimharris scic_sds_phy_default_start_handler, 2137230557Sjimharris scic_sds_phy_default_stop_handler, 2138230557Sjimharris scic_sds_phy_default_reset_handler, 2139230557Sjimharris scic_sds_phy_default_destroy_handler 2140230557Sjimharris }, 2141230557Sjimharris scic_sds_phy_default_frame_handler, 2142230557Sjimharris scic_sds_phy_resetting_state_event_handler, 2143230557Sjimharris scic_sds_phy_default_consume_power_handler 2144230557Sjimharris }, 2145230557Sjimharris // SCI_BASE_PHY_STATE_FINAL 2146230557Sjimharris { 2147230557Sjimharris { 2148230557Sjimharris scic_sds_phy_default_start_handler, 2149230557Sjimharris scic_sds_phy_default_stop_handler, 2150230557Sjimharris scic_sds_phy_default_reset_handler, 2151230557Sjimharris scic_sds_phy_default_destroy_handler 2152230557Sjimharris }, 2153230557Sjimharris scic_sds_phy_default_frame_handler, 2154230557Sjimharris scic_sds_phy_default_event_handler, 2155230557Sjimharris scic_sds_phy_default_consume_power_handler 2156230557Sjimharris } 2157230557Sjimharris}; 2158230557Sjimharris 2159230557Sjimharris//**************************************************************************** 2160230557Sjimharris//* PHY STATE PRIVATE METHODS 2161230557Sjimharris//**************************************************************************** 2162230557Sjimharris 2163230557Sjimharris/** 2164230557Sjimharris * This method will stop the SCIC_SDS_PHY object. This does not reset the 2165230557Sjimharris * protocol engine it just suspends it and places it in a state where it will 2166230557Sjimharris * not cause the end device to power up. 2167230557Sjimharris * 2168230557Sjimharris * @param[in] this_phy This is the SCIC_SDS_PHY object to stop. 2169230557Sjimharris * 2170230557Sjimharris * @return none 2171230557Sjimharris */ 2172230557Sjimharrisstatic 2173230557Sjimharrisvoid scu_link_layer_stop_protocol_engine( 2174230557Sjimharris SCIC_SDS_PHY_T *this_phy 2175230557Sjimharris) 2176230557Sjimharris{ 2177230557Sjimharris U32 scu_sas_pcfg_value; 2178230557Sjimharris U32 enable_spinup_value; 2179230557Sjimharris 2180230557Sjimharris // Suspend the protocol engine and place it in a sata spinup hold state 2181230557Sjimharris scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy); 2182230557Sjimharris scu_sas_pcfg_value |= ( 2183230557Sjimharris SCU_SAS_PCFG_GEN_BIT(OOB_RESET) 2184230557Sjimharris | SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE) 2185230557Sjimharris | SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) 2186230557Sjimharris ); 2187230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value); 2188230557Sjimharris 2189230557Sjimharris // Disable the notify enable spinup primitives 2190230557Sjimharris enable_spinup_value = SCU_SAS_ENSPINUP_READ(this_phy); 2191230557Sjimharris enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE); 2192230557Sjimharris SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup_value); 2193230557Sjimharris} 2194230557Sjimharris 2195230557Sjimharris/** 2196230557Sjimharris * This method will start the OOB/SN state machine for this SCIC_SDS_PHY 2197230557Sjimharris * object. 2198230557Sjimharris * 2199230557Sjimharris * @param[in] this_phy This is the SCIC_SDS_PHY object on which to start the 2200230557Sjimharris * OOB/SN state machine. 2201230557Sjimharris */ 2202230557Sjimharrisstatic 2203230557Sjimharrisvoid scu_link_layer_start_oob( 2204230557Sjimharris SCIC_SDS_PHY_T *this_phy 2205230557Sjimharris) 2206230557Sjimharris{ 2207230557Sjimharris U32 scu_sas_pcfg_value; 2208230557Sjimharris 2209230557Sjimharris /* Reset OOB sequence - start */ 2210230557Sjimharris scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy); 2211230557Sjimharris scu_sas_pcfg_value &= 2212230557Sjimharris ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) | SCU_SAS_PCFG_GEN_BIT(HARD_RESET)); 2213230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value); 2214230557Sjimharris SCU_SAS_PCFG_READ(this_phy); 2215230557Sjimharris /* Reset OOB sequence - end */ 2216230557Sjimharris 2217230557Sjimharris /* Start OOB sequence - start */ 2218230557Sjimharris scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy); 2219230557Sjimharris scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE); 2220230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value); 2221230557Sjimharris SCU_SAS_PCFG_READ(this_phy); 2222230557Sjimharris /* Start OOB sequence - end */ 2223230557Sjimharris} 2224230557Sjimharris 2225230557Sjimharris/** 2226230557Sjimharris * This method will transmit a hard reset request on the specified phy. The 2227230557Sjimharris * SCU hardware requires that we reset the OOB state machine and set the hard 2228230557Sjimharris * reset bit in the phy configuration register. 2229230557Sjimharris * We then must start OOB over with the hard reset bit set. 2230230557Sjimharris * 2231230557Sjimharris * @param[in] this_phy 2232230557Sjimharris */ 2233230557Sjimharrisstatic 2234230557Sjimharrisvoid scu_link_layer_tx_hard_reset( 2235230557Sjimharris SCIC_SDS_PHY_T *this_phy 2236230557Sjimharris) 2237230557Sjimharris{ 2238230557Sjimharris U32 phy_configuration_value; 2239230557Sjimharris 2240230557Sjimharris // SAS Phys must wait for the HARD_RESET_TX event notification to transition 2241230557Sjimharris // to the starting state. 2242230557Sjimharris phy_configuration_value = SCU_SAS_PCFG_READ(this_phy); 2243230557Sjimharris phy_configuration_value |= 2244230557Sjimharris (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) | SCU_SAS_PCFG_GEN_BIT(OOB_RESET)); 2245230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value); 2246230557Sjimharris 2247230557Sjimharris // Now take the OOB state machine out of reset 2248230557Sjimharris phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE); 2249230557Sjimharris phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET); 2250230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value); 2251230557Sjimharris} 2252230557Sjimharris 2253230557Sjimharris//**************************************************************************** 2254230557Sjimharris//* PHY BASE STATE METHODS 2255230557Sjimharris//**************************************************************************** 2256230557Sjimharris 2257230557Sjimharris/** 2258230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 2259230557Sjimharris * entering the SCI_BASE_PHY_STATE_INITIAL. 2260230557Sjimharris * - This function sets the state handlers for the phy object base state 2261230557Sjimharris * machine initial state. 2262230557Sjimharris * 2263230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 2264230557Sjimharris * SCIC_SDS_PHY object. 2265230557Sjimharris * 2266230557Sjimharris * @return none 2267230557Sjimharris */ 2268230557Sjimharrisstatic 2269230557Sjimharrisvoid scic_sds_phy_initial_state_enter( 2270230557Sjimharris SCI_BASE_OBJECT_T *object 2271230557Sjimharris) 2272230557Sjimharris{ 2273230557Sjimharris SCIC_SDS_PHY_T *this_phy; 2274230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 2275230557Sjimharris 2276230557Sjimharris scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_INITIAL); 2277230557Sjimharris} 2278230557Sjimharris 2279230557Sjimharris/** 2280230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 2281230557Sjimharris * entering the SCI_BASE_PHY_STATE_INITIAL. 2282230557Sjimharris * - This function sets the state handlers for the phy object base state 2283230557Sjimharris * machine initial state. 2284230557Sjimharris * - The SCU hardware is requested to stop the protocol engine. 2285230557Sjimharris * 2286230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 2287230557Sjimharris * SCIC_SDS_PHY object. 2288230557Sjimharris * 2289230557Sjimharris * @return none 2290230557Sjimharris */ 2291230557Sjimharrisstatic 2292230557Sjimharrisvoid scic_sds_phy_stopped_state_enter( 2293230557Sjimharris SCI_BASE_OBJECT_T *object 2294230557Sjimharris) 2295230557Sjimharris{ 2296230557Sjimharris SCIC_SDS_PHY_T *this_phy; 2297230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 2298230557Sjimharris 2299230557Sjimharris /// @todo We need to get to the controller to place this PE in a reset state 2300230557Sjimharris scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STOPPED); 2301230557Sjimharris 2302230557Sjimharris if (this_phy->sata_timeout_timer != NULL) 2303230557Sjimharris { 2304230557Sjimharris scic_cb_timer_destroy( 2305230557Sjimharris scic_sds_phy_get_controller(this_phy), 2306230557Sjimharris this_phy->sata_timeout_timer 2307230557Sjimharris ); 2308230557Sjimharris 2309230557Sjimharris this_phy->sata_timeout_timer = NULL; 2310230557Sjimharris } 2311230557Sjimharris 2312230557Sjimharris scu_link_layer_stop_protocol_engine(this_phy); 2313230557Sjimharris} 2314230557Sjimharris 2315230557Sjimharris/** 2316230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 2317230557Sjimharris * entering the SCI_BASE_PHY_STATE_STARTING. 2318230557Sjimharris * - This function sets the state handlers for the phy object base state 2319230557Sjimharris * machine starting state. 2320240743Skevlo * - The SCU hardware is requested to start OOB/SN on this protocol engine. 2321230557Sjimharris * - The phy starting substate machine is started. 2322230557Sjimharris * - If the previous state was the ready state then the 2323230557Sjimharris * SCIC_SDS_CONTROLLER is informed that the phy has gone link down. 2324230557Sjimharris * 2325230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 2326230557Sjimharris * SCIC_SDS_PHY object. 2327230557Sjimharris * 2328230557Sjimharris * @return none 2329230557Sjimharris */ 2330230557Sjimharrisstatic 2331230557Sjimharrisvoid scic_sds_phy_starting_state_enter( 2332230557Sjimharris SCI_BASE_OBJECT_T *object 2333230557Sjimharris) 2334230557Sjimharris{ 2335230557Sjimharris SCIC_SDS_PHY_T *this_phy; 2336230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 2337230557Sjimharris 2338230557Sjimharris scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STARTING); 2339230557Sjimharris 2340230557Sjimharris scu_link_layer_stop_protocol_engine(this_phy); 2341230557Sjimharris scu_link_layer_start_oob(this_phy); 2342230557Sjimharris 2343230557Sjimharris // We don't know what kind of phy we are going to be just yet 2344230557Sjimharris this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN; 2345230557Sjimharris this_phy->bcn_received_while_port_unassigned = FALSE; 2346230557Sjimharris 2347230557Sjimharris // Change over to the starting substate machine to continue 2348230557Sjimharris sci_base_state_machine_start(&this_phy->starting_substate_machine); 2349230557Sjimharris 2350230557Sjimharris if (this_phy->parent.state_machine.previous_state_id 2351230557Sjimharris == SCI_BASE_PHY_STATE_READY) 2352230557Sjimharris { 2353230557Sjimharris scic_sds_controller_link_down( 2354230557Sjimharris scic_sds_phy_get_controller(this_phy), 2355230557Sjimharris scic_sds_phy_get_port(this_phy), 2356230557Sjimharris this_phy 2357230557Sjimharris ); 2358230557Sjimharris } 2359230557Sjimharris} 2360230557Sjimharris 2361230557Sjimharris/** 2362230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 2363230557Sjimharris * entering the SCI_BASE_PHY_STATE_READY. 2364230557Sjimharris * - This function sets the state handlers for the phy object base state 2365230557Sjimharris * machine ready state. 2366230557Sjimharris * - The SCU hardware protocol engine is resumed. 2367230557Sjimharris * - The SCIC_SDS_CONTROLLER is informed that the phy object has gone link 2368230557Sjimharris * up. 2369230557Sjimharris * 2370230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 2371230557Sjimharris * SCIC_SDS_PHY object. 2372230557Sjimharris * 2373230557Sjimharris * @return none 2374230557Sjimharris */ 2375230557Sjimharrisstatic 2376230557Sjimharrisvoid scic_sds_phy_ready_state_enter( 2377230557Sjimharris SCI_BASE_OBJECT_T *object 2378230557Sjimharris) 2379230557Sjimharris{ 2380230557Sjimharris SCIC_SDS_PHY_T *this_phy; 2381230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 2382230557Sjimharris 2383230557Sjimharris scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_READY); 2384230557Sjimharris 2385230557Sjimharris scic_sds_controller_link_up( 2386230557Sjimharris scic_sds_phy_get_controller(this_phy), 2387230557Sjimharris scic_sds_phy_get_port(this_phy), 2388230557Sjimharris this_phy 2389230557Sjimharris ); 2390230557Sjimharris} 2391230557Sjimharris 2392230557Sjimharris/** 2393230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 2394230557Sjimharris * exiting the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU 2395230557Sjimharris * hardware protocol engine represented by this SCIC_SDS_PHY object. 2396230557Sjimharris * 2397230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 2398230557Sjimharris * SCIC_SDS_PHY object. 2399230557Sjimharris * 2400230557Sjimharris * @return none 2401230557Sjimharris */ 2402230557Sjimharrisstatic 2403230557Sjimharrisvoid scic_sds_phy_ready_state_exit( 2404230557Sjimharris SCI_BASE_OBJECT_T *object 2405230557Sjimharris) 2406230557Sjimharris{ 2407230557Sjimharris SCIC_SDS_PHY_T *this_phy; 2408230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 2409230557Sjimharris 2410230557Sjimharris scic_sds_phy_suspend(this_phy); 2411230557Sjimharris} 2412230557Sjimharris 2413230557Sjimharris/** 2414230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 2415230557Sjimharris * entering the SCI_BASE_PHY_STATE_RESETTING. 2416230557Sjimharris * - This function sets the state handlers for the phy object base state 2417230557Sjimharris * machine resetting state. 2418230557Sjimharris * 2419230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 2420230557Sjimharris * SCIC_SDS_PHY object. 2421230557Sjimharris * 2422230557Sjimharris * @return none 2423230557Sjimharris */ 2424230557Sjimharrisstatic 2425230557Sjimharrisvoid scic_sds_phy_resetting_state_enter( 2426230557Sjimharris SCI_BASE_OBJECT_T *object 2427230557Sjimharris) 2428230557Sjimharris{ 2429230557Sjimharris SCIC_SDS_PHY_T * this_phy; 2430230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 2431230557Sjimharris 2432230557Sjimharris scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_RESETTING); 2433230557Sjimharris 2434230557Sjimharris // The phy is being reset, therefore deactivate it from the port. 2435230557Sjimharris // In the resetting state we don't notify the user regarding 2436230557Sjimharris // link up and link down notifications. 2437230557Sjimharris scic_sds_port_deactivate_phy(this_phy->owning_port, this_phy, FALSE); 2438230557Sjimharris 2439230557Sjimharris if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) 2440230557Sjimharris { 2441230557Sjimharris scu_link_layer_tx_hard_reset(this_phy); 2442230557Sjimharris } 2443230557Sjimharris else 2444230557Sjimharris { 2445230557Sjimharris // The SCU does not need to have a descrete reset state so just go back to 2446230557Sjimharris // the starting state. 2447230557Sjimharris sci_base_state_machine_change_state( 2448230557Sjimharris &this_phy->parent.state_machine, 2449230557Sjimharris SCI_BASE_PHY_STATE_STARTING 2450230557Sjimharris ); 2451230557Sjimharris } 2452230557Sjimharris} 2453230557Sjimharris 2454230557Sjimharris/** 2455230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 2456230557Sjimharris * entering the SCI_BASE_PHY_STATE_FINAL. 2457230557Sjimharris * - This function sets the state handlers for the phy object base state 2458230557Sjimharris * machine final state. 2459230557Sjimharris * 2460230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 2461230557Sjimharris * SCIC_SDS_PHY object. 2462230557Sjimharris * 2463230557Sjimharris * @return none 2464230557Sjimharris */ 2465230557Sjimharrisstatic 2466230557Sjimharrisvoid scic_sds_phy_final_state_enter( 2467230557Sjimharris SCI_BASE_OBJECT_T *object 2468230557Sjimharris) 2469230557Sjimharris{ 2470230557Sjimharris SCIC_SDS_PHY_T *this_phy; 2471230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 2472230557Sjimharris 2473230557Sjimharris scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_FINAL); 2474230557Sjimharris 2475230557Sjimharris // Nothing to do here 2476230557Sjimharris} 2477230557Sjimharris 2478230557Sjimharris// --------------------------------------------------------------------------- 2479230557Sjimharris 2480230557SjimharrisSCI_BASE_STATE_T scic_sds_phy_state_table[SCI_BASE_PHY_MAX_STATES] = 2481230557Sjimharris{ 2482230557Sjimharris { 2483230557Sjimharris SCI_BASE_PHY_STATE_INITIAL, 2484230557Sjimharris scic_sds_phy_initial_state_enter, 2485230557Sjimharris NULL, 2486230557Sjimharris }, 2487230557Sjimharris { 2488230557Sjimharris SCI_BASE_PHY_STATE_STOPPED, 2489230557Sjimharris scic_sds_phy_stopped_state_enter, 2490230557Sjimharris NULL, 2491230557Sjimharris }, 2492230557Sjimharris { 2493230557Sjimharris SCI_BASE_PHY_STATE_STARTING, 2494230557Sjimharris scic_sds_phy_starting_state_enter, 2495230557Sjimharris NULL, 2496230557Sjimharris }, 2497230557Sjimharris { 2498230557Sjimharris SCI_BASE_PHY_STATE_READY, 2499230557Sjimharris scic_sds_phy_ready_state_enter, 2500230557Sjimharris scic_sds_phy_ready_state_exit, 2501230557Sjimharris }, 2502230557Sjimharris { 2503230557Sjimharris SCI_BASE_PHY_STATE_RESETTING, 2504230557Sjimharris scic_sds_phy_resetting_state_enter, 2505230557Sjimharris NULL, 2506230557Sjimharris }, 2507230557Sjimharris { 2508230557Sjimharris SCI_BASE_PHY_STATE_FINAL, 2509230557Sjimharris scic_sds_phy_final_state_enter, 2510230557Sjimharris NULL, 2511230557Sjimharris } 2512230557Sjimharris}; 2513230557Sjimharris 2514230557Sjimharris//****************************************************************************** 2515230557Sjimharris//* PHY STARTING SUB-STATE MACHINE 2516230557Sjimharris//****************************************************************************** 2517230557Sjimharris 2518230557Sjimharris//***************************************************************************** 2519230557Sjimharris//* SCIC SDS PHY HELPER FUNCTIONS 2520230557Sjimharris//***************************************************************************** 2521230557Sjimharris 2522230557Sjimharris 2523230557Sjimharris/** 2524230557Sjimharris * This method continues the link training for the phy as if it were a SAS PHY 2525230557Sjimharris * instead of a SATA PHY. This is done because the completion queue had a SAS 2526230557Sjimharris * PHY DETECTED event when the state machine was expecting a SATA PHY event. 2527230557Sjimharris * 2528230557Sjimharris * @param[in] this_phy The phy object that received SAS PHY DETECTED. 2529230557Sjimharris * 2530230557Sjimharris * @return none 2531230557Sjimharris */ 2532230557Sjimharrisstatic 2533230557Sjimharrisvoid scic_sds_phy_start_sas_link_training( 2534230557Sjimharris SCIC_SDS_PHY_T * this_phy 2535230557Sjimharris) 2536230557Sjimharris{ 2537230557Sjimharris U32 phy_control; 2538230557Sjimharris 2539230557Sjimharris phy_control = SCU_SAS_PCFG_READ(this_phy); 2540230557Sjimharris phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD); 2541230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, phy_control); 2542230557Sjimharris 2543230557Sjimharris sci_base_state_machine_change_state( 2544230557Sjimharris &this_phy->starting_substate_machine, 2545230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN 2546230557Sjimharris ); 2547230557Sjimharris 2548230557Sjimharris this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS; 2549230557Sjimharris} 2550230557Sjimharris 2551230557Sjimharris/** 2552230557Sjimharris * This method continues the link training for the phy as if it were a SATA 2553230557Sjimharris * PHY instead of a SAS PHY. This is done because the completion queue had a 2554230557Sjimharris * SATA SPINUP HOLD event when the state machine was expecting a SAS PHY 2555230557Sjimharris * event. 2556230557Sjimharris * 2557230557Sjimharris * @param[in] this_phy The phy object that received a SATA SPINUP HOLD event 2558230557Sjimharris * 2559230557Sjimharris * @return none 2560230557Sjimharris */ 2561230557Sjimharrisstatic 2562230557Sjimharrisvoid scic_sds_phy_start_sata_link_training( 2563230557Sjimharris SCIC_SDS_PHY_T * this_phy 2564230557Sjimharris) 2565230557Sjimharris{ 2566230557Sjimharris sci_base_state_machine_change_state( 2567230557Sjimharris &this_phy->starting_substate_machine, 2568230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER 2569230557Sjimharris ); 2570230557Sjimharris 2571230557Sjimharris this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA; 2572230557Sjimharris} 2573230557Sjimharris 2574230557Sjimharris/** 2575230557Sjimharris * @brief This method performs processing common to all protocols upon 2576230557Sjimharris * completion of link training. 2577230557Sjimharris * 2578230557Sjimharris * @param[in,out] this_phy This parameter specifies the phy object for which 2579230557Sjimharris * link training has completed. 2580230557Sjimharris * @param[in] max_link_rate This parameter specifies the maximum link 2581230557Sjimharris * rate to be associated with this phy. 2582230557Sjimharris * @param[in] next_state This parameter specifies the next state for the 2583230557Sjimharris * phy's starting sub-state machine. 2584230557Sjimharris * 2585230557Sjimharris * @return none 2586230557Sjimharris */ 2587230557Sjimharrisstatic 2588230557Sjimharrisvoid scic_sds_phy_complete_link_training( 2589230557Sjimharris SCIC_SDS_PHY_T * this_phy, 2590230557Sjimharris SCI_SAS_LINK_RATE max_link_rate, 2591230557Sjimharris U32 next_state 2592230557Sjimharris) 2593230557Sjimharris{ 2594230557Sjimharris this_phy->max_negotiated_speed = max_link_rate; 2595230557Sjimharris 2596230557Sjimharris sci_base_state_machine_change_state( 2597230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), next_state 2598230557Sjimharris ); 2599230557Sjimharris} 2600230557Sjimharris 2601230557Sjimharris/** 2602230557Sjimharris * This method restarts the SCIC_SDS_PHY objects base state machine in the 2603230557Sjimharris * starting state from any starting substate. 2604230557Sjimharris * 2605230557Sjimharris * @param[in] this_phy The SCIC_SDS_PHY object to restart. 2606230557Sjimharris * 2607230557Sjimharris * @return none 2608230557Sjimharris */ 2609230557Sjimharrisvoid scic_sds_phy_restart_starting_state( 2610230557Sjimharris SCIC_SDS_PHY_T *this_phy 2611230557Sjimharris) 2612230557Sjimharris{ 2613230557Sjimharris // Stop the current substate machine 2614230557Sjimharris sci_base_state_machine_stop( 2615230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy) 2616230557Sjimharris ); 2617230557Sjimharris 2618230557Sjimharris // Re-enter the base state machine starting state 2619230557Sjimharris sci_base_state_machine_change_state( 2620230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 2621230557Sjimharris SCI_BASE_PHY_STATE_STARTING 2622230557Sjimharris ); 2623230557Sjimharris} 2624230557Sjimharris 2625230557Sjimharris 2626230557Sjimharris//***************************************************************************** 2627230557Sjimharris//* SCIC SDS PHY general handlers 2628230557Sjimharris//***************************************************************************** 2629230557Sjimharris 2630230557Sjimharrisstatic 2631230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_general_stop_handler( 2632230557Sjimharris SCI_BASE_PHY_T *phy 2633230557Sjimharris) 2634230557Sjimharris{ 2635230557Sjimharris SCIC_SDS_PHY_T *this_phy; 2636230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)phy; 2637230557Sjimharris 2638230557Sjimharris sci_base_state_machine_stop( 2639230557Sjimharris &this_phy->starting_substate_machine 2640230557Sjimharris ); 2641230557Sjimharris 2642230557Sjimharris sci_base_state_machine_change_state( 2643230557Sjimharris &phy->state_machine, 2644230557Sjimharris SCI_BASE_PHY_STATE_STOPPED 2645230557Sjimharris ); 2646230557Sjimharris 2647230557Sjimharris return SCI_SUCCESS; 2648230557Sjimharris} 2649230557Sjimharris 2650230557Sjimharris//***************************************************************************** 2651230557Sjimharris//* SCIC SDS PHY EVENT_HANDLERS 2652230557Sjimharris//***************************************************************************** 2653230557Sjimharris 2654230557Sjimharris/** 2655230557Sjimharris * This method is called when an event notification is received for the phy 2656230557Sjimharris * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. 2657230557Sjimharris * - decode the event 2658230557Sjimharris * - sas phy detected causes a state transition to the wait for speed 2659230557Sjimharris * event notification. 2660230557Sjimharris * - any other events log a warning message and set a failure status 2661230557Sjimharris * 2662230557Sjimharris * @param[in] phy This SCIC_SDS_PHY object which has received an event. 2663230557Sjimharris * @param[in] event_code This is the event code which the phy object is to 2664230557Sjimharris * decode. 2665230557Sjimharris * 2666230557Sjimharris * @return SCI_STATUS 2667230557Sjimharris * @retval SCI_SUCCESS on any valid event notification 2668230557Sjimharris * @retval SCI_FAILURE on any unexpected event notifation 2669230557Sjimharris */ 2670230557Sjimharrisstatic 2671230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_ossp_event_handler( 2672230557Sjimharris SCIC_SDS_PHY_T *this_phy, 2673230557Sjimharris U32 event_code 2674230557Sjimharris) 2675230557Sjimharris{ 2676230557Sjimharris U32 result = SCI_SUCCESS; 2677230557Sjimharris 2678230557Sjimharris switch (scu_get_event_code(event_code)) 2679230557Sjimharris { 2680230557Sjimharris case SCU_EVENT_SAS_PHY_DETECTED: 2681230557Sjimharris scic_sds_phy_start_sas_link_training(this_phy); 2682230557Sjimharris this_phy->is_in_link_training = TRUE; 2683230557Sjimharris break; 2684230557Sjimharris 2685230557Sjimharris case SCU_EVENT_SATA_SPINUP_HOLD: 2686230557Sjimharris scic_sds_phy_start_sata_link_training(this_phy); 2687230557Sjimharris this_phy->is_in_link_training = TRUE; 2688230557Sjimharris break; 2689230557Sjimharris 2690230557Sjimharris default: 2691230557Sjimharris SCIC_LOG_WARNING(( 2692230557Sjimharris sci_base_object_get_logger(this_phy), 2693230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 2694298931Spfg "PHY starting substate machine received unexpected event_code %x\n", 2695230557Sjimharris event_code 2696230557Sjimharris )); 2697230557Sjimharris 2698230557Sjimharris result = SCI_FAILURE; 2699230557Sjimharris break; 2700230557Sjimharris } 2701230557Sjimharris 2702230557Sjimharris return result; 2703230557Sjimharris} 2704230557Sjimharris 2705230557Sjimharris/** 2706230557Sjimharris * This method is called when an event notification is received for the phy 2707230557Sjimharris * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. 2708230557Sjimharris * - decode the event 2709230557Sjimharris * - sas phy detected returns us back to this state. 2710230557Sjimharris * - speed event detected causes a state transition to the wait for iaf. 2711230557Sjimharris * - identify timeout is an un-expected event and the state machine is 2712230557Sjimharris * restarted. 2713230557Sjimharris * - link failure events restart the starting state machine 2714230557Sjimharris * - any other events log a warning message and set a failure status 2715230557Sjimharris * 2716230557Sjimharris * @param[in] phy This SCIC_SDS_PHY object which has received an event. 2717230557Sjimharris * @param[in] event_code This is the event code which the phy object is to 2718230557Sjimharris * decode. 2719230557Sjimharris * 2720230557Sjimharris * @return SCI_STATUS 2721230557Sjimharris * @retval SCI_SUCCESS on any valid event notification 2722230557Sjimharris * @retval SCI_FAILURE on any unexpected event notifation 2723230557Sjimharris */ 2724230557Sjimharrisstatic 2725230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler( 2726230557Sjimharris SCIC_SDS_PHY_T *this_phy, 2727230557Sjimharris U32 event_code 2728230557Sjimharris) 2729230557Sjimharris{ 2730230557Sjimharris U32 result = SCI_SUCCESS; 2731230557Sjimharris 2732230557Sjimharris switch (scu_get_event_code(event_code)) 2733230557Sjimharris { 2734230557Sjimharris case SCU_EVENT_SAS_PHY_DETECTED: 2735230557Sjimharris // Why is this being reported again by the controller? 2736230557Sjimharris // We would re-enter this state so just stay here 2737230557Sjimharris break; 2738230557Sjimharris 2739230557Sjimharris case SCU_EVENT_SAS_15: 2740230557Sjimharris case SCU_EVENT_SAS_15_SSC: 2741230557Sjimharris scic_sds_phy_complete_link_training( 2742230557Sjimharris this_phy, SCI_SAS_150_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF 2743230557Sjimharris ); 2744230557Sjimharris break; 2745230557Sjimharris 2746230557Sjimharris case SCU_EVENT_SAS_30: 2747230557Sjimharris case SCU_EVENT_SAS_30_SSC: 2748230557Sjimharris scic_sds_phy_complete_link_training( 2749230557Sjimharris this_phy, SCI_SAS_300_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF 2750230557Sjimharris ); 2751230557Sjimharris break; 2752230557Sjimharris 2753230557Sjimharris case SCU_EVENT_SAS_60: 2754230557Sjimharris case SCU_EVENT_SAS_60_SSC: 2755230557Sjimharris scic_sds_phy_complete_link_training( 2756230557Sjimharris this_phy, SCI_SAS_600_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF 2757230557Sjimharris ); 2758230557Sjimharris break; 2759230557Sjimharris 2760230557Sjimharris case SCU_EVENT_SATA_SPINUP_HOLD: 2761230557Sjimharris // We were doing SAS PHY link training and received a SATA PHY event 2762230557Sjimharris // continue OOB/SN as if this were a SATA PHY 2763230557Sjimharris scic_sds_phy_start_sata_link_training(this_phy); 2764230557Sjimharris break; 2765230557Sjimharris 2766230557Sjimharris case SCU_EVENT_LINK_FAILURE: 2767230557Sjimharris // Link failure change state back to the starting state 2768230557Sjimharris scic_sds_phy_restart_starting_state(this_phy); 2769230557Sjimharris break; 2770230557Sjimharris 2771230557Sjimharris default: 2772230557Sjimharris SCIC_LOG_WARNING(( 2773230557Sjimharris sci_base_object_get_logger(this_phy), 2774230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 2775298931Spfg "PHY starting substate machine received unexpected event_code %x\n", 2776230557Sjimharris event_code 2777230557Sjimharris )); 2778230557Sjimharris 2779230557Sjimharris result = SCI_FAILURE; 2780230557Sjimharris break; 2781230557Sjimharris } 2782230557Sjimharris 2783230557Sjimharris return result; 2784230557Sjimharris} 2785230557Sjimharris 2786230557Sjimharris/** 2787230557Sjimharris * This method is called when an event notification is received for the phy 2788230557Sjimharris * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. 2789230557Sjimharris * - decode the event 2790230557Sjimharris * - sas phy detected event backs up the state machine to the await 2791230557Sjimharris * speed notification. 2792230557Sjimharris * - identify timeout is an un-expected event and the state machine is 2793230557Sjimharris * restarted. 2794230557Sjimharris * - link failure events restart the starting state machine 2795230557Sjimharris * - any other events log a warning message and set a failure status 2796230557Sjimharris * 2797230557Sjimharris * @param[in] phy This SCIC_SDS_PHY object which has received an event. 2798230557Sjimharris * @param[in] event_code This is the event code which the phy object is to 2799230557Sjimharris * decode. 2800230557Sjimharris * 2801230557Sjimharris * @return SCI_STATUS 2802230557Sjimharris * @retval SCI_SUCCESS on any valid event notification 2803230557Sjimharris * @retval SCI_FAILURE on any unexpected event notifation 2804230557Sjimharris */ 2805230557Sjimharrisstatic 2806230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_iaf_uf_event_handler( 2807230557Sjimharris SCIC_SDS_PHY_T *this_phy, 2808230557Sjimharris U32 event_code 2809230557Sjimharris) 2810230557Sjimharris{ 2811230557Sjimharris U32 result = SCI_SUCCESS; 2812230557Sjimharris 2813230557Sjimharris switch (scu_get_event_code(event_code)) 2814230557Sjimharris { 2815230557Sjimharris case SCU_EVENT_SAS_PHY_DETECTED: 2816230557Sjimharris // Backup the state machine 2817230557Sjimharris scic_sds_phy_start_sas_link_training(this_phy); 2818230557Sjimharris break; 2819230557Sjimharris 2820230557Sjimharris case SCU_EVENT_SATA_SPINUP_HOLD: 2821230557Sjimharris // We were doing SAS PHY link training and received a SATA PHY event 2822230557Sjimharris // continue OOB/SN as if this were a SATA PHY 2823230557Sjimharris scic_sds_phy_start_sata_link_training(this_phy); 2824230557Sjimharris break; 2825230557Sjimharris 2826230557Sjimharris case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT: 2827230557Sjimharris case SCU_EVENT_LINK_FAILURE: 2828230557Sjimharris case SCU_EVENT_HARD_RESET_RECEIVED: 2829230557Sjimharris // Start the oob/sn state machine over again 2830230557Sjimharris scic_sds_phy_restart_starting_state(this_phy); 2831230557Sjimharris break; 2832230557Sjimharris 2833230557Sjimharris default: 2834230557Sjimharris SCIC_LOG_WARNING(( 2835230557Sjimharris sci_base_object_get_logger(this_phy), 2836230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 2837298931Spfg "PHY starting substate machine received unexpected event_code %x\n", 2838230557Sjimharris event_code 2839230557Sjimharris )); 2840230557Sjimharris 2841230557Sjimharris result = SCI_FAILURE; 2842230557Sjimharris break; 2843230557Sjimharris } 2844230557Sjimharris 2845230557Sjimharris return result; 2846230557Sjimharris} 2847230557Sjimharris 2848230557Sjimharris/** 2849230557Sjimharris * This method is called when an event notification is received for the phy 2850230557Sjimharris * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. 2851230557Sjimharris * - decode the event 2852230557Sjimharris * - link failure events restart the starting state machine 2853230557Sjimharris * - any other events log a warning message and set a failure status 2854230557Sjimharris * 2855230557Sjimharris * @param[in] phy This SCIC_SDS_PHY object which has received an event. 2856230557Sjimharris * @param[in] event_code This is the event code which the phy object is to 2857230557Sjimharris * decode. 2858230557Sjimharris * 2859230557Sjimharris * @return SCI_STATUS 2860230557Sjimharris * @retval SCI_SUCCESS on a link failure event 2861230557Sjimharris * @retval SCI_FAILURE on any unexpected event notifation 2862230557Sjimharris */ 2863230557Sjimharrisstatic 2864230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sas_power_event_handler( 2865230557Sjimharris SCIC_SDS_PHY_T *this_phy, 2866230557Sjimharris U32 event_code 2867230557Sjimharris) 2868230557Sjimharris{ 2869230557Sjimharris U32 result = SCI_SUCCESS; 2870230557Sjimharris 2871230557Sjimharris switch (scu_get_event_code(event_code)) 2872230557Sjimharris { 2873230557Sjimharris case SCU_EVENT_LINK_FAILURE: 2874230557Sjimharris // Link failure change state back to the starting state 2875230557Sjimharris scic_sds_phy_restart_starting_state(this_phy); 2876230557Sjimharris break; 2877230557Sjimharris 2878230557Sjimharris default: 2879230557Sjimharris SCIC_LOG_WARNING(( 2880230557Sjimharris sci_base_object_get_logger(this_phy), 2881230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 2882298931Spfg "PHY starting substate machine received unexpected event_code %x\n", 2883230557Sjimharris event_code 2884230557Sjimharris )); 2885230557Sjimharris 2886230557Sjimharris result = SCI_FAILURE; 2887230557Sjimharris break; 2888230557Sjimharris } 2889230557Sjimharris 2890230557Sjimharris return result; 2891230557Sjimharris} 2892230557Sjimharris 2893230557Sjimharris/** 2894230557Sjimharris * This method is called when an event notification is received for the phy 2895230557Sjimharris * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. 2896230557Sjimharris * - decode the event 2897230557Sjimharris * - link failure events restart the starting state machine 2898230557Sjimharris * - sata spinup hold events are ignored since they are expected 2899230557Sjimharris * - any other events log a warning message and set a failure status 2900230557Sjimharris * 2901230557Sjimharris * @param[in] phy This SCIC_SDS_PHY object which has received an event. 2902230557Sjimharris * @param[in] event_code This is the event code which the phy object is to 2903230557Sjimharris * decode. 2904230557Sjimharris * 2905230557Sjimharris * @return SCI_STATUS 2906230557Sjimharris * @retval SCI_SUCCESS on a link failure event 2907230557Sjimharris * @retval SCI_FAILURE on any unexpected event notifation 2908230557Sjimharris */ 2909230557Sjimharrisstatic 2910230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sata_power_event_handler( 2911230557Sjimharris SCIC_SDS_PHY_T *this_phy, 2912230557Sjimharris U32 event_code 2913230557Sjimharris) 2914230557Sjimharris{ 2915230557Sjimharris U32 result = SCI_SUCCESS; 2916230557Sjimharris 2917230557Sjimharris switch (scu_get_event_code(event_code)) 2918230557Sjimharris { 2919230557Sjimharris case SCU_EVENT_LINK_FAILURE: 2920230557Sjimharris // Link failure change state back to the starting state 2921230557Sjimharris scic_sds_phy_restart_starting_state(this_phy); 2922230557Sjimharris break; 2923230557Sjimharris 2924230557Sjimharris case SCU_EVENT_SATA_SPINUP_HOLD: 2925230557Sjimharris // These events are received every 10ms and are expected while in this state 2926230557Sjimharris break; 2927230557Sjimharris 2928230557Sjimharris case SCU_EVENT_SAS_PHY_DETECTED: 2929230557Sjimharris // There has been a change in the phy type before OOB/SN for the 2930230557Sjimharris // SATA finished start down the SAS link traning path. 2931230557Sjimharris scic_sds_phy_start_sas_link_training(this_phy); 2932230557Sjimharris break; 2933230557Sjimharris 2934230557Sjimharris default: 2935230557Sjimharris SCIC_LOG_WARNING(( 2936230557Sjimharris sci_base_object_get_logger(this_phy), 2937230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 2938298931Spfg "PHY starting substate machine received unexpected event_code %x\n", 2939230557Sjimharris event_code 2940230557Sjimharris )); 2941230557Sjimharris 2942230557Sjimharris result = SCI_FAILURE; 2943230557Sjimharris break; 2944230557Sjimharris } 2945230557Sjimharris 2946230557Sjimharris return result; 2947230557Sjimharris} 2948230557Sjimharris 2949230557Sjimharris/** 2950230557Sjimharris * This method is called when an event notification is received for the phy 2951230557Sjimharris * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. 2952230557Sjimharris * - decode the event 2953230557Sjimharris * - link failure events restart the starting state machine 2954230557Sjimharris * - sata spinup hold events are ignored since they are expected 2955230557Sjimharris * - sata phy detected event change to the wait speed event 2956230557Sjimharris * - any other events log a warning message and set a failure status 2957230557Sjimharris * 2958230557Sjimharris * @param[in] phy This SCIC_SDS_PHY object which has received an event. 2959230557Sjimharris * @param[in] event_code This is the event code which the phy object is to 2960230557Sjimharris * decode. 2961230557Sjimharris * 2962230557Sjimharris * @return SCI_STATUS 2963230557Sjimharris * @retval SCI_SUCCESS on a link failure event 2964230557Sjimharris * @retval SCI_FAILURE on any unexpected event notifation 2965230557Sjimharris */ 2966230557Sjimharrisstatic 2967230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sata_phy_event_handler( 2968230557Sjimharris SCIC_SDS_PHY_T *this_phy, 2969230557Sjimharris U32 event_code 2970230557Sjimharris) 2971230557Sjimharris{ 2972230557Sjimharris U32 result = SCI_SUCCESS; 2973230557Sjimharris 2974230557Sjimharris switch (scu_get_event_code(event_code)) 2975230557Sjimharris { 2976230557Sjimharris case SCU_EVENT_LINK_FAILURE: 2977230557Sjimharris // Link failure change state back to the starting state 2978230557Sjimharris scic_sds_phy_restart_starting_state(this_phy); 2979230557Sjimharris break; 2980230557Sjimharris 2981230557Sjimharris case SCU_EVENT_SATA_SPINUP_HOLD: 2982230557Sjimharris // These events might be received since we dont know how many may be in 2983230557Sjimharris // the completion queue while waiting for power 2984230557Sjimharris break; 2985230557Sjimharris 2986230557Sjimharris case SCU_EVENT_SATA_PHY_DETECTED: 2987230557Sjimharris this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA; 2988230557Sjimharris 2989230557Sjimharris // We have received the SATA PHY notification change state 2990230557Sjimharris sci_base_state_machine_change_state( 2991230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), 2992230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN 2993230557Sjimharris ); 2994230557Sjimharris break; 2995230557Sjimharris 2996230557Sjimharris case SCU_EVENT_SAS_PHY_DETECTED: 2997230557Sjimharris // There has been a change in the phy type before OOB/SN for the 2998230557Sjimharris // SATA finished start down the SAS link traning path. 2999230557Sjimharris scic_sds_phy_start_sas_link_training(this_phy); 3000230557Sjimharris break; 3001230557Sjimharris 3002230557Sjimharris default: 3003230557Sjimharris SCIC_LOG_WARNING(( 3004230557Sjimharris sci_base_object_get_logger(this_phy), 3005230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 3006298931Spfg "PHY starting substate machine received unexpected event_code %x\n", 3007230557Sjimharris event_code 3008230557Sjimharris )); 3009230557Sjimharris 3010230557Sjimharris result = SCI_FAILURE; 3011230557Sjimharris break; 3012230557Sjimharris } 3013230557Sjimharris 3014230557Sjimharris return result; 3015230557Sjimharris} 3016230557Sjimharris 3017230557Sjimharris/** 3018230557Sjimharris * This method is called when an event notification is received for the phy 3019230557Sjimharris * object when in the state 3020230557Sjimharris * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. 3021230557Sjimharris * - decode the event 3022230557Sjimharris * - sata phy detected returns us back to this state. 3023230557Sjimharris * - speed event detected causes a state transition to the wait for 3024230557Sjimharris * signature. 3025230557Sjimharris * - link failure events restart the starting state machine 3026230557Sjimharris * - any other events log a warning message and set a failure status 3027230557Sjimharris * 3028230557Sjimharris * @param[in] phy This SCIC_SDS_PHY object which has received an event. 3029230557Sjimharris * @param[in] event_code This is the event code which the phy object is to 3030230557Sjimharris * decode. 3031230557Sjimharris * 3032230557Sjimharris * @return SCI_STATUS 3033230557Sjimharris * @retval SCI_SUCCESS on any valid event notification 3034230557Sjimharris * @retval SCI_FAILURE on any unexpected event notifation 3035230557Sjimharris */ 3036230557Sjimharrisstatic 3037230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sata_speed_event_handler( 3038230557Sjimharris SCIC_SDS_PHY_T *this_phy, 3039230557Sjimharris U32 event_code 3040230557Sjimharris) 3041230557Sjimharris{ 3042230557Sjimharris U32 result = SCI_SUCCESS; 3043230557Sjimharris 3044230557Sjimharris switch (scu_get_event_code(event_code)) 3045230557Sjimharris { 3046230557Sjimharris case SCU_EVENT_SATA_PHY_DETECTED: 3047230557Sjimharris // The hardware reports multiple SATA PHY detected events 3048230557Sjimharris // ignore the extras 3049230557Sjimharris break; 3050230557Sjimharris 3051230557Sjimharris case SCU_EVENT_SATA_15: 3052230557Sjimharris case SCU_EVENT_SATA_15_SSC: 3053230557Sjimharris scic_sds_phy_complete_link_training( 3054230557Sjimharris this_phy, 3055230557Sjimharris SCI_SAS_150_GB, 3056230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF 3057230557Sjimharris ); 3058230557Sjimharris break; 3059230557Sjimharris 3060230557Sjimharris case SCU_EVENT_SATA_30: 3061230557Sjimharris case SCU_EVENT_SATA_30_SSC: 3062230557Sjimharris scic_sds_phy_complete_link_training( 3063230557Sjimharris this_phy, 3064230557Sjimharris SCI_SAS_300_GB, 3065230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF 3066230557Sjimharris ); 3067230557Sjimharris break; 3068230557Sjimharris 3069230557Sjimharris case SCU_EVENT_SATA_60: 3070230557Sjimharris case SCU_EVENT_SATA_60_SSC: 3071230557Sjimharris scic_sds_phy_complete_link_training( 3072230557Sjimharris this_phy, 3073230557Sjimharris SCI_SAS_600_GB, 3074230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF 3075230557Sjimharris ); 3076230557Sjimharris break; 3077230557Sjimharris 3078230557Sjimharris case SCU_EVENT_LINK_FAILURE: 3079230557Sjimharris // Link failure change state back to the starting state 3080230557Sjimharris scic_sds_phy_restart_starting_state(this_phy); 3081230557Sjimharris break; 3082230557Sjimharris 3083230557Sjimharris case SCU_EVENT_SAS_PHY_DETECTED: 3084230557Sjimharris // There has been a change in the phy type before OOB/SN for the 3085230557Sjimharris // SATA finished start down the SAS link traning path. 3086230557Sjimharris scic_sds_phy_start_sas_link_training(this_phy); 3087230557Sjimharris break; 3088230557Sjimharris 3089230557Sjimharris default: 3090230557Sjimharris SCIC_LOG_WARNING(( 3091230557Sjimharris sci_base_object_get_logger(this_phy), 3092230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 3093298931Spfg "PHY starting substate machine received unexpected event_code %x\n", 3094230557Sjimharris event_code 3095230557Sjimharris )); 3096230557Sjimharris 3097230557Sjimharris result = SCI_FAILURE; 3098230557Sjimharris break; 3099230557Sjimharris } 3100230557Sjimharris 3101230557Sjimharris return result; 3102230557Sjimharris} 3103230557Sjimharris 3104230557Sjimharris/** 3105230557Sjimharris * This method is called when an event notification is received for the phy 3106230557Sjimharris * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. 3107230557Sjimharris * - decode the event 3108230557Sjimharris * - sas phy detected event backs up the state machine to the await 3109230557Sjimharris * speed notification. 3110230557Sjimharris * - identify timeout is an un-expected event and the state machine is 3111230557Sjimharris * restarted. 3112230557Sjimharris * - link failure events restart the starting state machine 3113230557Sjimharris * - any other events log a warning message and set a failure status 3114230557Sjimharris * 3115230557Sjimharris * @param[in] phy This SCIC_SDS_PHY object which has received an event. 3116230557Sjimharris * @param[in] event_code This is the event code which the phy object is to 3117230557Sjimharris * decode. 3118230557Sjimharris * 3119230557Sjimharris * @return SCI_STATUS 3120230557Sjimharris * @retval SCI_SUCCESS on any valid event notification 3121230557Sjimharris * @retval SCI_FAILURE on any unexpected event notifation 3122230557Sjimharris */ 3123230557Sjimharrisstatic 3124230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sig_fis_event_handler( 3125230557Sjimharris SCIC_SDS_PHY_T *this_phy, 3126230557Sjimharris U32 event_code 3127230557Sjimharris) 3128230557Sjimharris{ 3129230557Sjimharris U32 result = SCI_SUCCESS; 3130230557Sjimharris 3131230557Sjimharris switch (scu_get_event_code(event_code)) 3132230557Sjimharris { 3133230557Sjimharris case SCU_EVENT_SATA_PHY_DETECTED: 3134230557Sjimharris // Backup the state machine 3135230557Sjimharris sci_base_state_machine_change_state( 3136230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), 3137230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN 3138230557Sjimharris ); 3139230557Sjimharris break; 3140230557Sjimharris 3141230557Sjimharris case SCU_EVENT_LINK_FAILURE: 3142230557Sjimharris // Link failure change state back to the starting state 3143230557Sjimharris scic_sds_phy_restart_starting_state(this_phy); 3144230557Sjimharris break; 3145230557Sjimharris 3146230557Sjimharris default: 3147230557Sjimharris SCIC_LOG_WARNING(( 3148230557Sjimharris sci_base_object_get_logger(this_phy), 3149230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS, 3150298931Spfg "PHY starting substate machine received unexpected event_code %x\n", 3151230557Sjimharris event_code 3152230557Sjimharris )); 3153230557Sjimharris 3154230557Sjimharris result = SCI_FAILURE; 3155230557Sjimharris break; 3156230557Sjimharris } 3157230557Sjimharris 3158230557Sjimharris return result; 3159230557Sjimharris} 3160230557Sjimharris 3161230557Sjimharris 3162230557Sjimharris//***************************************************************************** 3163230557Sjimharris//* SCIC SDS PHY FRAME_HANDLERS 3164230557Sjimharris//***************************************************************************** 3165230557Sjimharris 3166230557Sjimharris/** 3167230557Sjimharris * This method decodes the unsolicited frame when the SCIC_SDS_PHY is in the 3168230557Sjimharris * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. 3169230557Sjimharris * - Get the UF Header 3170230557Sjimharris * - If the UF is an IAF 3171230557Sjimharris * - Copy IAF data to local phy object IAF data buffer. 3172230557Sjimharris * - Change starting substate to wait power. 3173230557Sjimharris * - else 3174230557Sjimharris * - log warning message of unexpected unsolicted frame 3175230557Sjimharris * - release frame buffer 3176230557Sjimharris * 3177230557Sjimharris * @param[in] phy This is SCIC_SDS_PHY object which is being requested to 3178230557Sjimharris * decode the frame data. 3179230557Sjimharris * @param[in] frame_index This is the index of the unsolicited frame which was 3180230557Sjimharris * received for this phy. 3181230557Sjimharris * 3182230557Sjimharris * @return SCI_STATUS 3183230557Sjimharris * @retval SCI_SUCCESS 3184230557Sjimharris */ 3185230557Sjimharrisstatic 3186230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_iaf_uf_frame_handler( 3187230557Sjimharris SCIC_SDS_PHY_T *this_phy, 3188230557Sjimharris U32 frame_index 3189230557Sjimharris) 3190230557Sjimharris{ 3191230557Sjimharris SCI_STATUS result; 3192230557Sjimharris U32 *frame_words; 3193230557Sjimharris SCI_SAS_IDENTIFY_ADDRESS_FRAME_T *identify_frame; 3194230557Sjimharris 3195230557Sjimharris result = scic_sds_unsolicited_frame_control_get_header( 3196230557Sjimharris &(scic_sds_phy_get_controller(this_phy)->uf_control), 3197230557Sjimharris frame_index, 3198230557Sjimharris (void **)&frame_words); 3199230557Sjimharris 3200230557Sjimharris if (result != SCI_SUCCESS) 3201230557Sjimharris { 3202230557Sjimharris return result; 3203230557Sjimharris } 3204230557Sjimharris 3205230557Sjimharris frame_words[0] = SCIC_SWAP_DWORD(frame_words[0]); 3206230557Sjimharris identify_frame = (SCI_SAS_IDENTIFY_ADDRESS_FRAME_T *)frame_words; 3207230557Sjimharris 3208230557Sjimharris if (identify_frame->address_frame_type == 0) 3209230557Sjimharris { 3210230557Sjimharris // Byte swap the rest of the frame so we can make 3211230557Sjimharris // a copy of the buffer 3212230557Sjimharris frame_words[1] = SCIC_SWAP_DWORD(frame_words[1]); 3213230557Sjimharris frame_words[2] = SCIC_SWAP_DWORD(frame_words[2]); 3214230557Sjimharris frame_words[3] = SCIC_SWAP_DWORD(frame_words[3]); 3215230557Sjimharris frame_words[4] = SCIC_SWAP_DWORD(frame_words[4]); 3216230557Sjimharris frame_words[5] = SCIC_SWAP_DWORD(frame_words[5]); 3217230557Sjimharris 3218230557Sjimharris memcpy( 3219230557Sjimharris &this_phy->phy_type.sas.identify_address_frame_buffer, 3220230557Sjimharris identify_frame, 3221230557Sjimharris sizeof(SCI_SAS_IDENTIFY_ADDRESS_FRAME_T) 3222230557Sjimharris ); 3223230557Sjimharris 3224230557Sjimharris if (identify_frame->protocols.u.bits.smp_target) 3225230557Sjimharris { 3226230557Sjimharris // We got the IAF for an expander PHY go to the final state since 3227230557Sjimharris // there are no power requirements for expander phys. 3228230557Sjimharris sci_base_state_machine_change_state( 3229230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), 3230230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL 3231230557Sjimharris ); 3232230557Sjimharris } 3233230557Sjimharris else 3234230557Sjimharris { 3235230557Sjimharris // We got the IAF we can now go to the await spinup semaphore state 3236230557Sjimharris sci_base_state_machine_change_state( 3237230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), 3238230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER 3239230557Sjimharris ); 3240230557Sjimharris } 3241230557Sjimharris 3242230557Sjimharris result = SCI_SUCCESS; 3243230557Sjimharris } 3244230557Sjimharris else 3245230557Sjimharris { 3246230557Sjimharris SCIC_LOG_WARNING(( 3247230557Sjimharris sci_base_object_get_logger(this_phy), 3248230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_UNSOLICITED_FRAMES, 3249298931Spfg "PHY starting substate machine received unexpected frame id %x\n", 3250230557Sjimharris frame_index 3251230557Sjimharris )); 3252230557Sjimharris } 3253230557Sjimharris 3254230557Sjimharris // Regardless of the result release this frame since we are done with it 3255230557Sjimharris scic_sds_controller_release_frame( 3256230557Sjimharris scic_sds_phy_get_controller(this_phy), frame_index 3257230557Sjimharris ); 3258230557Sjimharris 3259230557Sjimharris return result; 3260230557Sjimharris} 3261230557Sjimharris 3262230557Sjimharris/** 3263230557Sjimharris * This method decodes the unsolicited frame when the SCIC_SDS_PHY is in the 3264230557Sjimharris * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. 3265230557Sjimharris * - Get the UF Header 3266230557Sjimharris * - If the UF is an SIGNATURE FIS 3267230557Sjimharris * - Copy IAF data to local phy object SIGNATURE FIS data buffer. 3268230557Sjimharris * - else 3269230557Sjimharris * - log warning message of unexpected unsolicted frame 3270230557Sjimharris * - release frame buffer 3271230557Sjimharris * 3272230557Sjimharris * @param[in] phy This is SCIC_SDS_PHY object which is being requested to 3273230557Sjimharris * decode the frame data. 3274230557Sjimharris * @param[in] frame_index This is the index of the unsolicited frame which was 3275230557Sjimharris * received for this phy. 3276230557Sjimharris * 3277230557Sjimharris * @return SCI_STATUS 3278230557Sjimharris * @retval SCI_SUCCESS 3279230557Sjimharris * 3280230557Sjimharris * @todo Must decode the SIGNATURE FIS data 3281230557Sjimharris */ 3282230557Sjimharrisstatic 3283230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sig_fis_frame_handler( 3284230557Sjimharris SCIC_SDS_PHY_T *this_phy, 3285230557Sjimharris U32 frame_index 3286230557Sjimharris) 3287230557Sjimharris{ 3288230557Sjimharris SCI_STATUS result; 3289230557Sjimharris U32 * frame_words; 3290230557Sjimharris SATA_FIS_HEADER_T * fis_frame_header; 3291230557Sjimharris U32 * fis_frame_data; 3292230557Sjimharris 3293230557Sjimharris result = scic_sds_unsolicited_frame_control_get_header( 3294230557Sjimharris &(scic_sds_phy_get_controller(this_phy)->uf_control), 3295230557Sjimharris frame_index, 3296230557Sjimharris (void **)&frame_words); 3297230557Sjimharris 3298230557Sjimharris if (result != SCI_SUCCESS) 3299230557Sjimharris { 3300230557Sjimharris return result; 3301230557Sjimharris } 3302230557Sjimharris 3303230557Sjimharris fis_frame_header = (SATA_FIS_HEADER_T *)frame_words; 3304230557Sjimharris 3305230557Sjimharris if ( 3306230557Sjimharris (fis_frame_header->fis_type == SATA_FIS_TYPE_REGD2H) 3307230557Sjimharris && !(fis_frame_header->status & ATA_STATUS_REG_BSY_BIT) 3308230557Sjimharris ) 3309230557Sjimharris { 3310230557Sjimharris scic_sds_unsolicited_frame_control_get_buffer( 3311230557Sjimharris &(scic_sds_phy_get_controller(this_phy)->uf_control), 3312230557Sjimharris frame_index, 3313230557Sjimharris (void **)&fis_frame_data 3314230557Sjimharris ); 3315230557Sjimharris 3316230557Sjimharris scic_sds_controller_copy_sata_response( 3317230557Sjimharris &this_phy->phy_type.sata.signature_fis_buffer, 3318230557Sjimharris frame_words, 3319230557Sjimharris fis_frame_data 3320230557Sjimharris ); 3321230557Sjimharris 3322230557Sjimharris // We got the IAF we can now go to the await spinup semaphore state 3323230557Sjimharris sci_base_state_machine_change_state( 3324230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), 3325230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL 3326230557Sjimharris ); 3327230557Sjimharris 3328230557Sjimharris result = SCI_SUCCESS; 3329230557Sjimharris } 3330230557Sjimharris else 3331230557Sjimharris { 3332230557Sjimharris SCIC_LOG_WARNING(( 3333230557Sjimharris sci_base_object_get_logger(this_phy), 3334230557Sjimharris SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_UNSOLICITED_FRAMES, 3335298931Spfg "PHY starting substate machine received unexpected frame id %x\n", 3336230557Sjimharris frame_index 3337230557Sjimharris )); 3338230557Sjimharris } 3339230557Sjimharris 3340230557Sjimharris // Regardless of the result release this frame since we are done with it 3341230557Sjimharris scic_sds_controller_release_frame( 3342230557Sjimharris scic_sds_phy_get_controller(this_phy), frame_index 3343230557Sjimharris ); 3344230557Sjimharris 3345230557Sjimharris return result; 3346230557Sjimharris} 3347230557Sjimharris 3348230557Sjimharris//***************************************************************************** 3349230557Sjimharris//* SCIC SDS PHY POWER_HANDLERS 3350230557Sjimharris//***************************************************************************** 3351230557Sjimharris 3352230557Sjimharris/** 3353230557Sjimharris * This method is called by the SCIC_SDS_CONTROLLER when the phy object is 3354230557Sjimharris * granted power. 3355230557Sjimharris * - The notify enable spinups are turned on for this phy object 3356230557Sjimharris * - The phy state machine is transitioned to the 3357230557Sjimharris * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. 3358230557Sjimharris * 3359230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 3360230557Sjimharris * SCIC_SDS_PHY object. 3361230557Sjimharris * 3362230557Sjimharris * @return SCI_STATUS 3363230557Sjimharris * @retval SCI_SUCCESS 3364230557Sjimharris */ 3365230557Sjimharrisstatic 3366230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sas_power_consume_power_handler( 3367230557Sjimharris SCIC_SDS_PHY_T *this_phy 3368230557Sjimharris) 3369230557Sjimharris{ 3370230557Sjimharris U32 enable_spinup; 3371230557Sjimharris 3372230557Sjimharris enable_spinup = SCU_SAS_ENSPINUP_READ(this_phy); 3373230557Sjimharris enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE); 3374230557Sjimharris SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup); 3375230557Sjimharris 3376230557Sjimharris // Change state to the final state this substate machine has run to completion 3377230557Sjimharris sci_base_state_machine_change_state( 3378230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), 3379230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL 3380230557Sjimharris ); 3381230557Sjimharris 3382230557Sjimharris return SCI_SUCCESS; 3383230557Sjimharris} 3384230557Sjimharris 3385230557Sjimharris/** 3386230557Sjimharris * This method is called by the SCIC_SDS_CONTROLLER when the phy object is 3387230557Sjimharris * granted power. 3388230557Sjimharris * - The phy state machine is transitioned to the 3389230557Sjimharris * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. 3390230557Sjimharris * 3391230557Sjimharris * @param[in] phy This is the SCI_BASE_PHY object which is cast into a 3392230557Sjimharris * SCIC_SDS_PHY object. 3393230557Sjimharris * 3394230557Sjimharris * @return SCI_STATUS 3395230557Sjimharris * @retval SCI_SUCCESS 3396230557Sjimharris */ 3397230557Sjimharrisstatic 3398230557SjimharrisSCI_STATUS scic_sds_phy_starting_substate_await_sata_power_consume_power_handler( 3399230557Sjimharris SCIC_SDS_PHY_T *this_phy 3400230557Sjimharris) 3401230557Sjimharris{ 3402230557Sjimharris U32 scu_sas_pcfg_value; 3403230557Sjimharris 3404230557Sjimharris // Release the spinup hold state and reset the OOB state machine 3405230557Sjimharris scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy); 3406230557Sjimharris scu_sas_pcfg_value &= 3407230557Sjimharris ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE)); 3408230557Sjimharris scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET); 3409230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value); 3410230557Sjimharris 3411230557Sjimharris // Now restart the OOB operation 3412230557Sjimharris scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET); 3413230557Sjimharris scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE); 3414230557Sjimharris SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value); 3415230557Sjimharris 3416230557Sjimharris // Change state to the final state this substate machine has run to completion 3417230557Sjimharris sci_base_state_machine_change_state( 3418230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), 3419230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN 3420230557Sjimharris ); 3421230557Sjimharris 3422230557Sjimharris return SCI_SUCCESS; 3423230557Sjimharris} 3424230557Sjimharris 3425230557Sjimharris// --------------------------------------------------------------------------- 3426230557Sjimharris 3427230557SjimharrisSCIC_SDS_PHY_STATE_HANDLER_T 3428230557Sjimharris scic_sds_phy_starting_substate_handler_table[SCIC_SDS_PHY_STARTING_MAX_SUBSTATES] = 3429230557Sjimharris{ 3430230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL 3431230557Sjimharris { 3432230557Sjimharris { 3433230557Sjimharris scic_sds_phy_default_start_handler, 3434230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3435230557Sjimharris scic_sds_phy_default_reset_handler, 3436230557Sjimharris scic_sds_phy_default_destroy_handler 3437230557Sjimharris }, 3438230557Sjimharris scic_sds_phy_default_frame_handler, 3439230557Sjimharris scic_sds_phy_default_event_handler, 3440230557Sjimharris scic_sds_phy_default_consume_power_handler 3441230557Sjimharris }, 3442230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN 3443230557Sjimharris { 3444230557Sjimharris { 3445230557Sjimharris scic_sds_phy_default_start_handler, 3446230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3447230557Sjimharris scic_sds_phy_default_reset_handler, 3448230557Sjimharris scic_sds_phy_default_destroy_handler 3449230557Sjimharris }, 3450230557Sjimharris scic_sds_phy_default_frame_handler, 3451230557Sjimharris scic_sds_phy_starting_substate_await_ossp_event_handler, 3452230557Sjimharris scic_sds_phy_default_consume_power_handler 3453230557Sjimharris }, 3454230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN 3455230557Sjimharris { 3456230557Sjimharris { 3457230557Sjimharris scic_sds_phy_default_start_handler, 3458230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3459230557Sjimharris scic_sds_phy_default_reset_handler, 3460230557Sjimharris scic_sds_phy_default_destroy_handler 3461230557Sjimharris }, 3462230557Sjimharris scic_sds_phy_default_frame_handler, 3463230557Sjimharris scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler, 3464230557Sjimharris scic_sds_phy_default_consume_power_handler 3465230557Sjimharris }, 3466230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF 3467230557Sjimharris { 3468230557Sjimharris { 3469230557Sjimharris scic_sds_phy_default_start_handler, 3470230557Sjimharris scic_sds_phy_default_stop_handler, 3471230557Sjimharris scic_sds_phy_default_reset_handler, 3472230557Sjimharris scic_sds_phy_default_destroy_handler 3473230557Sjimharris }, 3474230557Sjimharris scic_sds_phy_starting_substate_await_iaf_uf_frame_handler, 3475230557Sjimharris scic_sds_phy_starting_substate_await_iaf_uf_event_handler, 3476230557Sjimharris scic_sds_phy_default_consume_power_handler 3477230557Sjimharris }, 3478230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER 3479230557Sjimharris { 3480230557Sjimharris { 3481230557Sjimharris scic_sds_phy_default_start_handler, 3482230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3483230557Sjimharris scic_sds_phy_default_reset_handler, 3484230557Sjimharris scic_sds_phy_default_destroy_handler 3485230557Sjimharris }, 3486230557Sjimharris scic_sds_phy_default_frame_handler, 3487230557Sjimharris scic_sds_phy_starting_substate_await_sas_power_event_handler, 3488230557Sjimharris scic_sds_phy_starting_substate_await_sas_power_consume_power_handler 3489230557Sjimharris }, 3490230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER, 3491230557Sjimharris { 3492230557Sjimharris { 3493230557Sjimharris scic_sds_phy_default_start_handler, 3494230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3495230557Sjimharris scic_sds_phy_default_reset_handler, 3496230557Sjimharris scic_sds_phy_default_destroy_handler 3497230557Sjimharris }, 3498230557Sjimharris scic_sds_phy_default_frame_handler, 3499230557Sjimharris scic_sds_phy_starting_substate_await_sata_power_event_handler, 3500230557Sjimharris scic_sds_phy_starting_substate_await_sata_power_consume_power_handler 3501230557Sjimharris }, 3502230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN, 3503230557Sjimharris { 3504230557Sjimharris { 3505230557Sjimharris scic_sds_phy_default_start_handler, 3506230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3507230557Sjimharris scic_sds_phy_default_reset_handler, 3508230557Sjimharris scic_sds_phy_default_destroy_handler 3509230557Sjimharris }, 3510230557Sjimharris scic_sds_phy_default_frame_handler, 3511230557Sjimharris scic_sds_phy_starting_substate_await_sata_phy_event_handler, 3512230557Sjimharris scic_sds_phy_default_consume_power_handler 3513230557Sjimharris }, 3514230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN, 3515230557Sjimharris { 3516230557Sjimharris { 3517230557Sjimharris scic_sds_phy_default_start_handler, 3518230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3519230557Sjimharris scic_sds_phy_default_reset_handler, 3520230557Sjimharris scic_sds_phy_default_destroy_handler 3521230557Sjimharris }, 3522230557Sjimharris scic_sds_phy_default_frame_handler, 3523230557Sjimharris scic_sds_phy_starting_substate_await_sata_speed_event_handler, 3524230557Sjimharris scic_sds_phy_default_consume_power_handler 3525230557Sjimharris }, 3526230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF, 3527230557Sjimharris { 3528230557Sjimharris { 3529230557Sjimharris scic_sds_phy_default_start_handler, 3530230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3531230557Sjimharris scic_sds_phy_default_reset_handler, 3532230557Sjimharris scic_sds_phy_default_destroy_handler 3533230557Sjimharris }, 3534230557Sjimharris scic_sds_phy_starting_substate_await_sig_fis_frame_handler, 3535230557Sjimharris scic_sds_phy_starting_substate_await_sig_fis_event_handler, 3536230557Sjimharris scic_sds_phy_default_consume_power_handler 3537230557Sjimharris }, 3538230557Sjimharris // SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL 3539230557Sjimharris { 3540230557Sjimharris { 3541230557Sjimharris scic_sds_phy_default_start_handler, 3542230557Sjimharris scic_sds_phy_starting_substate_general_stop_handler, 3543230557Sjimharris scic_sds_phy_default_reset_handler, 3544230557Sjimharris scic_sds_phy_default_destroy_handler 3545230557Sjimharris }, 3546230557Sjimharris scic_sds_phy_default_frame_handler, 3547230557Sjimharris scic_sds_phy_default_event_handler, 3548230557Sjimharris scic_sds_phy_default_consume_power_handler 3549230557Sjimharris } 3550230557Sjimharris}; 3551230557Sjimharris 3552230557Sjimharris/** 3553230557Sjimharris * This macro sets the starting substate handlers by state_id 3554230557Sjimharris */ 3555230557Sjimharris#define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \ 3556230557Sjimharris scic_sds_phy_set_state_handlers( \ 3557230557Sjimharris (phy), \ 3558230557Sjimharris &scic_sds_phy_starting_substate_handler_table[(state_id)] \ 3559230557Sjimharris ) 3560230557Sjimharris 3561230557Sjimharris//**************************************************************************** 3562230557Sjimharris//* PHY STARTING SUBSTATE METHODS 3563230557Sjimharris//**************************************************************************** 3564230557Sjimharris 3565230557Sjimharris/** 3566230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3567230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL. 3568230557Sjimharris * - The initial state handlers are put in place for the SCIC_SDS_PHY 3569230557Sjimharris * object. 3570230557Sjimharris * - The state is changed to the wait phy type event notification. 3571230557Sjimharris * 3572230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3573230557Sjimharris * SCIC_SDS_PHY object. 3574230557Sjimharris * 3575230557Sjimharris * @return none 3576230557Sjimharris */ 3577230557Sjimharrisstatic 3578230557Sjimharrisvoid scic_sds_phy_starting_initial_substate_enter( 3579230557Sjimharris SCI_BASE_OBJECT_T *object 3580230557Sjimharris) 3581230557Sjimharris{ 3582230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3583230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3584230557Sjimharris 3585230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3586230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL); 3587230557Sjimharris 3588230557Sjimharris // This is just an temporary state go off to the starting state 3589230557Sjimharris sci_base_state_machine_change_state( 3590230557Sjimharris scic_sds_phy_get_starting_substate_machine(this_phy), 3591230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN 3592230557Sjimharris ); 3593230557Sjimharris} 3594230557Sjimharris 3595230557Sjimharris/** 3596230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3597230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_PHY_TYPE_EN. 3598230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3599230557Sjimharris * 3600230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3601230557Sjimharris * SCIC_SDS_PHY object. 3602230557Sjimharris * 3603230557Sjimharris * @return none 3604230557Sjimharris */ 3605230557Sjimharrisstatic 3606230557Sjimharrisvoid scic_sds_phy_starting_await_ossp_en_substate_enter( 3607230557Sjimharris SCI_BASE_OBJECT_T *object 3608230557Sjimharris) 3609230557Sjimharris{ 3610230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3611230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3612230557Sjimharris 3613230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3614230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN 3615230557Sjimharris ); 3616230557Sjimharris} 3617230557Sjimharris 3618230557Sjimharris/** 3619230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3620230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. 3621230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3622230557Sjimharris * 3623230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3624230557Sjimharris * SCIC_SDS_PHY object. 3625230557Sjimharris * 3626230557Sjimharris * @return none 3627230557Sjimharris */ 3628230557Sjimharrisstatic 3629230557Sjimharrisvoid scic_sds_phy_starting_await_sas_speed_en_substate_enter( 3630230557Sjimharris SCI_BASE_OBJECT_T *object 3631230557Sjimharris) 3632230557Sjimharris{ 3633230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3634230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3635230557Sjimharris 3636230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3637230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN 3638230557Sjimharris ); 3639230557Sjimharris} 3640230557Sjimharris 3641230557Sjimharris/** 3642230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3643230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. 3644230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3645230557Sjimharris * 3646230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3647230557Sjimharris * SCIC_SDS_PHY object. 3648230557Sjimharris * 3649230557Sjimharris * @return none 3650230557Sjimharris */ 3651230557Sjimharrisstatic 3652230557Sjimharrisvoid scic_sds_phy_starting_await_iaf_uf_substate_enter( 3653230557Sjimharris SCI_BASE_OBJECT_T *object 3654230557Sjimharris) 3655230557Sjimharris{ 3656230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3657230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3658230557Sjimharris 3659230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3660230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF 3661230557Sjimharris ); 3662230557Sjimharris} 3663230557Sjimharris 3664230557Sjimharris/** 3665230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3666230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. 3667230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3668230557Sjimharris * - Add this phy object to the power control queue 3669230557Sjimharris * 3670230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3671230557Sjimharris * SCIC_SDS_PHY object. 3672230557Sjimharris * 3673230557Sjimharris * @return none 3674230557Sjimharris */ 3675230557Sjimharrisstatic 3676230557Sjimharrisvoid scic_sds_phy_starting_await_sas_power_substate_enter( 3677230557Sjimharris SCI_BASE_OBJECT_T *object 3678230557Sjimharris) 3679230557Sjimharris{ 3680230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3681230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3682230557Sjimharris 3683230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3684230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER 3685230557Sjimharris ); 3686230557Sjimharris 3687230557Sjimharris scic_sds_controller_power_control_queue_insert( 3688230557Sjimharris scic_sds_phy_get_controller(this_phy), 3689230557Sjimharris this_phy 3690230557Sjimharris ); 3691230557Sjimharris} 3692230557Sjimharris 3693230557Sjimharris/** 3694230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3695230557Sjimharris * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. 3696230557Sjimharris * - Remove the SCIC_SDS_PHY object from the power control queue. 3697230557Sjimharris * 3698230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3699230557Sjimharris * SCIC_SDS_PHY object. 3700230557Sjimharris * 3701230557Sjimharris * @return none 3702230557Sjimharris */ 3703230557Sjimharrisstatic 3704230557Sjimharrisvoid scic_sds_phy_starting_await_sas_power_substate_exit( 3705230557Sjimharris SCI_BASE_OBJECT_T *object 3706230557Sjimharris) 3707230557Sjimharris{ 3708230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3709230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3710230557Sjimharris 3711230557Sjimharris scic_sds_controller_power_control_queue_remove( 3712230557Sjimharris scic_sds_phy_get_controller(this_phy), this_phy 3713230557Sjimharris ); 3714230557Sjimharris} 3715230557Sjimharris 3716230557Sjimharris/** 3717230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3718230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. 3719230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3720230557Sjimharris * - Add this phy object to the power control queue 3721230557Sjimharris * 3722230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3723230557Sjimharris * SCIC_SDS_PHY object. 3724230557Sjimharris * 3725230557Sjimharris * @return none 3726230557Sjimharris */ 3727230557Sjimharrisstatic 3728230557Sjimharrisvoid scic_sds_phy_starting_await_sata_power_substate_enter( 3729230557Sjimharris SCI_BASE_OBJECT_T *object 3730230557Sjimharris) 3731230557Sjimharris{ 3732230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3733230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3734230557Sjimharris 3735230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3736230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER 3737230557Sjimharris ); 3738230557Sjimharris 3739230557Sjimharris scic_sds_controller_power_control_queue_insert( 3740230557Sjimharris scic_sds_phy_get_controller(this_phy), 3741230557Sjimharris this_phy 3742230557Sjimharris ); 3743230557Sjimharris} 3744230557Sjimharris 3745230557Sjimharris/** 3746230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3747230557Sjimharris * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. 3748230557Sjimharris * - Remove the SCIC_SDS_PHY object from the power control queue. 3749230557Sjimharris * 3750230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3751230557Sjimharris * SCIC_SDS_PHY object. 3752230557Sjimharris * 3753230557Sjimharris * @return none 3754230557Sjimharris */ 3755230557Sjimharrisstatic 3756230557Sjimharrisvoid scic_sds_phy_starting_await_sata_power_substate_exit( 3757230557Sjimharris SCI_BASE_OBJECT_T *object 3758230557Sjimharris) 3759230557Sjimharris{ 3760230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3761230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3762230557Sjimharris 3763230557Sjimharris scic_sds_controller_power_control_queue_remove( 3764230557Sjimharris scic_sds_phy_get_controller(this_phy), 3765230557Sjimharris this_phy 3766230557Sjimharris ); 3767230557Sjimharris} 3768230557Sjimharris 3769230557Sjimharris/** 3770230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3771230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. 3772230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3773230557Sjimharris * 3774230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3775230557Sjimharris * SCIC_SDS_PHY object. 3776230557Sjimharris * 3777230557Sjimharris * @return none 3778230557Sjimharris */ 3779230557Sjimharrisstatic 3780230557Sjimharrisvoid scic_sds_phy_starting_await_sata_phy_substate_enter( 3781230557Sjimharris SCI_BASE_OBJECT_T *object 3782230557Sjimharris) 3783230557Sjimharris{ 3784230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3785230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3786230557Sjimharris 3787230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3788230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN 3789230557Sjimharris ); 3790230557Sjimharris 3791230557Sjimharris scic_cb_timer_start( 3792230557Sjimharris scic_sds_phy_get_controller(this_phy), 3793230557Sjimharris this_phy->sata_timeout_timer, 3794230557Sjimharris SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT 3795230557Sjimharris ); 3796230557Sjimharris} 3797230557Sjimharris 3798230557Sjimharris/** 3799230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3800230557Sjimharris * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. 3801230557Sjimharris * - stop the timer that was started on entry to await sata phy 3802230557Sjimharris * event notification 3803230557Sjimharris * 3804230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3805230557Sjimharris * SCIC_SDS_PHY object. 3806230557Sjimharris * 3807230557Sjimharris * @return none 3808230557Sjimharris */ 3809230557Sjimharrisstatic 3810230557Sjimharrisvoid scic_sds_phy_starting_await_sata_phy_substate_exit( 3811230557Sjimharris SCI_BASE_OBJECT_T *object 3812230557Sjimharris) 3813230557Sjimharris{ 3814230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3815230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3816230557Sjimharris 3817230557Sjimharris scic_cb_timer_stop( 3818230557Sjimharris scic_sds_phy_get_controller(this_phy), 3819230557Sjimharris this_phy->sata_timeout_timer 3820230557Sjimharris ); 3821230557Sjimharris} 3822230557Sjimharris 3823230557Sjimharris/** 3824230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3825230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. 3826230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3827230557Sjimharris * 3828230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3829230557Sjimharris * SCIC_SDS_PHY object. 3830230557Sjimharris * 3831230557Sjimharris * @return none 3832230557Sjimharris */ 3833230557Sjimharrisstatic 3834230557Sjimharrisvoid scic_sds_phy_starting_await_sata_speed_substate_enter( 3835230557Sjimharris SCI_BASE_OBJECT_T *object 3836230557Sjimharris) 3837230557Sjimharris{ 3838230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3839230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3840230557Sjimharris 3841230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3842230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN 3843230557Sjimharris ); 3844230557Sjimharris 3845230557Sjimharris scic_cb_timer_start( 3846230557Sjimharris scic_sds_phy_get_controller(this_phy), 3847230557Sjimharris this_phy->sata_timeout_timer, 3848230557Sjimharris SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT 3849230557Sjimharris ); 3850230557Sjimharris} 3851230557Sjimharris 3852230557Sjimharris/** 3853230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3854230557Sjimharris * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. 3855230557Sjimharris * - stop the timer that was started on entry to await sata phy 3856230557Sjimharris * event notification 3857230557Sjimharris * 3858230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3859230557Sjimharris * SCIC_SDS_PHY object. 3860230557Sjimharris * 3861230557Sjimharris * @return none 3862230557Sjimharris */ 3863230557Sjimharrisstatic 3864230557Sjimharrisvoid scic_sds_phy_starting_await_sata_speed_substate_exit( 3865230557Sjimharris SCI_BASE_OBJECT_T *object 3866230557Sjimharris) 3867230557Sjimharris{ 3868230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3869230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3870230557Sjimharris 3871230557Sjimharris scic_cb_timer_stop( 3872230557Sjimharris scic_sds_phy_get_controller(this_phy), 3873230557Sjimharris this_phy->sata_timeout_timer 3874230557Sjimharris ); 3875230557Sjimharris} 3876230557Sjimharris 3877230557Sjimharris/** 3878230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3879230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. 3880230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3881230557Sjimharris * - Start the SIGNATURE FIS timeout timer 3882230557Sjimharris * 3883230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3884230557Sjimharris * SCIC_SDS_PHY object. 3885230557Sjimharris * 3886230557Sjimharris * @return none 3887230557Sjimharris */ 3888230557Sjimharrisstatic 3889230557Sjimharrisvoid scic_sds_phy_starting_await_sig_fis_uf_substate_enter( 3890230557Sjimharris SCI_BASE_OBJECT_T *object 3891230557Sjimharris) 3892230557Sjimharris{ 3893230557Sjimharris BOOL continue_to_ready_state; 3894230557Sjimharris SCIC_SDS_PHY_T * this_phy; 3895230557Sjimharris 3896230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3897230557Sjimharris 3898230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3899230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF 3900230557Sjimharris ); 3901230557Sjimharris 3902230557Sjimharris continue_to_ready_state = scic_sds_port_link_detected( 3903230557Sjimharris this_phy->owning_port, 3904230557Sjimharris this_phy 3905230557Sjimharris ); 3906230557Sjimharris 3907230557Sjimharris if (continue_to_ready_state) 3908230557Sjimharris { 3909230557Sjimharris // Clear the PE suspend condition so we can actually receive SIG FIS 3910230557Sjimharris // The hardware will not respond to the XRDY until the PE suspend 3911230557Sjimharris // condition is cleared. 3912230557Sjimharris scic_sds_phy_resume(this_phy); 3913230557Sjimharris 3914230557Sjimharris scic_cb_timer_start( 3915230557Sjimharris scic_sds_phy_get_controller(this_phy), 3916230557Sjimharris this_phy->sata_timeout_timer, 3917230557Sjimharris SCIC_SDS_SIGNATURE_FIS_TIMEOUT 3918230557Sjimharris ); 3919230557Sjimharris } 3920230557Sjimharris else 3921230557Sjimharris { 3922230557Sjimharris this_phy->is_in_link_training = FALSE; 3923230557Sjimharris } 3924230557Sjimharris} 3925230557Sjimharris 3926230557Sjimharris/** 3927230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3928230557Sjimharris * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. 3929230557Sjimharris * - Stop the SIGNATURE FIS timeout timer. 3930230557Sjimharris * 3931230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3932230557Sjimharris * SCIC_SDS_PHY object. 3933230557Sjimharris * 3934230557Sjimharris * @return none 3935230557Sjimharris */ 3936230557Sjimharrisstatic 3937230557Sjimharrisvoid scic_sds_phy_starting_await_sig_fis_uf_substate_exit( 3938230557Sjimharris SCI_BASE_OBJECT_T *object 3939230557Sjimharris) 3940230557Sjimharris{ 3941230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3942230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3943230557Sjimharris 3944230557Sjimharris scic_cb_timer_stop( 3945230557Sjimharris scic_sds_phy_get_controller(this_phy), 3946230557Sjimharris this_phy->sata_timeout_timer 3947230557Sjimharris ); 3948230557Sjimharris} 3949230557Sjimharris 3950230557Sjimharris/** 3951230557Sjimharris * This method will perform the actions required by the SCIC_SDS_PHY on 3952230557Sjimharris * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. 3953230557Sjimharris * - Set the SCIC_SDS_PHY object state handlers for this state. 3954230557Sjimharris * - Change base state machine to the ready state. 3955230557Sjimharris * 3956230557Sjimharris * @param[in] object This is the SCI_BASE_OBJECT which is cast to a 3957230557Sjimharris * SCIC_SDS_PHY object. 3958230557Sjimharris * 3959230557Sjimharris * @return none 3960230557Sjimharris */ 3961230557Sjimharrisstatic 3962230557Sjimharrisvoid scic_sds_phy_starting_final_substate_enter( 3963230557Sjimharris SCI_BASE_OBJECT_T *object 3964230557Sjimharris) 3965230557Sjimharris{ 3966230557Sjimharris SCIC_SDS_PHY_T *this_phy; 3967230557Sjimharris this_phy = (SCIC_SDS_PHY_T *)object; 3968230557Sjimharris 3969230557Sjimharris scic_sds_phy_set_starting_substate_handlers( 3970230557Sjimharris this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL 3971230557Sjimharris ); 3972230557Sjimharris 3973230557Sjimharris // State machine has run to completion so exit out and change 3974230557Sjimharris // the base state machine to the ready state 3975230557Sjimharris sci_base_state_machine_change_state( 3976230557Sjimharris scic_sds_phy_get_base_state_machine(this_phy), 3977230557Sjimharris SCI_BASE_PHY_STATE_READY); 3978230557Sjimharris} 3979230557Sjimharris 3980230557Sjimharris// --------------------------------------------------------------------------- 3981230557Sjimharris 3982230557SjimharrisSCI_BASE_STATE_T 3983230557Sjimharris scic_sds_phy_starting_substates[SCIC_SDS_PHY_STARTING_MAX_SUBSTATES] = 3984230557Sjimharris{ 3985230557Sjimharris { 3986230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL, 3987230557Sjimharris scic_sds_phy_starting_initial_substate_enter, 3988230557Sjimharris NULL, 3989230557Sjimharris }, 3990230557Sjimharris { 3991230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN, 3992230557Sjimharris scic_sds_phy_starting_await_ossp_en_substate_enter, 3993230557Sjimharris NULL, 3994230557Sjimharris }, 3995230557Sjimharris { 3996230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN, 3997230557Sjimharris scic_sds_phy_starting_await_sas_speed_en_substate_enter, 3998230557Sjimharris NULL, 3999230557Sjimharris }, 4000230557Sjimharris { 4001230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF, 4002230557Sjimharris scic_sds_phy_starting_await_iaf_uf_substate_enter, 4003230557Sjimharris NULL, 4004230557Sjimharris }, 4005230557Sjimharris { 4006230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER, 4007230557Sjimharris scic_sds_phy_starting_await_sas_power_substate_enter, 4008230557Sjimharris scic_sds_phy_starting_await_sas_power_substate_exit, 4009230557Sjimharris }, 4010230557Sjimharris { 4011230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER, 4012230557Sjimharris scic_sds_phy_starting_await_sata_power_substate_enter, 4013230557Sjimharris scic_sds_phy_starting_await_sata_power_substate_exit 4014230557Sjimharris }, 4015230557Sjimharris { 4016230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN, 4017230557Sjimharris scic_sds_phy_starting_await_sata_phy_substate_enter, 4018230557Sjimharris scic_sds_phy_starting_await_sata_phy_substate_exit 4019230557Sjimharris }, 4020230557Sjimharris { 4021230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN, 4022230557Sjimharris scic_sds_phy_starting_await_sata_speed_substate_enter, 4023230557Sjimharris scic_sds_phy_starting_await_sata_speed_substate_exit 4024230557Sjimharris }, 4025230557Sjimharris { 4026230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF, 4027230557Sjimharris scic_sds_phy_starting_await_sig_fis_uf_substate_enter, 4028230557Sjimharris scic_sds_phy_starting_await_sig_fis_uf_substate_exit 4029230557Sjimharris }, 4030230557Sjimharris { 4031230557Sjimharris SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL, 4032230557Sjimharris scic_sds_phy_starting_final_substate_enter, 4033230557Sjimharris NULL, 4034230557Sjimharris } 4035230557Sjimharris}; 4036230557Sjimharris 4037