2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23 * The full GNU General Public License is included in this distribution
24 * in the file called LICENSE.GPL.
28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
35 * * Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * * Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in
39 * the documentation and/or other materials provided with the
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 #include <sys/cdefs.h>
56 __FBSDID("$FreeBSD$");
61 * @brief This file contains the implementation of the SCIC_SDS_PHY public and
65 #include <dev/isci/scil/scic_user_callback.h>
66 #include <dev/isci/scil/scic_phy.h>
67 #include <dev/isci/scil/scic_sds_phy.h>
68 #include <dev/isci/scil/scic_sds_port.h>
69 #include <dev/isci/scil/scic_sds_controller_registers.h>
70 #include <dev/isci/scil/scic_sds_phy_registers.h>
71 #include <dev/isci/scil/scic_sds_logger.h>
72 #include <dev/isci/scil/scic_sds_remote_node_context.h>
73 #include <dev/isci/scil/sci_util.h>
74 #include <dev/isci/scil/scic_sds_controller.h>
75 #include <dev/isci/scil/scu_event_codes.h>
76 #include <dev/isci/scil/sci_base_state.h>
77 #include <dev/isci/scil/intel_ata.h>
78 #include <dev/isci/scil/intel_sata.h>
79 #include <dev/isci/scil/sci_base_state_machine.h>
80 #include <dev/isci/scil/scic_sds_port_registers.h>
82 #define SCIC_SDS_PHY_MIN_TIMER_COUNT (SCI_MAX_PHYS)
83 #define SCIC_SDS_PHY_MAX_TIMER_COUNT (SCI_MAX_PHYS)
85 // Maximum arbitration wait time in micro-seconds
86 #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
88 #define AFE_REGISTER_WRITE_DELAY 10
90 //*****************************************************************************
91 //* SCIC SDS PHY Internal Methods
92 //*****************************************************************************
95 * @brief This method will initialize the phy transport layer registers
98 * @param[in] transport_layer_registers
103 SCI_STATUS scic_sds_phy_transport_layer_initialization(
104 SCIC_SDS_PHY_T *this_phy,
105 SCU_TRANSPORT_LAYER_REGISTERS_T *transport_layer_registers
111 sci_base_object_get_logger(this_phy),
113 "scic_sds_phy_link_layer_initialization(this_phy:0x%x, link_layer_registers:0x%x)\n",
114 this_phy, transport_layer_registers
117 this_phy->transport_layer_registers = transport_layer_registers;
119 SCU_STPTLDARNI_WRITE(this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
121 // Hardware team recommends that we enable the STP prefetch for all transports
122 tl_control = SCU_TLCR_READ(this_phy);
123 tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
124 SCU_TLCR_WRITE(this_phy, tl_control);
130 * @brief This method will initialize the phy link layer registers
132 * @param[in] this_phy
133 * @param[in] link_layer_registers
138 SCI_STATUS scic_sds_phy_link_layer_initialization(
139 SCIC_SDS_PHY_T *this_phy,
140 SCU_LINK_LAYER_REGISTERS_T *link_layer_registers
143 U32 phy_configuration;
144 SAS_CAPABILITIES_T phy_capabilities;
145 U32 parity_check = 0;
146 U32 parity_count = 0;
147 U32 link_layer_control;
148 U32 phy_timer_timeout_values;
152 sci_base_object_get_logger(this_phy),
154 "scic_sds_phy_link_layer_initialization(this_phy:0x%x, link_layer_registers:0x%x)\n",
155 this_phy, link_layer_registers
158 this_phy->link_layer_registers = link_layer_registers;
160 // Set our IDENTIFY frame data
161 #define SCI_END_DEVICE 0x01
165 ( SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR)
166 | SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR)
167 | SCU_SAS_TIID_GEN_BIT(STP_INITIATOR)
168 | SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST)
169 | SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE) )
172 // Write the device SAS Address
173 SCU_SAS_TIDNH_WRITE(this_phy, 0xFEDCBA98);
174 SCU_SAS_TIDNL_WRITE(this_phy, this_phy->phy_index);
176 // Write the source SAS Address
177 SCU_SAS_TISSAH_WRITE(
179 this_phy->owning_port->owning_controller->oem_parameters.sds1.phys[
180 this_phy->phy_index].sas_address.sci_format.high
182 SCU_SAS_TISSAL_WRITE(
184 this_phy->owning_port->owning_controller->oem_parameters.sds1.phys[
185 this_phy->phy_index].sas_address.sci_format.low
188 // Clear and Set the PHY Identifier
189 SCU_SAS_TIPID_WRITE(this_phy, 0x00000000);
190 SCU_SAS_TIPID_WRITE(this_phy, SCU_SAS_TIPID_GEN_VALUE(ID, this_phy->phy_index));
192 // Change the initial state of the phy configuration register
193 phy_configuration = SCU_SAS_PCFG_READ(this_phy);
195 // Hold OOB state machine in reset
196 phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
197 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration);
199 // Configure the SNW capabilities
200 phy_capabilities.u.all = 0;
201 phy_capabilities.u.bits.start = 1;
202 phy_capabilities.u.bits.gen3_without_ssc_supported = 1;
203 phy_capabilities.u.bits.gen2_without_ssc_supported = 1;
204 phy_capabilities.u.bits.gen1_without_ssc_supported = 1;
207 * Set up SSC settings according to version of OEM Parameters.
210 U8 header_version, enable_sata, enable_sas,
211 sata_spread, sas_type, sas_spread;
212 OEM_SSC_PARAMETERS_T ssc;
214 header_version = this_phy->owning_port->owning_controller->
215 oem_parameters_version;
217 ssc.bf.ssc_sata_tx_spread_level =
218 this_phy->owning_port->owning_controller->oem_parameters.sds1.controller.ssc_sata_tx_spread_level;
219 ssc.bf.ssc_sas_tx_spread_level =
220 this_phy->owning_port->owning_controller->oem_parameters.sds1.controller.ssc_sas_tx_spread_level;
221 ssc.bf.ssc_sas_tx_type =
222 this_phy->owning_port->owning_controller->oem_parameters.sds1.controller.ssc_sas_tx_type;
223 enable_sata = enable_sas = sata_spread = sas_type = sas_spread = 0;
225 if (header_version == SCI_OEM_PARAM_VER_1_0)
228 * Version 1.0 is merely turning SSC on to default values.;
230 if (ssc.do_enable_ssc != 0)
232 enable_sas = enable_sata = TRUE;
233 sas_type = 0x0; // Downspreading
234 sata_spread = 0x2; // +0 to -1419 PPM
235 sas_spread = 0x2; // +0 to -1419 PPM
238 else // header_version >= SCI_OEM_PARAM_VER_1_1
241 * Version 1.1 can turn on SAS and SATA independently and
242 * specify spread levels. Also can specify spread type for SAS.
244 if ((sata_spread = ssc.bf.ssc_sata_tx_spread_level) != 0)
245 enable_sata = TRUE; // Downspreading only
246 if ((sas_spread = ssc.bf.ssc_sas_tx_spread_level) != 0)
249 sas_type = ssc.bf.ssc_sas_tx_type;
253 if (enable_sas == TRUE)
255 U32 reg_val = scu_afe_register_read(
256 this_phy->owning_port->owning_controller,
257 scu_afe_xcvr[this_phy->phy_index].
259 reg_val |= (0x00100000 | (((U32)sas_type) << 19));
260 scu_afe_register_write(
261 this_phy->owning_port->owning_controller,
262 scu_afe_xcvr[this_phy->phy_index].afe_xcvr_control0,
265 reg_val = scu_afe_register_read(
266 this_phy->owning_port->owning_controller,
267 scu_afe_xcvr[this_phy->phy_index].
269 reg_val |= (((U32)(sas_spread)) << 8);
270 scu_afe_register_write(
271 this_phy->owning_port->owning_controller,
272 scu_afe_xcvr[this_phy->phy_index].afe_tx_ssc_control,
274 phy_capabilities.u.bits.gen3_with_ssc_supported = 1;
275 phy_capabilities.u.bits.gen2_with_ssc_supported = 1;
276 phy_capabilities.u.bits.gen1_with_ssc_supported = 1;
279 if (enable_sata == TRUE)
281 U32 reg_val = scu_afe_register_read(
282 this_phy->owning_port->owning_controller,
283 scu_afe_xcvr[this_phy->phy_index].
285 reg_val |= (U32)sata_spread;
286 scu_afe_register_write(
287 this_phy->owning_port->owning_controller,
288 scu_afe_xcvr[this_phy->phy_index].afe_tx_ssc_control,
291 reg_val = scu_link_layer_register_read(
294 reg_val |= (U32)(1 << 12);
295 scu_link_layer_register_write(
302 // The SAS specification indicates that the phy_capabilities that
303 // are transmitted shall have an even parity. Calculate the parity.
304 parity_check = phy_capabilities.u.all;
305 while (parity_check != 0)
307 if (parity_check & 0x1)
312 // If parity indicates there are an odd number of bits set, then
313 // set the parity bit to 1 in the phy capabilities.
314 if ((parity_count % 2) != 0)
315 phy_capabilities.u.bits.parity = 1;
317 SCU_SAS_PHYCAP_WRITE(this_phy, phy_capabilities.u.all);
319 // Set the enable spinup period but disable the ability to send notify enable spinup
320 SCU_SAS_ENSPINUP_WRITE(
322 SCU_ENSPINUP_GEN_VAL(
324 this_phy->owning_port->owning_controller->user_parameters.sds1.
325 phys[this_phy->phy_index].notify_enable_spin_up_insertion_frequency
329 // Write the ALIGN Insertion Ferequency for connected phy and inpendent of connected state
330 clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL (
332 this_phy->owning_port->owning_controller->user_parameters.sds1.
333 phys[this_phy->phy_index].in_connection_align_insertion_frequency
336 clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL (
338 this_phy->owning_port->owning_controller->user_parameters.sds1.
339 phys[this_phy->phy_index].align_insertion_frequency
342 SCU_SAS_CLKSM_WRITE ( this_phy, clksm_value);
345 #if defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD) || defined(PBG_HBA_BETA_BUILD)
346 /// @todo Provide a way to write this register correctly
347 scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x02108421);
348 #elif defined(PBG_BUILD)
350 (this_phy->owning_port->owning_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0)
351 || (this_phy->owning_port->owning_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1)
354 scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x04210400);
355 scu_link_layer_register_write(this_phy, sas_primitive_timeout, 0x20A7C05);
359 scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x02108421);
362 /// @todo Provide a way to write this register correctly
363 scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x0e739ce7);
366 link_layer_control = SCU_SAS_LLCTL_GEN_VAL(
367 NO_OUTBOUND_TASK_TIMEOUT,
368 (U8) this_phy->owning_port->owning_controller->
369 user_parameters.sds1.no_outbound_task_timeout
372 #if PHY_MAX_LINK_SPEED_GENERATION == SCIC_SDS_PARM_GEN1_SPEED
373 #define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1
374 #elif PHY_MAX_LINK_SPEED_GENERATION == SCIC_SDS_PARM_GEN2_SPEED
375 #define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2
377 #define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3
378 #endif // PHY_MAX_LINK_SPEED_GENERATION
380 if (this_phy->owning_port->owning_controller->user_parameters.sds1.
381 phys[this_phy->phy_index].max_speed_generation == SCIC_SDS_PARM_GEN3_SPEED)
383 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
384 MAX_LINK_RATE, COMPILED_MAX_LINK_RATE
387 else if (this_phy->owning_port->owning_controller->user_parameters.sds1.
388 phys[this_phy->phy_index].max_speed_generation == SCIC_SDS_PARM_GEN2_SPEED)
390 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
393 SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2,
394 COMPILED_MAX_LINK_RATE)
399 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
402 SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1,
403 COMPILED_MAX_LINK_RATE)
407 scu_link_layer_register_write(
408 this_phy, link_layer_control, link_layer_control
411 phy_timer_timeout_values = scu_link_layer_register_read(
413 phy_timer_timeout_values
416 // Clear the default 0x36 (54us) RATE_CHANGE timeout value.
417 phy_timer_timeout_values &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
419 // Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can
420 // lock with 3Gb drive when SCU max rate is set to 1.5Gb.
421 phy_timer_timeout_values |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
423 scu_link_layer_register_write(
424 this_phy, phy_timer_timeout_values, phy_timer_timeout_values
427 // Program the max ARB time for the PHY to 700us so we inter-operate with
428 // the PMC expander which shuts down PHYs if the expander PHY generates too
429 // many breaks. This time value will guarantee that the initiator PHY will
430 // generate the break.
431 #if defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD)
432 scu_link_layer_register_write(
434 maximum_arbitration_wait_timer_timeout,
435 SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME
437 #endif // defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD)
439 // Disable the link layer hang detection timer
440 scu_link_layer_register_write(
441 this_phy, link_layer_hang_detection_timeout, 0x00000000
444 // We can exit the initial state to the stopped state
445 sci_base_state_machine_change_state(
446 scic_sds_phy_get_base_state_machine(this_phy),
447 SCI_BASE_PHY_STATE_STOPPED
454 * This function will handle the sata SIGNATURE FIS timeout condition. It
455 * will restart the starting substate machine since we dont know what has
456 * actually happening.
458 * @param[in] cookie This object is cast to the SCIC_SDS_PHY_T object.
462 void scic_sds_phy_sata_timeout( SCI_OBJECT_HANDLE_T cookie)
464 SCIC_SDS_PHY_T * this_phy = (SCIC_SDS_PHY_T *)cookie;
467 sci_base_object_get_logger(this_phy),
469 "SCIC SDS Phy 0x%x did not receive signature fis before timeout.\n",
473 sci_base_state_machine_stop(
474 scic_sds_phy_get_starting_substate_machine(this_phy));
476 sci_base_state_machine_change_state(
477 scic_sds_phy_get_base_state_machine(this_phy),
478 SCI_BASE_PHY_STATE_STARTING
482 //*****************************************************************************
483 //* SCIC SDS PHY External Methods
484 //*****************************************************************************
487 * @brief This method returns the object size for a phy object.
491 U32 scic_sds_phy_get_object_size(void)
493 return sizeof(SCIC_SDS_PHY_T);
497 * @brief This method returns the minimum number of timers required for a
502 U32 scic_sds_phy_get_min_timer_count(void)
504 return SCIC_SDS_PHY_MIN_TIMER_COUNT;
508 * @brief This method returns the maximum number of timers required for a
513 U32 scic_sds_phy_get_max_timer_count(void)
515 return SCIC_SDS_PHY_MAX_TIMER_COUNT;
520 void scic_sds_phy_initialize_state_logging(
521 SCIC_SDS_PHY_T *this_phy
524 sci_base_state_machine_logger_initialize(
525 &this_phy->parent.state_machine_logger,
526 &this_phy->parent.state_machine,
527 &this_phy->parent.parent,
528 scic_cb_logger_log_states,
529 "SCIC_SDS_PHY_T", "base state machine",
533 sci_base_state_machine_logger_initialize(
534 &this_phy->starting_substate_machine_logger,
535 &this_phy->starting_substate_machine,
536 &this_phy->parent.parent,
537 scic_cb_logger_log_states,
538 "SCIC_SDS_PHY_T", "starting substate machine",
542 #endif // SCI_LOGGING
544 #ifdef SCIC_DEBUG_ENABLED
546 * Debug code to record the state transitions in the phy
548 * @param our_observer
549 * @param the_state_machine
551 void scic_sds_phy_observe_state_change(
552 SCI_BASE_OBSERVER_T * our_observer,
553 SCI_BASE_SUBJECT_T * the_subject
556 SCIC_SDS_PHY_T *this_phy;
557 SCI_BASE_STATE_MACHINE_T *the_state_machine;
559 U8 transition_requestor;
561 U32 starting_substate_id;
563 the_state_machine = (SCI_BASE_STATE_MACHINE_T *)the_subject;
564 this_phy = (SCIC_SDS_PHY_T *)the_state_machine->state_machine_owner;
566 if (the_state_machine == &this_phy->parent.state_machine)
568 transition_requestor = 0x01;
570 else if (the_state_machine == &this_phy->starting_substate_machine)
572 transition_requestor = 0x02;
576 transition_requestor = 0xFF;
580 sci_base_state_machine_get_state(&this_phy->parent.state_machine);
581 starting_substate_id =
582 sci_base_state_machine_get_state(&this_phy->starting_substate_machine);
584 this_phy->state_record.state_transition_table[
585 this_phy->state_record.index++] = ( (transition_requestor << 24)
586 | ((U8)base_state_id << 8)
587 | ((U8)starting_substate_id));
589 this_phy->state_record.index =
590 this_phy->state_record.index & (MAX_STATE_TRANSITION_RECORD - 1);
593 #endif // SCIC_DEBUG_ENABLED
595 #ifdef SCIC_DEBUG_ENABLED
597 * This method initializes the state record debug information for the phy
600 * @pre The state machines for the phy object must be constructed before this
601 * function is called.
603 * @param this_phy The phy which is being initialized.
605 void scic_sds_phy_initialize_state_recording(
606 SCIC_SDS_PHY_T *this_phy
609 this_phy->state_record.index = 0;
611 sci_base_observer_initialize(
612 &this_phy->state_record.base_state_observer,
613 scic_sds_phy_observe_state_change,
614 &this_phy->parent.state_machine.parent
617 sci_base_observer_initialize(
618 &this_phy->state_record.starting_state_observer,
619 scic_sds_phy_observe_state_change,
620 &this_phy->starting_substate_machine.parent
623 #endif // SCIC_DEBUG_ENABLED
626 * @brief This method will construct the SCIC_SDS_PHY object
628 * @param[in] this_phy
629 * @param[in] owning_port
630 * @param[in] phy_index
634 void scic_sds_phy_construct(
635 SCIC_SDS_PHY_T *this_phy,
636 SCIC_SDS_PORT_T *owning_port,
640 // Call the base constructor first
641 // Copy the logger from the port (this could be the dummy port)
642 sci_base_phy_construct(
644 sci_base_object_get_logger(owning_port),
645 scic_sds_phy_state_table
648 // Copy the rest of the input data to our locals
649 this_phy->owning_port = owning_port;
650 this_phy->phy_index = phy_index;
651 this_phy->bcn_received_while_port_unassigned = FALSE;
652 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
653 this_phy->link_layer_registers = NULL;
654 this_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE;
655 this_phy->sata_timeout_timer = NULL;
657 // Clear out the identification buffer data
658 memset(&this_phy->phy_type, 0, sizeof(this_phy->phy_type));
660 // Clear out the error counter data
661 memset(this_phy->error_counter, 0, sizeof(this_phy->error_counter));
663 // Initialize the substate machines
664 sci_base_state_machine_construct(
665 &this_phy->starting_substate_machine,
666 &this_phy->parent.parent,
667 scic_sds_phy_starting_substates,
668 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
672 scic_sds_phy_initialize_state_logging(this_phy);
673 #endif // SCI_LOGGING
675 #ifdef SCIC_DEBUG_ENABLED
676 scic_sds_phy_initialize_state_recording(this_phy);
677 #endif // SCIC_DEBUG_ENABLED
681 * @brief This method returns the port currently containing this phy.
682 * If the phy is currently contained by the dummy port, then
683 * the phy is considered to not be part of a port.
685 * @param[in] this_phy This parameter specifies the phy for which to
686 * retrieve the containing port.
688 * @return This method returns a handle to a port that contains
690 * @retval SCI_INVALID_HANDLE This value is returned if the phy is not
691 * part of a real port (i.e. it's contained in the dummy port).
692 * @retval !SCI_INVALID_HANDLE All other values indicate a handle/pointer
693 * to the port containing the phy.
695 SCI_PORT_HANDLE_T scic_sds_phy_get_port(
696 SCIC_SDS_PHY_T *this_phy
700 sci_base_object_get_logger(this_phy),
702 "scic_phy_get_port(0x%x) enter\n",
706 if (scic_sds_port_get_index(this_phy->owning_port) == SCIC_SDS_DUMMY_PORT)
707 return SCI_INVALID_HANDLE;
709 return this_phy->owning_port;
713 * @brief This method will assign a port to the phy object.
715 * @param[in, out] this_phy This parameter specifies the phy for which
716 * to assign a port object.
717 * @param[in] the_port This parameter is the port to assing to the phy.
719 void scic_sds_phy_set_port(
720 SCIC_SDS_PHY_T * this_phy,
721 SCIC_SDS_PORT_T * the_port
724 this_phy->owning_port = the_port;
726 if (this_phy->bcn_received_while_port_unassigned)
728 this_phy->bcn_received_while_port_unassigned = FALSE;
729 scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy);
734 * @brief This method will initialize the constructed phy
736 * @param[in] this_phy
737 * @param[in] link_layer_registers
741 SCI_STATUS scic_sds_phy_initialize(
742 SCIC_SDS_PHY_T *this_phy,
743 void *transport_layer_registers,
744 SCU_LINK_LAYER_REGISTERS_T *link_layer_registers
748 sci_base_object_get_logger(this_phy),
750 "scic_sds_phy_initialize(this_phy:0x%x, link_layer_registers:0x%x)\n",
751 this_phy, link_layer_registers
754 // Perform the initialization of the TL hardware
755 scic_sds_phy_transport_layer_initialization(this_phy, transport_layer_registers);
757 // Perofrm the initialization of the PE hardware
758 scic_sds_phy_link_layer_initialization(this_phy, link_layer_registers);
760 // There is nothing that needs to be done in this state just
761 // transition to the stopped state.
762 sci_base_state_machine_change_state(
763 scic_sds_phy_get_base_state_machine(this_phy),
764 SCI_BASE_PHY_STATE_STOPPED
771 * This method assigns the direct attached device ID for this phy.
773 * @param[in] this_phy The phy for which the direct attached device id is to
775 * @param[in] device_id The direct attached device ID to assign to the phy.
776 * This will either be the RNi for the device or an invalid RNi if there
777 * is no current device assigned to the phy.
779 void scic_sds_phy_setup_transport(
780 SCIC_SDS_PHY_T * this_phy,
786 SCU_STPTLDARNI_WRITE(this_phy, device_id);
788 // The read should guarntee that the first write gets posted
789 // before the next write
790 tl_control = SCU_TLCR_READ(this_phy);
791 tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
792 SCU_TLCR_WRITE(this_phy, tl_control);
796 * This function will perform the register reads/writes to suspend the SCU
797 * hardware protocol engine.
799 * @param[in,out] this_phy The phy object to be suspended.
803 void scic_sds_phy_suspend(
804 SCIC_SDS_PHY_T * this_phy
807 U32 scu_sas_pcfg_value;
809 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
810 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
811 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
813 scic_sds_phy_setup_transport(
814 this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
819 * This function will perform the register reads/writes required to resume the
820 * SCU hardware protocol engine.
822 * @param[in,out] this_phy The phy object to resume.
826 void scic_sds_phy_resume(
827 SCIC_SDS_PHY_T * this_phy
830 U32 scu_sas_pcfg_value;
832 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
834 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
836 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
840 * @brief This method returns the local sas address assigned to this phy.
842 * @param[in] this_phy This parameter specifies the phy for which
843 * to retrieve the local SAS address.
844 * @param[out] sas_address This parameter specifies the location into
845 * which to copy the local SAS address.
849 void scic_sds_phy_get_sas_address(
850 SCIC_SDS_PHY_T *this_phy,
851 SCI_SAS_ADDRESS_T *sas_address
855 sci_base_object_get_logger(this_phy),
857 "scic_sds_phy_get_sas_address(this_phy:0x%x, sas_address:0x%x)\n",
858 this_phy, sas_address
861 sas_address->high = SCU_SAS_TISSAH_READ(this_phy);
862 sas_address->low = SCU_SAS_TISSAL_READ(this_phy);
866 * @brief This method returns the remote end-point (i.e. attached)
867 * sas address assigned to this phy.
869 * @param[in] this_phy This parameter specifies the phy for which
870 * to retrieve the remote end-point SAS address.
871 * @param[out] sas_address This parameter specifies the location into
872 * which to copy the remote end-point SAS address.
876 void scic_sds_phy_get_attached_sas_address(
877 SCIC_SDS_PHY_T *this_phy,
878 SCI_SAS_ADDRESS_T *sas_address
882 sci_base_object_get_logger(this_phy),
884 "scic_sds_phy_get_attached_sas_address(0x%x, 0x%x) enter\n",
885 this_phy, sas_address
889 = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high;
891 = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low;
895 * @brief This method returns the supported protocols assigned to
898 * @param[in] this_phy
899 * @param[out] protocols
901 void scic_sds_phy_get_protocols(
902 SCIC_SDS_PHY_T *this_phy,
903 SCI_SAS_IDENTIFY_ADDRESS_FRAME_PROTOCOLS_T * protocols
906 U32 tiid_value = SCU_SAS_TIID_READ(this_phy);
908 //Check each bit of this register. please refer to
909 //SAS Transmit Identification Register (SAS_TIID).
910 if (tiid_value & 0x2)
911 protocols->u.bits.smp_target = 1;
913 if (tiid_value & 0x4)
914 protocols->u.bits.stp_target = 1;
916 if (tiid_value & 0x8)
917 protocols->u.bits.ssp_target = 1;
919 if (tiid_value & 0x200)
920 protocols->u.bits.smp_initiator = 1;
922 if ((tiid_value & 0x400))
923 protocols->u.bits.stp_initiator = 1;
925 if (tiid_value & 0x800)
926 protocols->u.bits.ssp_initiator = 1;
929 sci_base_object_get_logger(this_phy),
931 "scic_sds_phy_get_protocols(this_phy:0x%x, protocols:0x%x)\n",
932 this_phy, protocols->u.all
937 * This method returns the supported protocols for the attached phy. If this
938 * is a SAS phy the protocols are returned from the identify address frame.
939 * If this is a SATA phy then protocols are made up and the target phy is an
942 * @note The caller will get the entire set of bits for the protocol value.
944 * @param[in] this_phy The parameter is the phy object for which the attached
945 * phy protcols are to be returned.
946 * @param[out] protocols The parameter is the returned protocols for the
949 void scic_sds_phy_get_attached_phy_protocols(
950 SCIC_SDS_PHY_T *this_phy,
951 SCI_SAS_IDENTIFY_ADDRESS_FRAME_PROTOCOLS_T * protocols
955 sci_base_object_get_logger(this_phy),
957 "scic_sds_phy_get_attached_phy_protocols(this_phy:0x%x, protocols:0x%x[0x%x])\n",
958 this_phy, protocols, protocols->u.all
961 protocols->u.all = 0;
963 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS)
966 this_phy->phy_type.sas.identify_address_frame_buffer.protocols.u.all;
968 else if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA)
970 protocols->u.bits.stp_target = 1;
976 * @brief This method release resources in for a scic phy.
978 * @param[in] controller This parameter specifies the core controller, one of
979 * its phy's resources are to be released.
980 * @param[in] this_phy This parameter specifies the phy whose resource is to
983 void scic_sds_phy_release_resource(
984 SCIC_SDS_CONTROLLER_T * controller,
985 SCIC_SDS_PHY_T * this_phy
989 sci_base_object_get_logger(this_phy),
991 "scic_sds_phy_release_resource(0x%x, 0x%x)\n",
995 //Currently, the only resource to be released is a timer.
996 if (this_phy->sata_timeout_timer != NULL)
998 scic_cb_timer_destroy(controller, this_phy->sata_timeout_timer);
999 this_phy->sata_timeout_timer = NULL;
1004 //*****************************************************************************
1005 //* SCIC SDS PHY Handler Redirects
1006 //*****************************************************************************
1009 * @brief This method will attempt to reset the phy. This
1010 * request is only valid when the phy is in an ready
1013 * @param[in] this_phy
1015 * @return SCI_STATUS
1017 SCI_STATUS scic_sds_phy_reset(
1018 SCIC_SDS_PHY_T * this_phy
1022 sci_base_object_get_logger(this_phy),
1023 SCIC_LOG_OBJECT_PHY,
1024 "scic_sds_phy_reset(this_phy:0x%08x)\n",
1028 return this_phy->state_handlers->parent.reset_handler(
1034 * @brief This method will process the event code received.
1036 * @param[in] this_phy
1037 * @param[in] event_code
1039 * @return SCI_STATUS
1041 SCI_STATUS scic_sds_phy_event_handler(
1042 SCIC_SDS_PHY_T *this_phy,
1047 sci_base_object_get_logger(this_phy),
1048 SCIC_LOG_OBJECT_PHY,
1049 "scic_sds_phy_event_handler(this_phy:0x%08x, event_code:%x)\n",
1050 this_phy, event_code
1053 return this_phy->state_handlers->event_handler(this_phy, event_code);
1057 * @brief This method will process the frame index received.
1059 * @param[in] this_phy
1060 * @param[in] frame_index
1062 * @return SCI_STATUS
1064 SCI_STATUS scic_sds_phy_frame_handler(
1065 SCIC_SDS_PHY_T *this_phy,
1070 sci_base_object_get_logger(this_phy),
1071 SCIC_LOG_OBJECT_PHY,
1072 "scic_sds_phy_frame_handler(this_phy:0x%08x, frame_index:%d)\n",
1073 this_phy, frame_index
1076 return this_phy->state_handlers->frame_handler(this_phy, frame_index);
1080 * @brief This method will give the phy permission to consume power
1082 * @param[in] this_phy
1084 * @return SCI_STATUS
1086 SCI_STATUS scic_sds_phy_consume_power_handler(
1087 SCIC_SDS_PHY_T *this_phy
1091 sci_base_object_get_logger(this_phy),
1092 SCIC_LOG_OBJECT_PHY,
1093 "scic_sds_phy_consume_power_handler(this_phy:0x%08x)\n",
1097 return this_phy->state_handlers->consume_power_handler(this_phy);
1100 //*****************************************************************************
1101 //* SCIC PHY Public Methods
1102 //*****************************************************************************
1104 SCI_STATUS scic_phy_get_properties(
1105 SCI_PHY_HANDLE_T phy,
1106 SCIC_PHY_PROPERTIES_T * properties
1109 SCIC_SDS_PHY_T *this_phy;
1110 U8 max_speed_generation;
1112 this_phy = (SCIC_SDS_PHY_T *)phy;
1115 sci_base_object_get_logger(this_phy),
1116 SCIC_LOG_OBJECT_PHY,
1117 "scic_phy_get_properties(0x%x, 0x%x) enter\n",
1118 this_phy, properties
1121 if (phy == SCI_INVALID_HANDLE)
1123 return SCI_FAILURE_INVALID_PHY;
1126 memset(properties, 0, sizeof(SCIC_PHY_PROPERTIES_T));
1128 //get max link rate of this phy set by user.
1129 max_speed_generation =
1130 this_phy->owning_port->owning_controller->user_parameters.sds1.
1131 phys[this_phy->phy_index].max_speed_generation;
1133 properties->negotiated_link_rate = this_phy->max_negotiated_speed;
1135 if (max_speed_generation == SCIC_SDS_PARM_GEN3_SPEED)
1136 properties->max_link_rate = SCI_SAS_600_GB;
1137 else if (max_speed_generation == SCIC_SDS_PARM_GEN2_SPEED)
1138 properties->max_link_rate = SCI_SAS_300_GB;
1140 properties->max_link_rate = SCI_SAS_150_GB;
1142 properties->index = this_phy->phy_index;
1143 properties->owning_port = scic_sds_phy_get_port(this_phy);
1145 scic_sds_phy_get_protocols(this_phy, &properties->transmit_iaf.protocols);
1147 properties->transmit_iaf.sas_address.high =
1148 this_phy->owning_port->owning_controller->oem_parameters.sds1.
1149 phys[this_phy->phy_index].sas_address.sci_format.high;
1151 properties->transmit_iaf.sas_address.low =
1152 this_phy->owning_port->owning_controller->oem_parameters.sds1.
1153 phys[this_phy->phy_index].sas_address.sci_format.low;
1158 // ---------------------------------------------------------------------------
1160 SCI_STATUS scic_sas_phy_get_properties(
1161 SCI_PHY_HANDLE_T phy,
1162 SCIC_SAS_PHY_PROPERTIES_T * properties
1165 SCIC_SDS_PHY_T *this_phy;
1166 this_phy = (SCIC_SDS_PHY_T *)phy;
1169 sci_base_object_get_logger(this_phy),
1170 SCIC_LOG_OBJECT_PHY,
1171 "scic_sas_phy_get_properties(0x%x, 0x%x) enter\n",
1172 this_phy, properties
1175 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS)
1178 &properties->received_iaf,
1179 &this_phy->phy_type.sas.identify_address_frame_buffer,
1180 sizeof(SCI_SAS_IDENTIFY_ADDRESS_FRAME_T)
1183 properties->received_capabilities.u.all
1184 = SCU_SAS_RECPHYCAP_READ(this_phy);
1192 // ---------------------------------------------------------------------------
1194 SCI_STATUS scic_sata_phy_get_properties(
1195 SCI_PHY_HANDLE_T phy,
1196 SCIC_SATA_PHY_PROPERTIES_T * properties
1199 SCIC_SDS_PHY_T *this_phy;
1200 this_phy = (SCIC_SDS_PHY_T *)phy;
1203 sci_base_object_get_logger(this_phy),
1204 SCIC_LOG_OBJECT_PHY,
1205 "scic_sata_phy_get_properties(0x%x, 0x%x) enter\n",
1206 this_phy, properties
1209 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA)
1212 &properties->signature_fis,
1213 &this_phy->phy_type.sata.signature_fis_buffer,
1214 sizeof(SATA_FIS_REG_D2H_T)
1217 /// @todo add support for port selectors.
1218 properties->is_port_selector_present = FALSE;
1226 // ---------------------------------------------------------------------------
1228 #if !defined(DISABLE_PORT_SELECTORS)
1230 SCI_STATUS scic_sata_phy_send_port_selection_signal(
1231 SCI_PHY_HANDLE_T phy
1234 SCIC_SDS_PHY_T *this_phy;
1235 this_phy = (SCIC_SDS_PHY_T *)phy;
1238 sci_base_object_get_logger(this_phy),
1239 SCIC_LOG_OBJECT_PHY,
1240 "scic_sata_phy_send_port_selection_signals(0x%x) enter\n",
1244 /// @todo To be implemented
1249 #endif // !defined(DISABLE_PORT_SELECTORS)
1251 // ---------------------------------------------------------------------------
1253 #if !defined(DISABLE_PHY_COUNTERS)
1255 SCI_STATUS scic_phy_enable_counter(
1256 SCI_PHY_HANDLE_T phy,
1257 SCIC_PHY_COUNTER_ID_T counter_id
1260 SCIC_SDS_PHY_T *this_phy;
1261 SCI_STATUS status = SCI_SUCCESS;
1262 this_phy = (SCIC_SDS_PHY_T *)phy;
1265 sci_base_object_get_logger(this_phy),
1266 SCIC_LOG_OBJECT_PHY,
1267 "scic_phy_enable_counter(0x%x, 0x%x) enter\n",
1268 this_phy, counter_id
1273 case SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT:
1275 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1276 control |= (1 << SCU_ERR_CNT_RX_DONE_ACK_NAK_TIMEOUT_INDEX);
1277 SCU_SAS_ECENCR_WRITE(this_phy, control);
1280 case SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT:
1282 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1283 control |= (1 << SCU_ERR_CNT_TX_DONE_ACK_NAK_TIMEOUT_INDEX);
1284 SCU_SAS_ECENCR_WRITE(this_phy, control);
1287 case SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED:
1289 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1290 control |= (1 << SCU_ERR_CNT_INACTIVITY_TIMER_EXPIRED_INDEX);
1291 SCU_SAS_ECENCR_WRITE(this_phy, control);
1294 case SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT:
1296 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1297 control |= (1 << SCU_ERR_CNT_RX_DONE_CREDIT_TIMEOUT_INDEX);
1298 SCU_SAS_ECENCR_WRITE(this_phy, control);
1301 case SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT:
1303 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1304 control |= (1 << SCU_ERR_CNT_TX_DONE_CREDIT_TIMEOUT_INDEX);
1305 SCU_SAS_ECENCR_WRITE(this_phy, control);
1308 case SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED:
1310 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1311 control |= (1 << SCU_ERR_CNT_RX_CREDIT_BLOCKED_RECEIVED_INDEX);
1312 SCU_SAS_ECENCR_WRITE(this_phy, control);
1316 // These error counters are enabled by default, and cannot be
1317 // disabled. Return SCI_SUCCESS to denote that they are
1318 // enabled, hiding the fact that enabling the counter is
1320 case SCIC_PHY_COUNTER_RECEIVED_FRAME:
1321 case SCIC_PHY_COUNTER_TRANSMITTED_FRAME:
1322 case SCIC_PHY_COUNTER_RECEIVED_FRAME_DWORD:
1323 case SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD:
1324 case SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR:
1325 case SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR:
1326 case SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR:
1327 case SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME:
1328 case SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT:
1329 case SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE:
1330 case SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR:
1334 status = SCI_FAILURE;
1340 // ---------------------------------------------------------------------------
1342 SCI_STATUS scic_phy_disable_counter(
1343 SCI_PHY_HANDLE_T phy,
1344 SCIC_PHY_COUNTER_ID_T counter_id
1347 SCIC_SDS_PHY_T *this_phy;
1348 SCI_STATUS status = SCI_SUCCESS;
1350 this_phy = (SCIC_SDS_PHY_T *)phy;
1353 sci_base_object_get_logger(this_phy),
1354 SCIC_LOG_OBJECT_PHY,
1355 "scic_phy_disable_counter(0x%x, 0x%x) enter\n",
1356 this_phy, counter_id
1361 case SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT:
1363 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1364 control &= ~(1 << SCU_ERR_CNT_RX_DONE_ACK_NAK_TIMEOUT_INDEX);
1365 SCU_SAS_ECENCR_WRITE(this_phy, control);
1368 case SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT:
1370 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1371 control &= ~(1 << SCU_ERR_CNT_TX_DONE_ACK_NAK_TIMEOUT_INDEX);
1372 SCU_SAS_ECENCR_WRITE(this_phy, control);
1375 case SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED:
1377 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1378 control &= ~(1 << SCU_ERR_CNT_INACTIVITY_TIMER_EXPIRED_INDEX);
1379 SCU_SAS_ECENCR_WRITE(this_phy, control);
1382 case SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT:
1384 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1385 control &= ~(1 << SCU_ERR_CNT_RX_DONE_CREDIT_TIMEOUT_INDEX);
1386 SCU_SAS_ECENCR_WRITE(this_phy, control);
1389 case SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT:
1391 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1392 control &= ~(1 << SCU_ERR_CNT_TX_DONE_CREDIT_TIMEOUT_INDEX);
1393 SCU_SAS_ECENCR_WRITE(this_phy, control);
1396 case SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED:
1398 U32 control = SCU_SAS_ECENCR_READ(this_phy);
1399 control &= ~(1 << SCU_ERR_CNT_RX_CREDIT_BLOCKED_RECEIVED_INDEX);
1400 SCU_SAS_ECENCR_WRITE(this_phy, control);
1404 // These error counters cannot be disabled, so return SCI_FAILURE.
1405 case SCIC_PHY_COUNTER_RECEIVED_FRAME:
1406 case SCIC_PHY_COUNTER_TRANSMITTED_FRAME:
1407 case SCIC_PHY_COUNTER_RECEIVED_FRAME_DWORD:
1408 case SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD:
1409 case SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR:
1410 case SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR:
1411 case SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR:
1412 case SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME:
1413 case SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT:
1414 case SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE:
1415 case SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR:
1417 status = SCI_FAILURE;
1423 // ---------------------------------------------------------------------------
1425 SCI_STATUS scic_phy_get_counter(
1426 SCI_PHY_HANDLE_T phy,
1427 SCIC_PHY_COUNTER_ID_T counter_id,
1431 SCIC_SDS_PHY_T *this_phy;
1432 SCI_STATUS status = SCI_SUCCESS;
1433 this_phy = (SCIC_SDS_PHY_T *)phy;
1436 sci_base_object_get_logger(this_phy),
1437 SCIC_LOG_OBJECT_PHY,
1438 "scic_phy_get_counter(0x%x, 0x%x) enter\n",
1439 this_phy, counter_id
1444 case SCIC_PHY_COUNTER_RECEIVED_FRAME:
1445 *data = scu_link_layer_register_read(this_phy, received_frame_count);
1447 case SCIC_PHY_COUNTER_TRANSMITTED_FRAME:
1448 *data = scu_link_layer_register_read(this_phy, transmit_frame_count);
1450 case SCIC_PHY_COUNTER_RECEIVED_FRAME_DWORD:
1451 *data = scu_link_layer_register_read(this_phy, received_dword_count);
1453 case SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD:
1454 *data = scu_link_layer_register_read(this_phy, transmit_dword_count);
1456 case SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR:
1457 *data = scu_link_layer_register_read(this_phy, loss_of_sync_error_count);
1459 case SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR:
1460 *data = scu_link_layer_register_read(this_phy, running_disparity_error_count);
1462 case SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR:
1463 *data = scu_link_layer_register_read(this_phy, received_frame_crc_error_count);
1465 case SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT:
1466 *data = this_phy->error_counter[SCU_ERR_CNT_RX_DONE_ACK_NAK_TIMEOUT_INDEX];
1468 case SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT:
1469 *data = this_phy->error_counter[SCU_ERR_CNT_TX_DONE_ACK_NAK_TIMEOUT_INDEX];
1471 case SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED:
1472 *data = this_phy->error_counter[SCU_ERR_CNT_INACTIVITY_TIMER_EXPIRED_INDEX];
1474 case SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT:
1475 *data = this_phy->error_counter[SCU_ERR_CNT_RX_DONE_CREDIT_TIMEOUT_INDEX];
1477 case SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT:
1478 *data = this_phy->error_counter[SCU_ERR_CNT_TX_DONE_CREDIT_TIMEOUT_INDEX];
1480 case SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED:
1481 *data = this_phy->error_counter[SCU_ERR_CNT_RX_CREDIT_BLOCKED_RECEIVED_INDEX];
1483 case SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME:
1484 *data = scu_link_layer_register_read(this_phy, received_short_frame_count);
1486 case SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT:
1487 *data = scu_link_layer_register_read(this_phy, received_frame_without_credit_count);
1489 case SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE:
1490 *data = scu_link_layer_register_read(this_phy, received_frame_after_done_count);
1492 case SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR:
1493 *data = scu_link_layer_register_read(this_phy, phy_reset_problem_count);
1496 status = SCI_FAILURE;
1503 // ---------------------------------------------------------------------------
1505 SCI_STATUS scic_phy_clear_counter(
1506 SCI_PHY_HANDLE_T phy,
1507 SCIC_PHY_COUNTER_ID_T counter_id
1510 SCIC_SDS_PHY_T *this_phy;
1511 SCI_STATUS status = SCI_SUCCESS;
1512 this_phy = (SCIC_SDS_PHY_T *)phy;
1515 sci_base_object_get_logger(this_phy),
1516 SCIC_LOG_OBJECT_PHY,
1517 "scic_phy_clear_counter(0x%x, 0x%x) enter\n",
1518 this_phy, counter_id
1523 case SCIC_PHY_COUNTER_RECEIVED_FRAME:
1524 scu_link_layer_register_write(this_phy, received_frame_count, 0);
1526 case SCIC_PHY_COUNTER_TRANSMITTED_FRAME:
1527 scu_link_layer_register_write(this_phy, transmit_frame_count, 0);
1529 case SCIC_PHY_COUNTER_RECEIVED_FRAME_DWORD:
1530 scu_link_layer_register_write(this_phy, received_dword_count, 0);
1532 case SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD:
1533 scu_link_layer_register_write(this_phy, transmit_dword_count, 0);
1535 case SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR:
1536 scu_link_layer_register_write(this_phy, loss_of_sync_error_count, 0);
1538 case SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR:
1539 scu_link_layer_register_write(this_phy, running_disparity_error_count, 0);
1541 case SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR:
1542 scu_link_layer_register_write(this_phy, received_frame_crc_error_count, 0);
1544 case SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT:
1545 this_phy->error_counter[SCU_ERR_CNT_RX_DONE_ACK_NAK_TIMEOUT_INDEX] = 0;
1547 case SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT:
1548 this_phy->error_counter[SCU_ERR_CNT_TX_DONE_ACK_NAK_TIMEOUT_INDEX] = 0;
1550 case SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED:
1551 this_phy->error_counter[SCU_ERR_CNT_INACTIVITY_TIMER_EXPIRED_INDEX] = 0;
1553 case SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT:
1554 this_phy->error_counter[SCU_ERR_CNT_RX_DONE_CREDIT_TIMEOUT_INDEX] = 0;
1556 case SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT:
1557 this_phy->error_counter[SCU_ERR_CNT_TX_DONE_CREDIT_TIMEOUT_INDEX] = 0;
1559 case SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED:
1560 this_phy->error_counter[SCU_ERR_CNT_RX_CREDIT_BLOCKED_RECEIVED_INDEX] = 0;
1562 case SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME:
1563 scu_link_layer_register_write(this_phy, received_short_frame_count, 0);
1565 case SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT:
1566 scu_link_layer_register_write(this_phy, received_frame_without_credit_count, 0);
1568 case SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE:
1569 scu_link_layer_register_write(this_phy, received_frame_after_done_count, 0);
1571 case SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR:
1572 scu_link_layer_register_write(this_phy, phy_reset_problem_count, 0);
1575 status = SCI_FAILURE;
1581 #endif // !defined(DISABLE_PHY_COUNTERS)
1583 SCI_STATUS scic_phy_stop(
1584 SCI_PHY_HANDLE_T phy
1587 SCIC_SDS_PHY_T *this_phy;
1588 this_phy = (SCIC_SDS_PHY_T *)phy;
1591 sci_base_object_get_logger(this_phy),
1592 SCIC_LOG_OBJECT_PHY,
1593 "scic_phy_stop(this_phy:0x%x)\n",
1597 return this_phy->state_handlers->parent.stop_handler(&this_phy->parent);
1600 SCI_STATUS scic_phy_start(
1601 SCI_PHY_HANDLE_T phy
1604 SCIC_SDS_PHY_T *this_phy;
1605 this_phy = (SCIC_SDS_PHY_T *)phy;
1608 sci_base_object_get_logger(this_phy),
1609 SCIC_LOG_OBJECT_PHY,
1610 "scic_phy_start(this_phy:0x%x)\n",
1614 return this_phy->state_handlers->parent.start_handler(&this_phy->parent);
1617 //******************************************************************************
1618 //* PHY STATE MACHINE
1619 //******************************************************************************
1621 //***************************************************************************
1622 //* DEFAULT HANDLERS
1623 //***************************************************************************
1626 * This is the default method for phy a start request. It will report a
1629 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1630 * SCIC_SDS_PHY object.
1632 * @return SCI_STATUS
1633 * @retval SCI_FAILURE_INVALID_STATE
1635 SCI_STATUS scic_sds_phy_default_start_handler(
1639 SCIC_SDS_PHY_T *this_phy;
1640 this_phy = (SCIC_SDS_PHY_T *)phy;
1643 sci_base_object_get_logger(this_phy),
1644 SCIC_LOG_OBJECT_PHY,
1645 "SCIC Phy 0x%08x requested to start from invalid state %d\n",
1647 sci_base_state_machine_get_state(&this_phy->parent.state_machine)
1650 return SCI_FAILURE_INVALID_STATE;
1655 * This is the default method for phy a stop request. It will report a
1658 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1659 * SCIC_SDS_PHY object.
1661 * @return SCI_STATUS
1662 * @retval SCI_FAILURE_INVALID_STATE
1664 SCI_STATUS scic_sds_phy_default_stop_handler(
1668 SCIC_SDS_PHY_T *this_phy;
1669 this_phy = (SCIC_SDS_PHY_T *)phy;
1672 sci_base_object_get_logger(this_phy),
1673 SCIC_LOG_OBJECT_PHY,
1674 "SCIC Phy 0x%08x requested to stop from invalid state %d\n",
1676 sci_base_state_machine_get_state(&this_phy->parent.state_machine)
1679 return SCI_FAILURE_INVALID_STATE;
1683 * This is the default method for phy a reset request. It will report a
1686 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1687 * SCIC_SDS_PHY object.
1689 * @return SCI_STATUS
1690 * @retval SCI_FAILURE_INVALID_STATE
1692 SCI_STATUS scic_sds_phy_default_reset_handler(
1693 SCI_BASE_PHY_T * phy
1696 SCIC_SDS_PHY_T *this_phy;
1697 this_phy = (SCIC_SDS_PHY_T *)phy;
1700 sci_base_object_get_logger(this_phy),
1701 SCIC_LOG_OBJECT_PHY,
1702 "SCIC Phy 0x%08x requested to reset from invalid state %d\n",
1704 sci_base_state_machine_get_state(&this_phy->parent.state_machine)
1707 return SCI_FAILURE_INVALID_STATE;
1711 * This is the default method for phy a destruct request. It will report a
1714 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1715 * SCIC_SDS_PHY object.
1717 * @return SCI_STATUS
1718 * @retval SCI_FAILURE_INVALID_STATE
1720 SCI_STATUS scic_sds_phy_default_destroy_handler(
1724 SCIC_SDS_PHY_T *this_phy;
1725 this_phy = (SCIC_SDS_PHY_T *)phy;
1727 /// @todo Implement something for the default
1729 sci_base_object_get_logger(this_phy),
1730 SCIC_LOG_OBJECT_PHY,
1731 "SCIC Phy 0x%08x requested to destroy from invalid state %d\n",
1733 sci_base_state_machine_get_state(&this_phy->parent.state_machine)
1736 return SCI_FAILURE_INVALID_STATE;
1740 * This is the default method for a phy frame handling request. It will
1741 * report a warning, release the frame and exit.
1743 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1744 * SCIC_SDS_PHY object.
1745 * @param[in] frame_index This is the frame index that was received from the
1748 * @return SCI_STATUS
1749 * @retval SCI_FAILURE_INVALID_STATE
1751 SCI_STATUS scic_sds_phy_default_frame_handler(
1752 SCIC_SDS_PHY_T *this_phy,
1757 sci_base_object_get_logger(this_phy),
1758 SCIC_LOG_OBJECT_PHY,
1759 "SCIC Phy 0x%08x received unexpected frame data %d while in state %d\n",
1760 this_phy, frame_index,
1761 sci_base_state_machine_get_state(&this_phy->parent.state_machine)
1764 scic_sds_controller_release_frame(
1765 scic_sds_phy_get_controller(this_phy), frame_index);
1767 return SCI_FAILURE_INVALID_STATE;
1771 * This is the default method for a phy event handler. It will report a
1774 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1775 * SCIC_SDS_PHY object.
1776 * @param[in] event_code This is the event code that was received from the SCU
1779 * @return SCI_STATUS
1780 * @retval SCI_FAILURE_INVALID_STATE
1782 SCI_STATUS scic_sds_phy_default_event_handler(
1783 SCIC_SDS_PHY_T *this_phy,
1788 sci_base_object_get_logger(this_phy),
1789 SCIC_LOG_OBJECT_PHY,
1790 "SCIC Phy 0x%08x received unexpected event status %x while in state %d\n",
1791 this_phy, event_code,
1792 sci_base_state_machine_get_state(&this_phy->parent.state_machine)
1795 return SCI_FAILURE_INVALID_STATE;
1799 * This is the default method for a phy consume power handler. It will report
1800 * a warning and exit.
1802 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1803 * SCIC_SDS_PHY object.
1805 * @return SCI_STATUS
1806 * @retval SCI_FAILURE_INVALID_STATE
1808 SCI_STATUS scic_sds_phy_default_consume_power_handler(
1809 SCIC_SDS_PHY_T *this_phy
1813 sci_base_object_get_logger(this_phy),
1814 SCIC_LOG_OBJECT_PHY,
1815 "SCIC Phy 0x%08x given unexpected permission to consume power while in state %d\n",
1817 sci_base_state_machine_get_state(&this_phy->parent.state_machine)
1820 return SCI_FAILURE_INVALID_STATE;
1823 //******************************************************************************
1824 //* PHY STOPPED STATE HANDLERS
1825 //******************************************************************************
1828 * This method takes the SCIC_SDS_PHY from a stopped state and attempts to
1830 * - The phy state machine is transitioned to the
1831 * SCI_BASE_PHY_STATE_STARTING.
1833 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1834 * SCIC_SDS_PHY object.
1836 * @return SCI_STATUS
1837 * @retval SCI_SUCCESS
1840 SCI_STATUS scic_sds_phy_stopped_state_start_handler(
1844 SCIC_SDS_PHY_T *this_phy;
1845 this_phy = (SCIC_SDS_PHY_T *)phy;
1849 // Create the SIGNATURE FIS Timeout timer for this phy
1850 this_phy->sata_timeout_timer = scic_cb_timer_create(
1851 scic_sds_phy_get_controller(this_phy),
1852 scic_sds_phy_sata_timeout,
1856 if (this_phy->sata_timeout_timer != NULL)
1858 sci_base_state_machine_change_state(
1859 scic_sds_phy_get_base_state_machine(this_phy),
1860 SCI_BASE_PHY_STATE_STARTING
1868 * This method takes the SCIC_SDS_PHY from a stopped state and destroys it.
1869 * - This function takes no action.
1871 * @todo Shouldn't this function transition the SCI_BASE_PHY::state_machine to
1872 * the SCI_BASE_PHY_STATE_FINAL?
1874 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1875 * SCIC_SDS_PHY object.
1877 * @return SCI_STATUS
1878 * @retval SCI_SUCCESS
1881 SCI_STATUS scic_sds_phy_stopped_state_destroy_handler(
1885 SCIC_SDS_PHY_T *this_phy;
1886 this_phy = (SCIC_SDS_PHY_T *)phy;
1888 /// @todo what do we actually need to do here?
1892 //******************************************************************************
1893 //* PHY STARTING STATE HANDLERS
1894 //******************************************************************************
1896 // All of these state handlers are mapped to the starting sub-state machine
1898 //******************************************************************************
1899 //* PHY READY STATE HANDLERS
1900 //******************************************************************************
1903 * This method takes the SCIC_SDS_PHY from a ready state and attempts to stop
1905 * - The phy state machine is transitioned to the SCI_BASE_PHY_STATE_STOPPED.
1907 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1908 * SCIC_SDS_PHY object.
1910 * @return SCI_STATUS
1911 * @retval SCI_SUCCESS
1914 SCI_STATUS scic_sds_phy_ready_state_stop_handler(
1918 SCIC_SDS_PHY_T *this_phy;
1919 this_phy = (SCIC_SDS_PHY_T *)phy;
1921 sci_base_state_machine_change_state(
1922 scic_sds_phy_get_base_state_machine(this_phy),
1923 SCI_BASE_PHY_STATE_STOPPED
1926 scic_sds_controller_link_down(
1927 scic_sds_phy_get_controller(this_phy),
1928 scic_sds_phy_get_port(this_phy),
1936 * This method takes the SCIC_SDS_PHY from a ready state and attempts to reset
1938 * - The phy state machine is transitioned to the SCI_BASE_PHY_STATE_STARTING.
1940 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
1941 * SCIC_SDS_PHY object.
1943 * @return SCI_STATUS
1944 * @retval SCI_SUCCESS
1947 SCI_STATUS scic_sds_phy_ready_state_reset_handler(
1948 SCI_BASE_PHY_T * phy
1951 SCIC_SDS_PHY_T * this_phy;
1952 this_phy = (SCIC_SDS_PHY_T *)phy;
1954 sci_base_state_machine_change_state(
1955 scic_sds_phy_get_base_state_machine(this_phy),
1956 SCI_BASE_PHY_STATE_RESETTING
1963 * This method request the SCIC_SDS_PHY handle the received event. The only
1964 * event that we are interested in while in the ready state is the link
1966 * - decoded event is a link failure
1967 * - transition the SCIC_SDS_PHY back to the SCI_BASE_PHY_STATE_STARTING
1969 * - any other event received will report a warning message
1971 * @param[in] phy This is the SCIC_SDS_PHY object which has received the
1974 * @return SCI_STATUS
1975 * @retval SCI_SUCCESS if the event received is a link failure
1976 * @retval SCI_FAILURE_INVALID_STATE for any other event received.
1979 SCI_STATUS scic_sds_phy_ready_state_event_handler(
1980 SCIC_SDS_PHY_T *this_phy,
1984 SCI_STATUS result = SCI_FAILURE;
1986 switch (scu_get_event_code(event_code))
1988 case SCU_EVENT_LINK_FAILURE:
1989 // Link failure change state back to the starting state
1990 sci_base_state_machine_change_state(
1991 scic_sds_phy_get_base_state_machine(this_phy),
1992 SCI_BASE_PHY_STATE_STARTING
1995 result = SCI_SUCCESS;
1998 case SCU_EVENT_BROADCAST_CHANGE:
1999 // Broadcast change received. Notify the port.
2000 if (scic_sds_phy_get_port(this_phy) != SCI_INVALID_HANDLE)
2001 scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy);
2003 this_phy->bcn_received_while_port_unassigned = TRUE;
2006 case SCU_EVENT_ERR_CNT(RX_CREDIT_BLOCKED_RECEIVED):
2007 case SCU_EVENT_ERR_CNT(TX_DONE_CREDIT_TIMEOUT):
2008 case SCU_EVENT_ERR_CNT(RX_DONE_CREDIT_TIMEOUT):
2009 case SCU_EVENT_ERR_CNT(INACTIVITY_TIMER_EXPIRED):
2010 case SCU_EVENT_ERR_CNT(TX_DONE_ACK_NAK_TIMEOUT):
2011 case SCU_EVENT_ERR_CNT(RX_DONE_ACK_NAK_TIMEOUT):
2013 U32 error_counter_index =
2014 scu_get_event_specifier(event_code) >> SCU_EVENT_SPECIFIC_CODE_SHIFT;
2016 this_phy->error_counter[error_counter_index]++;
2017 result = SCI_SUCCESS;
2023 sci_base_object_get_logger(this_phy),
2024 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
2025 "SCIC PHY 0x%x ready state machine received unexpected event_code %x\n",
2026 this_phy, event_code
2028 result = SCI_FAILURE_INVALID_STATE;
2035 // ---------------------------------------------------------------------------
2038 * This is the resetting state event handler.
2040 * @param[in] this_phy This is the SCIC_SDS_PHY object which is receiving the
2042 * @param[in] event_code This is the event code to be processed.
2044 * @return SCI_STATUS
2045 * @retval SCI_FAILURE_INVALID_STATE
2048 SCI_STATUS scic_sds_phy_resetting_state_event_handler(
2049 SCIC_SDS_PHY_T *this_phy,
2053 SCI_STATUS result = SCI_FAILURE;
2055 switch (scu_get_event_code(event_code))
2057 case SCU_EVENT_HARD_RESET_TRANSMITTED:
2058 // Link failure change state back to the starting state
2059 sci_base_state_machine_change_state(
2060 scic_sds_phy_get_base_state_machine(this_phy),
2061 SCI_BASE_PHY_STATE_STARTING
2064 result = SCI_SUCCESS;
2069 sci_base_object_get_logger(this_phy),
2070 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
2071 "SCIC PHY 0x%x resetting state machine received unexpected event_code %x\n",
2072 this_phy, event_code
2075 result = SCI_FAILURE_INVALID_STATE;
2082 // ---------------------------------------------------------------------------
2084 SCIC_SDS_PHY_STATE_HANDLER_T
2085 scic_sds_phy_state_handler_table[SCI_BASE_PHY_MAX_STATES] =
2087 // SCI_BASE_PHY_STATE_INITIAL
2090 scic_sds_phy_default_start_handler,
2091 scic_sds_phy_default_stop_handler,
2092 scic_sds_phy_default_reset_handler,
2093 scic_sds_phy_default_destroy_handler
2095 scic_sds_phy_default_frame_handler,
2096 scic_sds_phy_default_event_handler,
2097 scic_sds_phy_default_consume_power_handler
2099 // SCI_BASE_PHY_STATE_STOPPED
2102 scic_sds_phy_stopped_state_start_handler,
2103 scic_sds_phy_default_stop_handler,
2104 scic_sds_phy_default_reset_handler,
2105 scic_sds_phy_stopped_state_destroy_handler
2107 scic_sds_phy_default_frame_handler,
2108 scic_sds_phy_default_event_handler,
2109 scic_sds_phy_default_consume_power_handler
2111 // SCI_BASE_PHY_STATE_STARTING
2114 scic_sds_phy_default_start_handler,
2115 scic_sds_phy_default_stop_handler,
2116 scic_sds_phy_default_reset_handler,
2117 scic_sds_phy_default_destroy_handler
2119 scic_sds_phy_default_frame_handler,
2120 scic_sds_phy_default_event_handler,
2121 scic_sds_phy_default_consume_power_handler
2123 // SCI_BASE_PHY_STATE_READY
2126 scic_sds_phy_default_start_handler,
2127 scic_sds_phy_ready_state_stop_handler,
2128 scic_sds_phy_ready_state_reset_handler,
2129 scic_sds_phy_default_destroy_handler
2131 scic_sds_phy_default_frame_handler,
2132 scic_sds_phy_ready_state_event_handler,
2133 scic_sds_phy_default_consume_power_handler
2135 // SCI_BASE_PHY_STATE_RESETTING
2138 scic_sds_phy_default_start_handler,
2139 scic_sds_phy_default_stop_handler,
2140 scic_sds_phy_default_reset_handler,
2141 scic_sds_phy_default_destroy_handler
2143 scic_sds_phy_default_frame_handler,
2144 scic_sds_phy_resetting_state_event_handler,
2145 scic_sds_phy_default_consume_power_handler
2147 // SCI_BASE_PHY_STATE_FINAL
2150 scic_sds_phy_default_start_handler,
2151 scic_sds_phy_default_stop_handler,
2152 scic_sds_phy_default_reset_handler,
2153 scic_sds_phy_default_destroy_handler
2155 scic_sds_phy_default_frame_handler,
2156 scic_sds_phy_default_event_handler,
2157 scic_sds_phy_default_consume_power_handler
2161 //****************************************************************************
2162 //* PHY STATE PRIVATE METHODS
2163 //****************************************************************************
2166 * This method will stop the SCIC_SDS_PHY object. This does not reset the
2167 * protocol engine it just suspends it and places it in a state where it will
2168 * not cause the end device to power up.
2170 * @param[in] this_phy This is the SCIC_SDS_PHY object to stop.
2175 void scu_link_layer_stop_protocol_engine(
2176 SCIC_SDS_PHY_T *this_phy
2179 U32 scu_sas_pcfg_value;
2180 U32 enable_spinup_value;
2182 // Suspend the protocol engine and place it in a sata spinup hold state
2183 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2184 scu_sas_pcfg_value |= (
2185 SCU_SAS_PCFG_GEN_BIT(OOB_RESET)
2186 | SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE)
2187 | SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD)
2189 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2191 // Disable the notify enable spinup primitives
2192 enable_spinup_value = SCU_SAS_ENSPINUP_READ(this_phy);
2193 enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
2194 SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup_value);
2198 * This method will start the OOB/SN state machine for this SCIC_SDS_PHY
2201 * @param[in] this_phy This is the SCIC_SDS_PHY object on which to start the
2202 * OOB/SN state machine.
2205 void scu_link_layer_start_oob(
2206 SCIC_SDS_PHY_T *this_phy
2209 U32 scu_sas_pcfg_value;
2211 /* Reset OOB sequence - start */
2212 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2213 scu_sas_pcfg_value &=
2214 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) | SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
2215 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2216 SCU_SAS_PCFG_READ(this_phy);
2217 /* Reset OOB sequence - end */
2219 /* Start OOB sequence - start */
2220 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2221 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2222 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2223 SCU_SAS_PCFG_READ(this_phy);
2224 /* Start OOB sequence - end */
2228 * This method will transmit a hard reset request on the specified phy. The
2229 * SCU hardware requires that we reset the OOB state machine and set the hard
2230 * reset bit in the phy configuration register.
2231 * We then must start OOB over with the hard reset bit set.
2233 * @param[in] this_phy
2236 void scu_link_layer_tx_hard_reset(
2237 SCIC_SDS_PHY_T *this_phy
2240 U32 phy_configuration_value;
2242 // SAS Phys must wait for the HARD_RESET_TX event notification to transition
2243 // to the starting state.
2244 phy_configuration_value = SCU_SAS_PCFG_READ(this_phy);
2245 phy_configuration_value |=
2246 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) | SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
2247 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value);
2249 // Now take the OOB state machine out of reset
2250 phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2251 phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
2252 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value);
2255 //****************************************************************************
2256 //* PHY BASE STATE METHODS
2257 //****************************************************************************
2260 * This method will perform the actions required by the SCIC_SDS_PHY on
2261 * entering the SCI_BASE_PHY_STATE_INITIAL.
2262 * - This function sets the state handlers for the phy object base state
2263 * machine initial state.
2265 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
2266 * SCIC_SDS_PHY object.
2271 void scic_sds_phy_initial_state_enter(
2272 SCI_BASE_OBJECT_T *object
2275 SCIC_SDS_PHY_T *this_phy;
2276 this_phy = (SCIC_SDS_PHY_T *)object;
2278 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_INITIAL);
2282 * This method will perform the actions required by the SCIC_SDS_PHY on
2283 * entering the SCI_BASE_PHY_STATE_INITIAL.
2284 * - This function sets the state handlers for the phy object base state
2285 * machine initial state.
2286 * - The SCU hardware is requested to stop the protocol engine.
2288 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
2289 * SCIC_SDS_PHY object.
2294 void scic_sds_phy_stopped_state_enter(
2295 SCI_BASE_OBJECT_T *object
2298 SCIC_SDS_PHY_T *this_phy;
2299 this_phy = (SCIC_SDS_PHY_T *)object;
2301 /// @todo We need to get to the controller to place this PE in a reset state
2302 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STOPPED);
2304 if (this_phy->sata_timeout_timer != NULL)
2306 scic_cb_timer_destroy(
2307 scic_sds_phy_get_controller(this_phy),
2308 this_phy->sata_timeout_timer
2311 this_phy->sata_timeout_timer = NULL;
2314 scu_link_layer_stop_protocol_engine(this_phy);
2318 * This method will perform the actions required by the SCIC_SDS_PHY on
2319 * entering the SCI_BASE_PHY_STATE_STARTING.
2320 * - This function sets the state handlers for the phy object base state
2321 * machine starting state.
2322 * - The SCU hardware is requested to start OOB/SN on this protocol engine.
2323 * - The phy starting substate machine is started.
2324 * - If the previous state was the ready state then the
2325 * SCIC_SDS_CONTROLLER is informed that the phy has gone link down.
2327 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
2328 * SCIC_SDS_PHY object.
2333 void scic_sds_phy_starting_state_enter(
2334 SCI_BASE_OBJECT_T *object
2337 SCIC_SDS_PHY_T *this_phy;
2338 this_phy = (SCIC_SDS_PHY_T *)object;
2340 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STARTING);
2342 scu_link_layer_stop_protocol_engine(this_phy);
2343 scu_link_layer_start_oob(this_phy);
2345 // We don't know what kind of phy we are going to be just yet
2346 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
2347 this_phy->bcn_received_while_port_unassigned = FALSE;
2349 // Change over to the starting substate machine to continue
2350 sci_base_state_machine_start(&this_phy->starting_substate_machine);
2352 if (this_phy->parent.state_machine.previous_state_id
2353 == SCI_BASE_PHY_STATE_READY)
2355 scic_sds_controller_link_down(
2356 scic_sds_phy_get_controller(this_phy),
2357 scic_sds_phy_get_port(this_phy),
2364 * This method will perform the actions required by the SCIC_SDS_PHY on
2365 * entering the SCI_BASE_PHY_STATE_READY.
2366 * - This function sets the state handlers for the phy object base state
2367 * machine ready state.
2368 * - The SCU hardware protocol engine is resumed.
2369 * - The SCIC_SDS_CONTROLLER is informed that the phy object has gone link
2372 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
2373 * SCIC_SDS_PHY object.
2378 void scic_sds_phy_ready_state_enter(
2379 SCI_BASE_OBJECT_T *object
2382 SCIC_SDS_PHY_T *this_phy;
2383 this_phy = (SCIC_SDS_PHY_T *)object;
2385 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_READY);
2387 scic_sds_controller_link_up(
2388 scic_sds_phy_get_controller(this_phy),
2389 scic_sds_phy_get_port(this_phy),
2395 * This method will perform the actions required by the SCIC_SDS_PHY on
2396 * exiting the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU
2397 * hardware protocol engine represented by this SCIC_SDS_PHY object.
2399 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
2400 * SCIC_SDS_PHY object.
2405 void scic_sds_phy_ready_state_exit(
2406 SCI_BASE_OBJECT_T *object
2409 SCIC_SDS_PHY_T *this_phy;
2410 this_phy = (SCIC_SDS_PHY_T *)object;
2412 scic_sds_phy_suspend(this_phy);
2416 * This method will perform the actions required by the SCIC_SDS_PHY on
2417 * entering the SCI_BASE_PHY_STATE_RESETTING.
2418 * - This function sets the state handlers for the phy object base state
2419 * machine resetting state.
2421 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
2422 * SCIC_SDS_PHY object.
2427 void scic_sds_phy_resetting_state_enter(
2428 SCI_BASE_OBJECT_T *object
2431 SCIC_SDS_PHY_T * this_phy;
2432 this_phy = (SCIC_SDS_PHY_T *)object;
2434 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_RESETTING);
2436 // The phy is being reset, therefore deactivate it from the port.
2437 // In the resetting state we don't notify the user regarding
2438 // link up and link down notifications.
2439 scic_sds_port_deactivate_phy(this_phy->owning_port, this_phy, FALSE);
2441 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS)
2443 scu_link_layer_tx_hard_reset(this_phy);
2447 // The SCU does not need to have a descrete reset state so just go back to
2448 // the starting state.
2449 sci_base_state_machine_change_state(
2450 &this_phy->parent.state_machine,
2451 SCI_BASE_PHY_STATE_STARTING
2457 * This method will perform the actions required by the SCIC_SDS_PHY on
2458 * entering the SCI_BASE_PHY_STATE_FINAL.
2459 * - This function sets the state handlers for the phy object base state
2460 * machine final state.
2462 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
2463 * SCIC_SDS_PHY object.
2468 void scic_sds_phy_final_state_enter(
2469 SCI_BASE_OBJECT_T *object
2472 SCIC_SDS_PHY_T *this_phy;
2473 this_phy = (SCIC_SDS_PHY_T *)object;
2475 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_FINAL);
2477 // Nothing to do here
2480 // ---------------------------------------------------------------------------
2482 SCI_BASE_STATE_T scic_sds_phy_state_table[SCI_BASE_PHY_MAX_STATES] =
2485 SCI_BASE_PHY_STATE_INITIAL,
2486 scic_sds_phy_initial_state_enter,
2490 SCI_BASE_PHY_STATE_STOPPED,
2491 scic_sds_phy_stopped_state_enter,
2495 SCI_BASE_PHY_STATE_STARTING,
2496 scic_sds_phy_starting_state_enter,
2500 SCI_BASE_PHY_STATE_READY,
2501 scic_sds_phy_ready_state_enter,
2502 scic_sds_phy_ready_state_exit,
2505 SCI_BASE_PHY_STATE_RESETTING,
2506 scic_sds_phy_resetting_state_enter,
2510 SCI_BASE_PHY_STATE_FINAL,
2511 scic_sds_phy_final_state_enter,
2516 //******************************************************************************
2517 //* PHY STARTING SUB-STATE MACHINE
2518 //******************************************************************************
2520 //*****************************************************************************
2521 //* SCIC SDS PHY HELPER FUNCTIONS
2522 //*****************************************************************************
2526 * This method continues the link training for the phy as if it were a SAS PHY
2527 * instead of a SATA PHY. This is done because the completion queue had a SAS
2528 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
2530 * @param[in] this_phy The phy object that received SAS PHY DETECTED.
2535 void scic_sds_phy_start_sas_link_training(
2536 SCIC_SDS_PHY_T * this_phy
2541 phy_control = SCU_SAS_PCFG_READ(this_phy);
2542 phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
2543 SCU_SAS_PCFG_WRITE(this_phy, phy_control);
2545 sci_base_state_machine_change_state(
2546 &this_phy->starting_substate_machine,
2547 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
2550 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
2554 * This method continues the link training for the phy as if it were a SATA
2555 * PHY instead of a SAS PHY. This is done because the completion queue had a
2556 * SATA SPINUP HOLD event when the state machine was expecting a SAS PHY
2559 * @param[in] this_phy The phy object that received a SATA SPINUP HOLD event
2564 void scic_sds_phy_start_sata_link_training(
2565 SCIC_SDS_PHY_T * this_phy
2568 sci_base_state_machine_change_state(
2569 &this_phy->starting_substate_machine,
2570 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
2573 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
2577 * @brief This method performs processing common to all protocols upon
2578 * completion of link training.
2580 * @param[in,out] this_phy This parameter specifies the phy object for which
2581 * link training has completed.
2582 * @param[in] max_link_rate This parameter specifies the maximum link
2583 * rate to be associated with this phy.
2584 * @param[in] next_state This parameter specifies the next state for the
2585 * phy's starting sub-state machine.
2590 void scic_sds_phy_complete_link_training(
2591 SCIC_SDS_PHY_T * this_phy,
2592 SCI_SAS_LINK_RATE max_link_rate,
2596 this_phy->max_negotiated_speed = max_link_rate;
2598 sci_base_state_machine_change_state(
2599 scic_sds_phy_get_starting_substate_machine(this_phy), next_state
2604 * This method restarts the SCIC_SDS_PHY objects base state machine in the
2605 * starting state from any starting substate.
2607 * @param[in] this_phy The SCIC_SDS_PHY object to restart.
2611 void scic_sds_phy_restart_starting_state(
2612 SCIC_SDS_PHY_T *this_phy
2615 // Stop the current substate machine
2616 sci_base_state_machine_stop(
2617 scic_sds_phy_get_starting_substate_machine(this_phy)
2620 // Re-enter the base state machine starting state
2621 sci_base_state_machine_change_state(
2622 scic_sds_phy_get_base_state_machine(this_phy),
2623 SCI_BASE_PHY_STATE_STARTING
2628 //*****************************************************************************
2629 //* SCIC SDS PHY general handlers
2630 //*****************************************************************************
2633 SCI_STATUS scic_sds_phy_starting_substate_general_stop_handler(
2637 SCIC_SDS_PHY_T *this_phy;
2638 this_phy = (SCIC_SDS_PHY_T *)phy;
2640 sci_base_state_machine_stop(
2641 &this_phy->starting_substate_machine
2644 sci_base_state_machine_change_state(
2645 &phy->state_machine,
2646 SCI_BASE_PHY_STATE_STOPPED
2652 //*****************************************************************************
2653 //* SCIC SDS PHY EVENT_HANDLERS
2654 //*****************************************************************************
2657 * This method is called when an event notification is received for the phy
2658 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN.
2659 * - decode the event
2660 * - sas phy detected causes a state transition to the wait for speed
2661 * event notification.
2662 * - any other events log a warning message and set a failure status
2664 * @param[in] phy This SCIC_SDS_PHY object which has received an event.
2665 * @param[in] event_code This is the event code which the phy object is to
2668 * @return SCI_STATUS
2669 * @retval SCI_SUCCESS on any valid event notification
2670 * @retval SCI_FAILURE on any unexpected event notifation
2673 SCI_STATUS scic_sds_phy_starting_substate_await_ossp_event_handler(
2674 SCIC_SDS_PHY_T *this_phy,
2678 U32 result = SCI_SUCCESS;
2680 switch (scu_get_event_code(event_code))
2682 case SCU_EVENT_SAS_PHY_DETECTED:
2683 scic_sds_phy_start_sas_link_training(this_phy);
2684 this_phy->is_in_link_training = TRUE;
2687 case SCU_EVENT_SATA_SPINUP_HOLD:
2688 scic_sds_phy_start_sata_link_training(this_phy);
2689 this_phy->is_in_link_training = TRUE;
2694 sci_base_object_get_logger(this_phy),
2695 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
2696 "PHY starting substate machine received unexpected event_code %x\n",
2700 result = SCI_FAILURE;
2708 * This method is called when an event notification is received for the phy
2709 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN.
2710 * - decode the event
2711 * - sas phy detected returns us back to this state.
2712 * - speed event detected causes a state transition to the wait for iaf.
2713 * - identify timeout is an un-expected event and the state machine is
2715 * - link failure events restart the starting state machine
2716 * - any other events log a warning message and set a failure status
2718 * @param[in] phy This SCIC_SDS_PHY object which has received an event.
2719 * @param[in] event_code This is the event code which the phy object is to
2722 * @return SCI_STATUS
2723 * @retval SCI_SUCCESS on any valid event notification
2724 * @retval SCI_FAILURE on any unexpected event notifation
2727 SCI_STATUS scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler(
2728 SCIC_SDS_PHY_T *this_phy,
2732 U32 result = SCI_SUCCESS;
2734 switch (scu_get_event_code(event_code))
2736 case SCU_EVENT_SAS_PHY_DETECTED:
2737 // Why is this being reported again by the controller?
2738 // We would re-enter this state so just stay here
2741 case SCU_EVENT_SAS_15:
2742 case SCU_EVENT_SAS_15_SSC:
2743 scic_sds_phy_complete_link_training(
2744 this_phy, SCI_SAS_150_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
2748 case SCU_EVENT_SAS_30:
2749 case SCU_EVENT_SAS_30_SSC:
2750 scic_sds_phy_complete_link_training(
2751 this_phy, SCI_SAS_300_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
2755 case SCU_EVENT_SAS_60:
2756 case SCU_EVENT_SAS_60_SSC:
2757 scic_sds_phy_complete_link_training(
2758 this_phy, SCI_SAS_600_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
2762 case SCU_EVENT_SATA_SPINUP_HOLD:
2763 // We were doing SAS PHY link training and received a SATA PHY event
2764 // continue OOB/SN as if this were a SATA PHY
2765 scic_sds_phy_start_sata_link_training(this_phy);
2768 case SCU_EVENT_LINK_FAILURE:
2769 // Link failure change state back to the starting state
2770 scic_sds_phy_restart_starting_state(this_phy);
2775 sci_base_object_get_logger(this_phy),
2776 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
2777 "PHY starting substate machine received unexpected event_code %x\n",
2781 result = SCI_FAILURE;
2789 * This method is called when an event notification is received for the phy
2790 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF.
2791 * - decode the event
2792 * - sas phy detected event backs up the state machine to the await
2793 * speed notification.
2794 * - identify timeout is an un-expected event and the state machine is
2796 * - link failure events restart the starting state machine
2797 * - any other events log a warning message and set a failure status
2799 * @param[in] phy This SCIC_SDS_PHY object which has received an event.
2800 * @param[in] event_code This is the event code which the phy object is to
2803 * @return SCI_STATUS
2804 * @retval SCI_SUCCESS on any valid event notification
2805 * @retval SCI_FAILURE on any unexpected event notifation
2808 SCI_STATUS scic_sds_phy_starting_substate_await_iaf_uf_event_handler(
2809 SCIC_SDS_PHY_T *this_phy,
2813 U32 result = SCI_SUCCESS;
2815 switch (scu_get_event_code(event_code))
2817 case SCU_EVENT_SAS_PHY_DETECTED:
2818 // Backup the state machine
2819 scic_sds_phy_start_sas_link_training(this_phy);
2822 case SCU_EVENT_SATA_SPINUP_HOLD:
2823 // We were doing SAS PHY link training and received a SATA PHY event
2824 // continue OOB/SN as if this were a SATA PHY
2825 scic_sds_phy_start_sata_link_training(this_phy);
2828 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
2829 case SCU_EVENT_LINK_FAILURE:
2830 case SCU_EVENT_HARD_RESET_RECEIVED:
2831 // Start the oob/sn state machine over again
2832 scic_sds_phy_restart_starting_state(this_phy);
2837 sci_base_object_get_logger(this_phy),
2838 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
2839 "PHY starting substate machine received unexpected event_code %x\n",
2843 result = SCI_FAILURE;
2851 * This method is called when an event notification is received for the phy
2852 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER.
2853 * - decode the event
2854 * - link failure events restart the starting state machine
2855 * - any other events log a warning message and set a failure status
2857 * @param[in] phy This SCIC_SDS_PHY object which has received an event.
2858 * @param[in] event_code This is the event code which the phy object is to
2861 * @return SCI_STATUS
2862 * @retval SCI_SUCCESS on a link failure event
2863 * @retval SCI_FAILURE on any unexpected event notifation
2866 SCI_STATUS scic_sds_phy_starting_substate_await_sas_power_event_handler(
2867 SCIC_SDS_PHY_T *this_phy,
2871 U32 result = SCI_SUCCESS;
2873 switch (scu_get_event_code(event_code))
2875 case SCU_EVENT_LINK_FAILURE:
2876 // Link failure change state back to the starting state
2877 scic_sds_phy_restart_starting_state(this_phy);
2882 sci_base_object_get_logger(this_phy),
2883 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
2884 "PHY starting substate machine received unexpected event_code %x\n",
2888 result = SCI_FAILURE;
2896 * This method is called when an event notification is received for the phy
2897 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER.
2898 * - decode the event
2899 * - link failure events restart the starting state machine
2900 * - sata spinup hold events are ignored since they are expected
2901 * - any other events log a warning message and set a failure status
2903 * @param[in] phy This SCIC_SDS_PHY object which has received an event.
2904 * @param[in] event_code This is the event code which the phy object is to
2907 * @return SCI_STATUS
2908 * @retval SCI_SUCCESS on a link failure event
2909 * @retval SCI_FAILURE on any unexpected event notifation
2912 SCI_STATUS scic_sds_phy_starting_substate_await_sata_power_event_handler(
2913 SCIC_SDS_PHY_T *this_phy,
2917 U32 result = SCI_SUCCESS;
2919 switch (scu_get_event_code(event_code))
2921 case SCU_EVENT_LINK_FAILURE:
2922 // Link failure change state back to the starting state
2923 scic_sds_phy_restart_starting_state(this_phy);
2926 case SCU_EVENT_SATA_SPINUP_HOLD:
2927 // These events are received every 10ms and are expected while in this state
2930 case SCU_EVENT_SAS_PHY_DETECTED:
2931 // There has been a change in the phy type before OOB/SN for the
2932 // SATA finished start down the SAS link traning path.
2933 scic_sds_phy_start_sas_link_training(this_phy);
2938 sci_base_object_get_logger(this_phy),
2939 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
2940 "PHY starting substate machine received unexpected event_code %x\n",
2944 result = SCI_FAILURE;
2952 * This method is called when an event notification is received for the phy
2953 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN.
2954 * - decode the event
2955 * - link failure events restart the starting state machine
2956 * - sata spinup hold events are ignored since they are expected
2957 * - sata phy detected event change to the wait speed event
2958 * - any other events log a warning message and set a failure status
2960 * @param[in] phy This SCIC_SDS_PHY object which has received an event.
2961 * @param[in] event_code This is the event code which the phy object is to
2964 * @return SCI_STATUS
2965 * @retval SCI_SUCCESS on a link failure event
2966 * @retval SCI_FAILURE on any unexpected event notifation
2969 SCI_STATUS scic_sds_phy_starting_substate_await_sata_phy_event_handler(
2970 SCIC_SDS_PHY_T *this_phy,
2974 U32 result = SCI_SUCCESS;
2976 switch (scu_get_event_code(event_code))
2978 case SCU_EVENT_LINK_FAILURE:
2979 // Link failure change state back to the starting state
2980 scic_sds_phy_restart_starting_state(this_phy);
2983 case SCU_EVENT_SATA_SPINUP_HOLD:
2984 // These events might be received since we dont know how many may be in
2985 // the completion queue while waiting for power
2988 case SCU_EVENT_SATA_PHY_DETECTED:
2989 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
2991 // We have received the SATA PHY notification change state
2992 sci_base_state_machine_change_state(
2993 scic_sds_phy_get_starting_substate_machine(this_phy),
2994 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
2998 case SCU_EVENT_SAS_PHY_DETECTED:
2999 // There has been a change in the phy type before OOB/SN for the
3000 // SATA finished start down the SAS link traning path.
3001 scic_sds_phy_start_sas_link_training(this_phy);
3006 sci_base_object_get_logger(this_phy),
3007 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
3008 "PHY starting substate machine received unexpected event_code %x\n",
3012 result = SCI_FAILURE;
3020 * This method is called when an event notification is received for the phy
3021 * object when in the state
3022 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
3023 * - decode the event
3024 * - sata phy detected returns us back to this state.
3025 * - speed event detected causes a state transition to the wait for
3027 * - link failure events restart the starting state machine
3028 * - any other events log a warning message and set a failure status
3030 * @param[in] phy This SCIC_SDS_PHY object which has received an event.
3031 * @param[in] event_code This is the event code which the phy object is to
3034 * @return SCI_STATUS
3035 * @retval SCI_SUCCESS on any valid event notification
3036 * @retval SCI_FAILURE on any unexpected event notifation
3039 SCI_STATUS scic_sds_phy_starting_substate_await_sata_speed_event_handler(
3040 SCIC_SDS_PHY_T *this_phy,
3044 U32 result = SCI_SUCCESS;
3046 switch (scu_get_event_code(event_code))
3048 case SCU_EVENT_SATA_PHY_DETECTED:
3049 // The hardware reports multiple SATA PHY detected events
3050 // ignore the extras
3053 case SCU_EVENT_SATA_15:
3054 case SCU_EVENT_SATA_15_SSC:
3055 scic_sds_phy_complete_link_training(
3058 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
3062 case SCU_EVENT_SATA_30:
3063 case SCU_EVENT_SATA_30_SSC:
3064 scic_sds_phy_complete_link_training(
3067 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
3071 case SCU_EVENT_SATA_60:
3072 case SCU_EVENT_SATA_60_SSC:
3073 scic_sds_phy_complete_link_training(
3076 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
3080 case SCU_EVENT_LINK_FAILURE:
3081 // Link failure change state back to the starting state
3082 scic_sds_phy_restart_starting_state(this_phy);
3085 case SCU_EVENT_SAS_PHY_DETECTED:
3086 // There has been a change in the phy type before OOB/SN for the
3087 // SATA finished start down the SAS link traning path.
3088 scic_sds_phy_start_sas_link_training(this_phy);
3093 sci_base_object_get_logger(this_phy),
3094 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
3095 "PHY starting substate machine received unexpected event_code %x\n",
3099 result = SCI_FAILURE;
3107 * This method is called when an event notification is received for the phy
3108 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF.
3109 * - decode the event
3110 * - sas phy detected event backs up the state machine to the await
3111 * speed notification.
3112 * - identify timeout is an un-expected event and the state machine is
3114 * - link failure events restart the starting state machine
3115 * - any other events log a warning message and set a failure status
3117 * @param[in] phy This SCIC_SDS_PHY object which has received an event.
3118 * @param[in] event_code This is the event code which the phy object is to
3121 * @return SCI_STATUS
3122 * @retval SCI_SUCCESS on any valid event notification
3123 * @retval SCI_FAILURE on any unexpected event notifation
3126 SCI_STATUS scic_sds_phy_starting_substate_await_sig_fis_event_handler(
3127 SCIC_SDS_PHY_T *this_phy,
3131 U32 result = SCI_SUCCESS;
3133 switch (scu_get_event_code(event_code))
3135 case SCU_EVENT_SATA_PHY_DETECTED:
3136 // Backup the state machine
3137 sci_base_state_machine_change_state(
3138 scic_sds_phy_get_starting_substate_machine(this_phy),
3139 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
3143 case SCU_EVENT_LINK_FAILURE:
3144 // Link failure change state back to the starting state
3145 scic_sds_phy_restart_starting_state(this_phy);
3150 sci_base_object_get_logger(this_phy),
3151 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_RECEIVED_EVENTS,
3152 "PHY starting substate machine received unexpected event_code %x\n",
3156 result = SCI_FAILURE;
3164 //*****************************************************************************
3165 //* SCIC SDS PHY FRAME_HANDLERS
3166 //*****************************************************************************
3169 * This method decodes the unsolicited frame when the SCIC_SDS_PHY is in the
3170 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF.
3171 * - Get the UF Header
3172 * - If the UF is an IAF
3173 * - Copy IAF data to local phy object IAF data buffer.
3174 * - Change starting substate to wait power.
3176 * - log warning message of unexpected unsolicted frame
3177 * - release frame buffer
3179 * @param[in] phy This is SCIC_SDS_PHY object which is being requested to
3180 * decode the frame data.
3181 * @param[in] frame_index This is the index of the unsolicited frame which was
3182 * received for this phy.
3184 * @return SCI_STATUS
3185 * @retval SCI_SUCCESS
3188 SCI_STATUS scic_sds_phy_starting_substate_await_iaf_uf_frame_handler(
3189 SCIC_SDS_PHY_T *this_phy,
3195 SCI_SAS_IDENTIFY_ADDRESS_FRAME_T *identify_frame;
3197 result = scic_sds_unsolicited_frame_control_get_header(
3198 &(scic_sds_phy_get_controller(this_phy)->uf_control),
3200 (void **)&frame_words);
3202 if (result != SCI_SUCCESS)
3207 frame_words[0] = SCIC_SWAP_DWORD(frame_words[0]);
3208 identify_frame = (SCI_SAS_IDENTIFY_ADDRESS_FRAME_T *)frame_words;
3210 if (identify_frame->address_frame_type == 0)
3212 // Byte swap the rest of the frame so we can make
3213 // a copy of the buffer
3214 frame_words[1] = SCIC_SWAP_DWORD(frame_words[1]);
3215 frame_words[2] = SCIC_SWAP_DWORD(frame_words[2]);
3216 frame_words[3] = SCIC_SWAP_DWORD(frame_words[3]);
3217 frame_words[4] = SCIC_SWAP_DWORD(frame_words[4]);
3218 frame_words[5] = SCIC_SWAP_DWORD(frame_words[5]);
3221 &this_phy->phy_type.sas.identify_address_frame_buffer,
3223 sizeof(SCI_SAS_IDENTIFY_ADDRESS_FRAME_T)
3226 if (identify_frame->protocols.u.bits.smp_target)
3228 // We got the IAF for an expander PHY go to the final state since
3229 // there are no power requirements for expander phys.
3230 sci_base_state_machine_change_state(
3231 scic_sds_phy_get_starting_substate_machine(this_phy),
3232 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
3237 // We got the IAF we can now go to the await spinup semaphore state
3238 sci_base_state_machine_change_state(
3239 scic_sds_phy_get_starting_substate_machine(this_phy),
3240 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
3244 result = SCI_SUCCESS;
3249 sci_base_object_get_logger(this_phy),
3250 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_UNSOLICITED_FRAMES,
3251 "PHY starting substate machine received unexpected frame id %x\n",
3256 // Regardless of the result release this frame since we are done with it
3257 scic_sds_controller_release_frame(
3258 scic_sds_phy_get_controller(this_phy), frame_index
3265 * This method decodes the unsolicited frame when the SCIC_SDS_PHY is in the
3266 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF.
3267 * - Get the UF Header
3268 * - If the UF is an SIGNATURE FIS
3269 * - Copy IAF data to local phy object SIGNATURE FIS data buffer.
3271 * - log warning message of unexpected unsolicted frame
3272 * - release frame buffer
3274 * @param[in] phy This is SCIC_SDS_PHY object which is being requested to
3275 * decode the frame data.
3276 * @param[in] frame_index This is the index of the unsolicited frame which was
3277 * received for this phy.
3279 * @return SCI_STATUS
3280 * @retval SCI_SUCCESS
3282 * @todo Must decode the SIGNATURE FIS data
3285 SCI_STATUS scic_sds_phy_starting_substate_await_sig_fis_frame_handler(
3286 SCIC_SDS_PHY_T *this_phy,
3292 SATA_FIS_HEADER_T * fis_frame_header;
3293 U32 * fis_frame_data;
3295 result = scic_sds_unsolicited_frame_control_get_header(
3296 &(scic_sds_phy_get_controller(this_phy)->uf_control),
3298 (void **)&frame_words);
3300 if (result != SCI_SUCCESS)
3305 fis_frame_header = (SATA_FIS_HEADER_T *)frame_words;
3308 (fis_frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
3309 && !(fis_frame_header->status & ATA_STATUS_REG_BSY_BIT)
3312 scic_sds_unsolicited_frame_control_get_buffer(
3313 &(scic_sds_phy_get_controller(this_phy)->uf_control),
3315 (void **)&fis_frame_data
3318 scic_sds_controller_copy_sata_response(
3319 &this_phy->phy_type.sata.signature_fis_buffer,
3324 // We got the IAF we can now go to the await spinup semaphore state
3325 sci_base_state_machine_change_state(
3326 scic_sds_phy_get_starting_substate_machine(this_phy),
3327 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
3330 result = SCI_SUCCESS;
3335 sci_base_object_get_logger(this_phy),
3336 SCIC_LOG_OBJECT_PHY | SCIC_LOG_OBJECT_UNSOLICITED_FRAMES,
3337 "PHY starting substate machine received unexpected frame id %x\n",
3342 // Regardless of the result release this frame since we are done with it
3343 scic_sds_controller_release_frame(
3344 scic_sds_phy_get_controller(this_phy), frame_index
3350 //*****************************************************************************
3351 //* SCIC SDS PHY POWER_HANDLERS
3352 //*****************************************************************************
3355 * This method is called by the SCIC_SDS_CONTROLLER when the phy object is
3357 * - The notify enable spinups are turned on for this phy object
3358 * - The phy state machine is transitioned to the
3359 * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL.
3361 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
3362 * SCIC_SDS_PHY object.
3364 * @return SCI_STATUS
3365 * @retval SCI_SUCCESS
3368 SCI_STATUS scic_sds_phy_starting_substate_await_sas_power_consume_power_handler(
3369 SCIC_SDS_PHY_T *this_phy
3374 enable_spinup = SCU_SAS_ENSPINUP_READ(this_phy);
3375 enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
3376 SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup);
3378 // Change state to the final state this substate machine has run to completion
3379 sci_base_state_machine_change_state(
3380 scic_sds_phy_get_starting_substate_machine(this_phy),
3381 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
3388 * This method is called by the SCIC_SDS_CONTROLLER when the phy object is
3390 * - The phy state machine is transitioned to the
3391 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN.
3393 * @param[in] phy This is the SCI_BASE_PHY object which is cast into a
3394 * SCIC_SDS_PHY object.
3396 * @return SCI_STATUS
3397 * @retval SCI_SUCCESS
3400 SCI_STATUS scic_sds_phy_starting_substate_await_sata_power_consume_power_handler(
3401 SCIC_SDS_PHY_T *this_phy
3404 U32 scu_sas_pcfg_value;
3406 // Release the spinup hold state and reset the OOB state machine
3407 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
3408 scu_sas_pcfg_value &=
3409 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
3410 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
3411 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
3413 // Now restart the OOB operation
3414 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
3415 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
3416 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
3418 // Change state to the final state this substate machine has run to completion
3419 sci_base_state_machine_change_state(
3420 scic_sds_phy_get_starting_substate_machine(this_phy),
3421 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
3427 // ---------------------------------------------------------------------------
3429 SCIC_SDS_PHY_STATE_HANDLER_T
3430 scic_sds_phy_starting_substate_handler_table[SCIC_SDS_PHY_STARTING_MAX_SUBSTATES] =
3432 // SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
3435 scic_sds_phy_default_start_handler,
3436 scic_sds_phy_starting_substate_general_stop_handler,
3437 scic_sds_phy_default_reset_handler,
3438 scic_sds_phy_default_destroy_handler
3440 scic_sds_phy_default_frame_handler,
3441 scic_sds_phy_default_event_handler,
3442 scic_sds_phy_default_consume_power_handler
3444 // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
3447 scic_sds_phy_default_start_handler,
3448 scic_sds_phy_starting_substate_general_stop_handler,
3449 scic_sds_phy_default_reset_handler,
3450 scic_sds_phy_default_destroy_handler
3452 scic_sds_phy_default_frame_handler,
3453 scic_sds_phy_starting_substate_await_ossp_event_handler,
3454 scic_sds_phy_default_consume_power_handler
3456 // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
3459 scic_sds_phy_default_start_handler,
3460 scic_sds_phy_starting_substate_general_stop_handler,
3461 scic_sds_phy_default_reset_handler,
3462 scic_sds_phy_default_destroy_handler
3464 scic_sds_phy_default_frame_handler,
3465 scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler,
3466 scic_sds_phy_default_consume_power_handler
3468 // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
3471 scic_sds_phy_default_start_handler,
3472 scic_sds_phy_default_stop_handler,
3473 scic_sds_phy_default_reset_handler,
3474 scic_sds_phy_default_destroy_handler
3476 scic_sds_phy_starting_substate_await_iaf_uf_frame_handler,
3477 scic_sds_phy_starting_substate_await_iaf_uf_event_handler,
3478 scic_sds_phy_default_consume_power_handler
3480 // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
3483 scic_sds_phy_default_start_handler,
3484 scic_sds_phy_starting_substate_general_stop_handler,
3485 scic_sds_phy_default_reset_handler,
3486 scic_sds_phy_default_destroy_handler
3488 scic_sds_phy_default_frame_handler,
3489 scic_sds_phy_starting_substate_await_sas_power_event_handler,
3490 scic_sds_phy_starting_substate_await_sas_power_consume_power_handler
3492 // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER,
3495 scic_sds_phy_default_start_handler,
3496 scic_sds_phy_starting_substate_general_stop_handler,
3497 scic_sds_phy_default_reset_handler,
3498 scic_sds_phy_default_destroy_handler
3500 scic_sds_phy_default_frame_handler,
3501 scic_sds_phy_starting_substate_await_sata_power_event_handler,
3502 scic_sds_phy_starting_substate_await_sata_power_consume_power_handler
3504 // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN,
3507 scic_sds_phy_default_start_handler,
3508 scic_sds_phy_starting_substate_general_stop_handler,
3509 scic_sds_phy_default_reset_handler,
3510 scic_sds_phy_default_destroy_handler
3512 scic_sds_phy_default_frame_handler,
3513 scic_sds_phy_starting_substate_await_sata_phy_event_handler,
3514 scic_sds_phy_default_consume_power_handler
3516 // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN,
3519 scic_sds_phy_default_start_handler,
3520 scic_sds_phy_starting_substate_general_stop_handler,
3521 scic_sds_phy_default_reset_handler,
3522 scic_sds_phy_default_destroy_handler
3524 scic_sds_phy_default_frame_handler,
3525 scic_sds_phy_starting_substate_await_sata_speed_event_handler,
3526 scic_sds_phy_default_consume_power_handler
3528 // SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF,
3531 scic_sds_phy_default_start_handler,
3532 scic_sds_phy_starting_substate_general_stop_handler,
3533 scic_sds_phy_default_reset_handler,
3534 scic_sds_phy_default_destroy_handler
3536 scic_sds_phy_starting_substate_await_sig_fis_frame_handler,
3537 scic_sds_phy_starting_substate_await_sig_fis_event_handler,
3538 scic_sds_phy_default_consume_power_handler
3540 // SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
3543 scic_sds_phy_default_start_handler,
3544 scic_sds_phy_starting_substate_general_stop_handler,
3545 scic_sds_phy_default_reset_handler,
3546 scic_sds_phy_default_destroy_handler
3548 scic_sds_phy_default_frame_handler,
3549 scic_sds_phy_default_event_handler,
3550 scic_sds_phy_default_consume_power_handler
3555 * This macro sets the starting substate handlers by state_id
3557 #define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \
3558 scic_sds_phy_set_state_handlers( \
3560 &scic_sds_phy_starting_substate_handler_table[(state_id)] \
3563 //****************************************************************************
3564 //* PHY STARTING SUBSTATE METHODS
3565 //****************************************************************************
3568 * This method will perform the actions required by the SCIC_SDS_PHY on
3569 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL.
3570 * - The initial state handlers are put in place for the SCIC_SDS_PHY
3572 * - The state is changed to the wait phy type event notification.
3574 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3575 * SCIC_SDS_PHY object.
3580 void scic_sds_phy_starting_initial_substate_enter(
3581 SCI_BASE_OBJECT_T *object
3584 SCIC_SDS_PHY_T *this_phy;
3585 this_phy = (SCIC_SDS_PHY_T *)object;
3587 scic_sds_phy_set_starting_substate_handlers(
3588 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
3590 // This is just an temporary state go off to the starting state
3591 sci_base_state_machine_change_state(
3592 scic_sds_phy_get_starting_substate_machine(this_phy),
3593 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
3598 * This method will perform the actions required by the SCIC_SDS_PHY on
3599 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_PHY_TYPE_EN.
3600 * - Set the SCIC_SDS_PHY object state handlers for this state.
3602 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3603 * SCIC_SDS_PHY object.
3608 void scic_sds_phy_starting_await_ossp_en_substate_enter(
3609 SCI_BASE_OBJECT_T *object
3612 SCIC_SDS_PHY_T *this_phy;
3613 this_phy = (SCIC_SDS_PHY_T *)object;
3615 scic_sds_phy_set_starting_substate_handlers(
3616 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
3621 * This method will perform the actions required by the SCIC_SDS_PHY on
3622 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN.
3623 * - Set the SCIC_SDS_PHY object state handlers for this state.
3625 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3626 * SCIC_SDS_PHY object.
3631 void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
3632 SCI_BASE_OBJECT_T *object
3635 SCIC_SDS_PHY_T *this_phy;
3636 this_phy = (SCIC_SDS_PHY_T *)object;
3638 scic_sds_phy_set_starting_substate_handlers(
3639 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
3644 * This method will perform the actions required by the SCIC_SDS_PHY on
3645 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF.
3646 * - Set the SCIC_SDS_PHY object state handlers for this state.
3648 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3649 * SCIC_SDS_PHY object.
3654 void scic_sds_phy_starting_await_iaf_uf_substate_enter(
3655 SCI_BASE_OBJECT_T *object
3658 SCIC_SDS_PHY_T *this_phy;
3659 this_phy = (SCIC_SDS_PHY_T *)object;
3661 scic_sds_phy_set_starting_substate_handlers(
3662 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
3667 * This method will perform the actions required by the SCIC_SDS_PHY on
3668 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER.
3669 * - Set the SCIC_SDS_PHY object state handlers for this state.
3670 * - Add this phy object to the power control queue
3672 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3673 * SCIC_SDS_PHY object.
3678 void scic_sds_phy_starting_await_sas_power_substate_enter(
3679 SCI_BASE_OBJECT_T *object
3682 SCIC_SDS_PHY_T *this_phy;
3683 this_phy = (SCIC_SDS_PHY_T *)object;
3685 scic_sds_phy_set_starting_substate_handlers(
3686 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
3689 scic_sds_controller_power_control_queue_insert(
3690 scic_sds_phy_get_controller(this_phy),
3696 * This method will perform the actions required by the SCIC_SDS_PHY on
3697 * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER.
3698 * - Remove the SCIC_SDS_PHY object from the power control queue.
3700 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3701 * SCIC_SDS_PHY object.
3706 void scic_sds_phy_starting_await_sas_power_substate_exit(
3707 SCI_BASE_OBJECT_T *object
3710 SCIC_SDS_PHY_T *this_phy;
3711 this_phy = (SCIC_SDS_PHY_T *)object;
3713 scic_sds_controller_power_control_queue_remove(
3714 scic_sds_phy_get_controller(this_phy), this_phy
3719 * This method will perform the actions required by the SCIC_SDS_PHY on
3720 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER.
3721 * - Set the SCIC_SDS_PHY object state handlers for this state.
3722 * - Add this phy object to the power control queue
3724 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3725 * SCIC_SDS_PHY object.
3730 void scic_sds_phy_starting_await_sata_power_substate_enter(
3731 SCI_BASE_OBJECT_T *object
3734 SCIC_SDS_PHY_T *this_phy;
3735 this_phy = (SCIC_SDS_PHY_T *)object;
3737 scic_sds_phy_set_starting_substate_handlers(
3738 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
3741 scic_sds_controller_power_control_queue_insert(
3742 scic_sds_phy_get_controller(this_phy),
3748 * This method will perform the actions required by the SCIC_SDS_PHY on
3749 * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER.
3750 * - Remove the SCIC_SDS_PHY object from the power control queue.
3752 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3753 * SCIC_SDS_PHY object.
3758 void scic_sds_phy_starting_await_sata_power_substate_exit(
3759 SCI_BASE_OBJECT_T *object
3762 SCIC_SDS_PHY_T *this_phy;
3763 this_phy = (SCIC_SDS_PHY_T *)object;
3765 scic_sds_controller_power_control_queue_remove(
3766 scic_sds_phy_get_controller(this_phy),
3772 * This method will perform the actions required by the SCIC_SDS_PHY on
3773 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN.
3774 * - Set the SCIC_SDS_PHY object state handlers for this state.
3776 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3777 * SCIC_SDS_PHY object.
3782 void scic_sds_phy_starting_await_sata_phy_substate_enter(
3783 SCI_BASE_OBJECT_T *object
3786 SCIC_SDS_PHY_T *this_phy;
3787 this_phy = (SCIC_SDS_PHY_T *)object;
3789 scic_sds_phy_set_starting_substate_handlers(
3790 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
3793 scic_cb_timer_start(
3794 scic_sds_phy_get_controller(this_phy),
3795 this_phy->sata_timeout_timer,
3796 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
3801 * This method will perform the actions required by the SCIC_SDS_PHY on
3802 * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
3803 * - stop the timer that was started on entry to await sata phy
3804 * event notification
3806 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3807 * SCIC_SDS_PHY object.
3812 void scic_sds_phy_starting_await_sata_phy_substate_exit(
3813 SCI_BASE_OBJECT_T *object
3816 SCIC_SDS_PHY_T *this_phy;
3817 this_phy = (SCIC_SDS_PHY_T *)object;
3820 scic_sds_phy_get_controller(this_phy),
3821 this_phy->sata_timeout_timer
3826 * This method will perform the actions required by the SCIC_SDS_PHY on
3827 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
3828 * - Set the SCIC_SDS_PHY object state handlers for this state.
3830 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3831 * SCIC_SDS_PHY object.
3836 void scic_sds_phy_starting_await_sata_speed_substate_enter(
3837 SCI_BASE_OBJECT_T *object
3840 SCIC_SDS_PHY_T *this_phy;
3841 this_phy = (SCIC_SDS_PHY_T *)object;
3843 scic_sds_phy_set_starting_substate_handlers(
3844 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
3847 scic_cb_timer_start(
3848 scic_sds_phy_get_controller(this_phy),
3849 this_phy->sata_timeout_timer,
3850 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
3855 * This method will perform the actions required by the SCIC_SDS_PHY on
3856 * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
3857 * - stop the timer that was started on entry to await sata phy
3858 * event notification
3860 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3861 * SCIC_SDS_PHY object.
3866 void scic_sds_phy_starting_await_sata_speed_substate_exit(
3867 SCI_BASE_OBJECT_T *object
3870 SCIC_SDS_PHY_T *this_phy;
3871 this_phy = (SCIC_SDS_PHY_T *)object;
3874 scic_sds_phy_get_controller(this_phy),
3875 this_phy->sata_timeout_timer
3880 * This method will perform the actions required by the SCIC_SDS_PHY on
3881 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF.
3882 * - Set the SCIC_SDS_PHY object state handlers for this state.
3883 * - Start the SIGNATURE FIS timeout timer
3885 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3886 * SCIC_SDS_PHY object.
3891 void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(
3892 SCI_BASE_OBJECT_T *object
3895 BOOL continue_to_ready_state;
3896 SCIC_SDS_PHY_T * this_phy;
3898 this_phy = (SCIC_SDS_PHY_T *)object;
3900 scic_sds_phy_set_starting_substate_handlers(
3901 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
3904 continue_to_ready_state = scic_sds_port_link_detected(
3905 this_phy->owning_port,
3909 if (continue_to_ready_state)
3911 // Clear the PE suspend condition so we can actually receive SIG FIS
3912 // The hardware will not respond to the XRDY until the PE suspend
3913 // condition is cleared.
3914 scic_sds_phy_resume(this_phy);
3916 scic_cb_timer_start(
3917 scic_sds_phy_get_controller(this_phy),
3918 this_phy->sata_timeout_timer,
3919 SCIC_SDS_SIGNATURE_FIS_TIMEOUT
3924 this_phy->is_in_link_training = FALSE;
3929 * This method will perform the actions required by the SCIC_SDS_PHY on
3930 * exiting the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF.
3931 * - Stop the SIGNATURE FIS timeout timer.
3933 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3934 * SCIC_SDS_PHY object.
3939 void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(
3940 SCI_BASE_OBJECT_T *object
3943 SCIC_SDS_PHY_T *this_phy;
3944 this_phy = (SCIC_SDS_PHY_T *)object;
3947 scic_sds_phy_get_controller(this_phy),
3948 this_phy->sata_timeout_timer
3953 * This method will perform the actions required by the SCIC_SDS_PHY on
3954 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL.
3955 * - Set the SCIC_SDS_PHY object state handlers for this state.
3956 * - Change base state machine to the ready state.
3958 * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
3959 * SCIC_SDS_PHY object.
3964 void scic_sds_phy_starting_final_substate_enter(
3965 SCI_BASE_OBJECT_T *object
3968 SCIC_SDS_PHY_T *this_phy;
3969 this_phy = (SCIC_SDS_PHY_T *)object;
3971 scic_sds_phy_set_starting_substate_handlers(
3972 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
3975 // State machine has run to completion so exit out and change
3976 // the base state machine to the ready state
3977 sci_base_state_machine_change_state(
3978 scic_sds_phy_get_base_state_machine(this_phy),
3979 SCI_BASE_PHY_STATE_READY);
3982 // ---------------------------------------------------------------------------
3985 scic_sds_phy_starting_substates[SCIC_SDS_PHY_STARTING_MAX_SUBSTATES] =
3988 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL,
3989 scic_sds_phy_starting_initial_substate_enter,
3993 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN,
3994 scic_sds_phy_starting_await_ossp_en_substate_enter,
3998 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN,
3999 scic_sds_phy_starting_await_sas_speed_en_substate_enter,
4003 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF,
4004 scic_sds_phy_starting_await_iaf_uf_substate_enter,
4008 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER,
4009 scic_sds_phy_starting_await_sas_power_substate_enter,
4010 scic_sds_phy_starting_await_sas_power_substate_exit,
4013 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER,
4014 scic_sds_phy_starting_await_sata_power_substate_enter,
4015 scic_sds_phy_starting_await_sata_power_substate_exit
4018 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN,
4019 scic_sds_phy_starting_await_sata_phy_substate_enter,
4020 scic_sds_phy_starting_await_sata_phy_substate_exit
4023 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN,
4024 scic_sds_phy_starting_await_sata_speed_substate_enter,
4025 scic_sds_phy_starting_await_sata_speed_substate_exit
4028 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF,
4029 scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
4030 scic_sds_phy_starting_await_sig_fis_uf_substate_exit
4033 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL,
4034 scic_sds_phy_starting_final_substate_enter,