2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 #include "sci_base_state.h"
59 #include "sci_base_state_machine.h"
61 #include "scic_sds_controller.h"
62 #include "scic_sds_phy.h"
63 #include "scic_sds_port.h"
64 #include "remote_node_context.h"
65 #include "sci_environment.h"
67 #include "scu_event_codes.h"
69 #define SCIC_SDS_PHY_MIN_TIMER_COUNT (SCI_MAX_PHYS)
70 #define SCIC_SDS_PHY_MAX_TIMER_COUNT (SCI_MAX_PHYS)
72 /* Maximum arbitration wait time in micro-seconds */
73 #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
75 enum sas_linkrate sci_phy_linkrate(struct scic_sds_phy *sci_phy)
77 return sci_phy->max_negotiated_speed;
81 * *****************************************************************************
82 * * SCIC SDS PHY Internal Methods
83 * ***************************************************************************** */
86 * This method will initialize the phy transport layer registers
88 * @transport_layer_registers
92 static enum sci_status scic_sds_phy_transport_layer_initialization(
93 struct scic_sds_phy *sci_phy,
94 struct scu_transport_layer_registers __iomem *transport_layer_registers)
98 sci_phy->transport_layer_registers = transport_layer_registers;
100 writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX,
101 &sci_phy->transport_layer_registers->stp_rni);
104 * Hardware team recommends that we enable the STP prefetch for all
107 tl_control = readl(&sci_phy->transport_layer_registers->control);
108 tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
109 writel(tl_control, &sci_phy->transport_layer_registers->control);
115 * This method will initialize the phy link layer registers
117 * @link_layer_registers:
121 static enum sci_status
122 scic_sds_phy_link_layer_initialization(struct scic_sds_phy *sci_phy,
123 struct scu_link_layer_registers __iomem *link_layer_registers)
125 struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
126 int phy_idx = sci_phy->phy_index;
127 struct sci_phy_user_params *phy_user = &scic->user_parameters.sds1.phys[phy_idx];
128 struct sci_phy_oem_params *phy_oem = &scic->oem_parameters.sds1.phys[phy_idx];
129 u32 phy_configuration;
130 struct sas_capabilities phy_capabilities;
131 u32 parity_check = 0;
132 u32 parity_count = 0;
133 u32 llctl, link_rate;
136 sci_phy->link_layer_registers = link_layer_registers;
138 /* Set our IDENTIFY frame data */
139 #define SCI_END_DEVICE 0x01
141 writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) |
142 SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) |
143 SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
144 SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
145 SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE),
146 &sci_phy->link_layer_registers->transmit_identification);
148 /* Write the device SAS Address */
149 writel(0xFEDCBA98, &sci_phy->link_layer_registers->sas_device_name_high);
150 writel(phy_idx, &sci_phy->link_layer_registers->sas_device_name_low);
152 /* Write the source SAS Address */
153 writel(phy_oem->sas_address.high,
154 &sci_phy->link_layer_registers->source_sas_address_high);
155 writel(phy_oem->sas_address.low,
156 &sci_phy->link_layer_registers->source_sas_address_low);
158 /* Clear and Set the PHY Identifier */
159 writel(0, &sci_phy->link_layer_registers->identify_frame_phy_id);
160 writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx),
161 &sci_phy->link_layer_registers->identify_frame_phy_id);
163 /* Change the initial state of the phy configuration register */
165 readl(&sci_phy->link_layer_registers->phy_configuration);
167 /* Hold OOB state machine in reset */
168 phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
169 writel(phy_configuration,
170 &sci_phy->link_layer_registers->phy_configuration);
172 /* Configure the SNW capabilities */
173 phy_capabilities.u.all = 0;
174 phy_capabilities.u.bits.start = 1;
175 phy_capabilities.u.bits.gen3_without_ssc_supported = 1;
176 phy_capabilities.u.bits.gen2_without_ssc_supported = 1;
177 phy_capabilities.u.bits.gen1_without_ssc_supported = 1;
178 if (scic->oem_parameters.sds1.controller.do_enable_ssc == true) {
179 phy_capabilities.u.bits.gen3_with_ssc_supported = 1;
180 phy_capabilities.u.bits.gen2_with_ssc_supported = 1;
181 phy_capabilities.u.bits.gen1_with_ssc_supported = 1;
185 * The SAS specification indicates that the phy_capabilities that
186 * are transmitted shall have an even parity. Calculate the parity. */
187 parity_check = phy_capabilities.u.all;
188 while (parity_check != 0) {
189 if (parity_check & 0x1)
195 * If parity indicates there are an odd number of bits set, then
196 * set the parity bit to 1 in the phy capabilities. */
197 if ((parity_count % 2) != 0)
198 phy_capabilities.u.bits.parity = 1;
200 writel(phy_capabilities.u.all,
201 &sci_phy->link_layer_registers->phy_capabilities);
203 /* Set the enable spinup period but disable the ability to send
204 * notify enable spinup
206 writel(SCU_ENSPINUP_GEN_VAL(COUNT,
207 phy_user->notify_enable_spin_up_insertion_frequency),
208 &sci_phy->link_layer_registers->notify_enable_spinup_control);
210 /* Write the ALIGN Insertion Ferequency for connected phy and
211 * inpendent of connected state
213 clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
214 phy_user->in_connection_align_insertion_frequency);
216 clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
217 phy_user->align_insertion_frequency);
219 writel(clksm_value, &sci_phy->link_layer_registers->clock_skew_management);
221 /* @todo Provide a way to write this register correctly */
223 &sci_phy->link_layer_registers->afe_lookup_table_control);
225 llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
226 (u8)scic->user_parameters.sds1.no_outbound_task_timeout);
228 switch(phy_user->max_speed_generation) {
229 case SCIC_SDS_PARM_GEN3_SPEED:
230 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3;
232 case SCIC_SDS_PARM_GEN2_SPEED:
233 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
236 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
239 llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
240 writel(llctl, &sci_phy->link_layer_registers->link_layer_control);
242 if (is_a0() || is_a2()) {
243 /* Program the max ARB time for the PHY to 700us so we inter-operate with
244 * the PMC expander which shuts down PHYs if the expander PHY generates too
245 * many breaks. This time value will guarantee that the initiator PHY will
246 * generate the break.
248 writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
249 &sci_phy->link_layer_registers->maximum_arbitration_wait_timer_timeout);
253 * Set the link layer hang detection to 500ms (0x1F4) from its default
254 * value of 128ms. Max value is 511 ms.
256 writel(0x1F4, &sci_phy->link_layer_registers->link_layer_hang_detection_timeout);
258 /* We can exit the initial state to the stopped state */
259 sci_base_state_machine_change_state(&sci_phy->state_machine,
260 SCI_BASE_PHY_STATE_STOPPED);
266 * This function will handle the sata SIGNATURE FIS timeout condition. It will
267 * restart the starting substate machine since we dont know what has actually
270 static void scic_sds_phy_sata_timeout(void *phy)
272 struct scic_sds_phy *sci_phy = phy;
274 dev_dbg(sciphy_to_dev(sci_phy),
275 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
280 sci_base_state_machine_stop(&sci_phy->starting_substate_machine);
282 sci_base_state_machine_change_state(&sci_phy->state_machine,
283 SCI_BASE_PHY_STATE_STARTING);
287 * This method returns the port currently containing this phy. If the phy is
288 * currently contained by the dummy port, then the phy is considered to not
290 * @sci_phy: This parameter specifies the phy for which to retrieve the
293 * This method returns a handle to a port that contains the supplied phy.
294 * NULL This value is returned if the phy is not part of a real
295 * port (i.e. it's contained in the dummy port). !NULL All other
296 * values indicate a handle/pointer to the port containing the phy.
298 struct scic_sds_port *scic_sds_phy_get_port(
299 struct scic_sds_phy *sci_phy)
301 if (scic_sds_port_get_index(sci_phy->owning_port) == SCIC_SDS_DUMMY_PORT)
304 return sci_phy->owning_port;
308 * This method will assign a port to the phy object.
309 * @out]: sci_phy This parameter specifies the phy for which to assign a port
314 void scic_sds_phy_set_port(
315 struct scic_sds_phy *sci_phy,
316 struct scic_sds_port *sci_port)
318 sci_phy->owning_port = sci_port;
320 if (sci_phy->bcn_received_while_port_unassigned) {
321 sci_phy->bcn_received_while_port_unassigned = false;
322 scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy);
327 * This method will initialize the constructed phy
329 * @link_layer_registers:
333 enum sci_status scic_sds_phy_initialize(
334 struct scic_sds_phy *sci_phy,
335 struct scu_transport_layer_registers __iomem *transport_layer_registers,
336 struct scu_link_layer_registers __iomem *link_layer_registers)
338 struct scic_sds_controller *scic = scic_sds_phy_get_controller(sci_phy);
339 struct isci_host *ihost = scic->ihost;
341 /* Create the SIGNATURE FIS Timeout timer for this phy */
342 sci_phy->sata_timeout_timer =
346 scic_sds_phy_sata_timeout);
348 /* Perfrom the initialization of the TL hardware */
349 scic_sds_phy_transport_layer_initialization(
351 transport_layer_registers);
353 /* Perofrm the initialization of the PE hardware */
354 scic_sds_phy_link_layer_initialization(sci_phy, link_layer_registers);
357 * There is nothing that needs to be done in this state just
358 * transition to the stopped state. */
359 sci_base_state_machine_change_state(&sci_phy->state_machine,
360 SCI_BASE_PHY_STATE_STOPPED);
366 * This method assigns the direct attached device ID for this phy.
368 * @sci_phy The phy for which the direct attached device id is to
370 * @device_id The direct attached device ID to assign to the phy.
371 * This will either be the RNi for the device or an invalid RNi if there
372 * is no current device assigned to the phy.
374 void scic_sds_phy_setup_transport(
375 struct scic_sds_phy *sci_phy,
380 writel(device_id, &sci_phy->transport_layer_registers->stp_rni);
383 * The read should guarantee that the first write gets posted
384 * before the next write
386 tl_control = readl(&sci_phy->transport_layer_registers->control);
387 tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
388 writel(tl_control, &sci_phy->transport_layer_registers->control);
393 * @sci_phy: The phy object to be suspended.
395 * This function will perform the register reads/writes to suspend the SCU
396 * hardware protocol engine. none
398 static void scic_sds_phy_suspend(
399 struct scic_sds_phy *sci_phy)
401 u32 scu_sas_pcfg_value;
404 readl(&sci_phy->link_layer_registers->phy_configuration);
405 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
406 writel(scu_sas_pcfg_value,
407 &sci_phy->link_layer_registers->phy_configuration);
409 scic_sds_phy_setup_transport(
411 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
414 void scic_sds_phy_resume(struct scic_sds_phy *sci_phy)
416 u32 scu_sas_pcfg_value;
419 readl(&sci_phy->link_layer_registers->phy_configuration);
420 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
421 writel(scu_sas_pcfg_value,
422 &sci_phy->link_layer_registers->phy_configuration);
425 void scic_sds_phy_get_sas_address(struct scic_sds_phy *sci_phy,
426 struct sci_sas_address *sas_address)
428 sas_address->high = readl(&sci_phy->link_layer_registers->source_sas_address_high);
429 sas_address->low = readl(&sci_phy->link_layer_registers->source_sas_address_low);
432 void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy *sci_phy,
433 struct sci_sas_address *sas_address)
435 struct sas_identify_frame *iaf;
437 iaf = &sci_phy->phy_type.sas.identify_address_frame_buffer;
438 memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE);
441 void scic_sds_phy_get_protocols(
442 struct scic_sds_phy *sci_phy,
443 struct sci_sas_identify_address_frame_protocols *protocols)
446 (u16)(readl(&sci_phy->
447 link_layer_registers->transmit_identification) &
451 void scic_sds_phy_get_attached_phy_protocols(
452 struct scic_sds_phy *sci_phy,
453 struct sci_sas_identify_address_frame_protocols *protocols)
455 protocols->u.all = 0;
457 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
458 struct sas_identify_frame *iaf;
460 iaf = &sci_phy->phy_type.sas.identify_address_frame_buffer;
461 memcpy(&protocols->u.all, &iaf->initiator_bits, 2);
462 } else if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
463 protocols->u.bits.stp_target = 1;
468 * *****************************************************************************
469 * * SCIC SDS PHY Handler Redirects
470 * ***************************************************************************** */
473 * This method will attempt to start the phy object. This request is only valid
474 * when the phy is in the stopped state
479 enum sci_status scic_sds_phy_start(struct scic_sds_phy *sci_phy)
481 return sci_phy->state_handlers->start_handler(sci_phy);
485 * This method will attempt to stop the phy object.
488 * enum sci_status SCI_SUCCESS if the phy is going to stop SCI_INVALID_STATE
489 * if the phy is not in a valid state to stop
491 enum sci_status scic_sds_phy_stop(struct scic_sds_phy *sci_phy)
493 return sci_phy->state_handlers->stop_handler(sci_phy);
497 * This method will attempt to reset the phy. This request is only valid when
498 * the phy is in an ready state
503 enum sci_status scic_sds_phy_reset(
504 struct scic_sds_phy *sci_phy)
506 return sci_phy->state_handlers->reset_handler(sci_phy);
510 * This method will process the event code received.
516 enum sci_status scic_sds_phy_event_handler(
517 struct scic_sds_phy *sci_phy,
520 return sci_phy->state_handlers->event_handler(sci_phy, event_code);
524 * This method will process the frame index received.
530 enum sci_status scic_sds_phy_frame_handler(
531 struct scic_sds_phy *sci_phy,
534 return sci_phy->state_handlers->frame_handler(sci_phy, frame_index);
538 * This method will give the phy permission to consume power
543 enum sci_status scic_sds_phy_consume_power_handler(
544 struct scic_sds_phy *sci_phy)
546 return sci_phy->state_handlers->consume_power_handler(sci_phy);
550 * *****************************************************************************
551 * * SCIC PHY Public Methods
552 * ***************************************************************************** */
555 enum sci_status scic_sas_phy_get_properties(
556 struct scic_sds_phy *sci_phy,
557 struct scic_sas_phy_properties *properties)
559 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
560 memcpy(&properties->rcvd_iaf,
561 &sci_phy->phy_type.sas.identify_address_frame_buffer,
562 sizeof(struct sas_identify_frame));
564 properties->received_capabilities.u.all =
565 readl(&sci_phy->link_layer_registers->receive_phycap);
574 enum sci_status scic_sata_phy_get_properties(
575 struct scic_sds_phy *sci_phy,
576 struct scic_sata_phy_properties *properties)
578 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
579 memcpy(&properties->signature_fis,
580 &sci_phy->phy_type.sata.signature_fis_buffer,
581 sizeof(struct dev_to_host_fis));
583 /* / @todo add support for port selectors. */
584 properties->is_port_selector_present = false;
593 * *****************************************************************************
594 * * SCIC SDS PHY HELPER FUNCTIONS
595 * ***************************************************************************** */
600 * @sci_phy: The phy object that received SAS PHY DETECTED.
602 * This method continues the link training for the phy as if it were a SAS PHY
603 * instead of a SATA PHY. This is done because the completion queue had a SAS
604 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
607 static void scic_sds_phy_start_sas_link_training(
608 struct scic_sds_phy *sci_phy)
613 readl(&sci_phy->link_layer_registers->phy_configuration);
614 phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
616 &sci_phy->link_layer_registers->phy_configuration);
618 sci_base_state_machine_change_state(
619 &sci_phy->starting_substate_machine,
620 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
623 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
628 * @sci_phy: The phy object that received a SATA SPINUP HOLD event
630 * This method continues the link training for the phy as if it were a SATA PHY
631 * instead of a SAS PHY. This is done because the completion queue had a SATA
632 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
634 static void scic_sds_phy_start_sata_link_training(
635 struct scic_sds_phy *sci_phy)
637 sci_base_state_machine_change_state(
638 &sci_phy->starting_substate_machine,
639 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
642 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
646 * scic_sds_phy_complete_link_training - perform processing common to
647 * all protocols upon completion of link training.
648 * @sci_phy: This parameter specifies the phy object for which link training
650 * @max_link_rate: This parameter specifies the maximum link rate to be
651 * associated with this phy.
652 * @next_state: This parameter specifies the next state for the phy's starting
656 static void scic_sds_phy_complete_link_training(
657 struct scic_sds_phy *sci_phy,
658 enum sas_linkrate max_link_rate,
661 sci_phy->max_negotiated_speed = max_link_rate;
663 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
667 static void scic_sds_phy_restart_starting_state(
668 struct scic_sds_phy *sci_phy)
670 /* Stop the current substate machine */
671 sci_base_state_machine_stop(&sci_phy->starting_substate_machine);
673 /* Re-enter the base state machine starting state */
674 sci_base_state_machine_change_state(&sci_phy->state_machine,
675 SCI_BASE_PHY_STATE_STARTING);
678 /* ****************************************************************************
679 * SCIC SDS PHY general handlers
680 ************************************************************************** */
681 static enum sci_status scic_sds_phy_starting_substate_general_stop_handler(
682 struct scic_sds_phy *phy)
684 sci_base_state_machine_stop(&phy->starting_substate_machine);
686 sci_base_state_machine_change_state(&phy->state_machine,
687 SCI_BASE_PHY_STATE_STOPPED);
693 * *****************************************************************************
694 * * SCIC SDS PHY EVENT_HANDLERS
695 * ***************************************************************************** */
699 * @phy: This struct scic_sds_phy object which has received an event.
700 * @event_code: This is the event code which the phy object is to decode.
702 * This method is called when an event notification is received for the phy
703 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
704 * decode the event - sas phy detected causes a state transition to the wait
705 * for speed event notification. - any other events log a warning message and
706 * set a failure status enum sci_status SCI_SUCCESS on any valid event notification
707 * SCI_FAILURE on any unexpected event notifation
709 static enum sci_status scic_sds_phy_starting_substate_await_ossp_event_handler(
710 struct scic_sds_phy *sci_phy,
713 u32 result = SCI_SUCCESS;
715 switch (scu_get_event_code(event_code)) {
716 case SCU_EVENT_SAS_PHY_DETECTED:
717 scic_sds_phy_start_sas_link_training(sci_phy);
718 sci_phy->is_in_link_training = true;
721 case SCU_EVENT_SATA_SPINUP_HOLD:
722 scic_sds_phy_start_sata_link_training(sci_phy);
723 sci_phy->is_in_link_training = true;
727 dev_dbg(sciphy_to_dev(sci_phy),
728 "%s: PHY starting substate machine received "
729 "unexpected event_code %x\n",
733 result = SCI_FAILURE;
742 * @phy: This struct scic_sds_phy object which has received an event.
743 * @event_code: This is the event code which the phy object is to decode.
745 * This method is called when an event notification is received for the phy
746 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
747 * decode the event - sas phy detected returns us back to this state. - speed
748 * event detected causes a state transition to the wait for iaf. - identify
749 * timeout is an un-expected event and the state machine is restarted. - link
750 * failure events restart the starting state machine - any other events log a
751 * warning message and set a failure status enum sci_status SCI_SUCCESS on any valid
752 * event notification SCI_FAILURE on any unexpected event notifation
754 static enum sci_status scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler(
755 struct scic_sds_phy *sci_phy,
758 u32 result = SCI_SUCCESS;
760 switch (scu_get_event_code(event_code)) {
761 case SCU_EVENT_SAS_PHY_DETECTED:
763 * Why is this being reported again by the controller?
764 * We would re-enter this state so just stay here */
767 case SCU_EVENT_SAS_15:
768 case SCU_EVENT_SAS_15_SSC:
769 scic_sds_phy_complete_link_training(
771 SAS_LINK_RATE_1_5_GBPS,
772 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF);
775 case SCU_EVENT_SAS_30:
776 case SCU_EVENT_SAS_30_SSC:
777 scic_sds_phy_complete_link_training(
779 SAS_LINK_RATE_3_0_GBPS,
780 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF);
783 case SCU_EVENT_SAS_60:
784 case SCU_EVENT_SAS_60_SSC:
785 scic_sds_phy_complete_link_training(
787 SAS_LINK_RATE_6_0_GBPS,
788 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF);
791 case SCU_EVENT_SATA_SPINUP_HOLD:
793 * We were doing SAS PHY link training and received a SATA PHY event
794 * continue OOB/SN as if this were a SATA PHY */
795 scic_sds_phy_start_sata_link_training(sci_phy);
798 case SCU_EVENT_LINK_FAILURE:
799 /* Link failure change state back to the starting state */
800 scic_sds_phy_restart_starting_state(sci_phy);
804 dev_warn(sciphy_to_dev(sci_phy),
805 "%s: PHY starting substate machine received "
806 "unexpected event_code %x\n",
810 result = SCI_FAILURE;
819 * @phy: This struct scic_sds_phy object which has received an event.
820 * @event_code: This is the event code which the phy object is to decode.
822 * This method is called when an event notification is received for the phy
823 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. -
824 * decode the event - sas phy detected event backs up the state machine to the
825 * await speed notification. - identify timeout is an un-expected event and the
826 * state machine is restarted. - link failure events restart the starting state
827 * machine - any other events log a warning message and set a failure status
828 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
829 * unexpected event notifation
831 static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_event_handler(
832 struct scic_sds_phy *sci_phy,
835 u32 result = SCI_SUCCESS;
837 switch (scu_get_event_code(event_code)) {
838 case SCU_EVENT_SAS_PHY_DETECTED:
839 /* Backup the state machine */
840 scic_sds_phy_start_sas_link_training(sci_phy);
843 case SCU_EVENT_SATA_SPINUP_HOLD:
845 * We were doing SAS PHY link training and received a SATA PHY event
846 * continue OOB/SN as if this were a SATA PHY */
847 scic_sds_phy_start_sata_link_training(sci_phy);
850 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
851 case SCU_EVENT_LINK_FAILURE:
852 case SCU_EVENT_HARD_RESET_RECEIVED:
853 /* Start the oob/sn state machine over again */
854 scic_sds_phy_restart_starting_state(sci_phy);
858 dev_warn(sciphy_to_dev(sci_phy),
859 "%s: PHY starting substate machine received "
860 "unexpected event_code %x\n",
864 result = SCI_FAILURE;
873 * @phy: This struct scic_sds_phy object which has received an event.
874 * @event_code: This is the event code which the phy object is to decode.
876 * This method is called when an event notification is received for the phy
877 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. -
878 * decode the event - link failure events restart the starting state machine -
879 * any other events log a warning message and set a failure status enum sci_status
880 * SCI_SUCCESS on a link failure event SCI_FAILURE on any unexpected event
883 static enum sci_status scic_sds_phy_starting_substate_await_sas_power_event_handler(
884 struct scic_sds_phy *sci_phy,
887 u32 result = SCI_SUCCESS;
889 switch (scu_get_event_code(event_code)) {
890 case SCU_EVENT_LINK_FAILURE:
891 /* Link failure change state back to the starting state */
892 scic_sds_phy_restart_starting_state(sci_phy);
896 dev_warn(sciphy_to_dev(sci_phy),
897 "%s: PHY starting substate machine received unexpected "
902 result = SCI_FAILURE;
911 * @phy: This struct scic_sds_phy object which has received an event.
912 * @event_code: This is the event code which the phy object is to decode.
914 * This method is called when an event notification is received for the phy
915 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. -
916 * decode the event - link failure events restart the starting state machine -
917 * sata spinup hold events are ignored since they are expected - any other
918 * events log a warning message and set a failure status enum sci_status SCI_SUCCESS
919 * on a link failure event SCI_FAILURE on any unexpected event notifation
921 static enum sci_status scic_sds_phy_starting_substate_await_sata_power_event_handler(
922 struct scic_sds_phy *sci_phy,
925 u32 result = SCI_SUCCESS;
927 switch (scu_get_event_code(event_code)) {
928 case SCU_EVENT_LINK_FAILURE:
929 /* Link failure change state back to the starting state */
930 scic_sds_phy_restart_starting_state(sci_phy);
933 case SCU_EVENT_SATA_SPINUP_HOLD:
934 /* These events are received every 10ms and are expected while in this state */
937 case SCU_EVENT_SAS_PHY_DETECTED:
939 * There has been a change in the phy type before OOB/SN for the
940 * SATA finished start down the SAS link traning path. */
941 scic_sds_phy_start_sas_link_training(sci_phy);
945 dev_warn(sciphy_to_dev(sci_phy),
946 "%s: PHY starting substate machine received "
947 "unexpected event_code %x\n",
951 result = SCI_FAILURE;
959 * scic_sds_phy_starting_substate_await_sata_phy_event_handler -
960 * @phy: This struct scic_sds_phy object which has received an event.
961 * @event_code: This is the event code which the phy object is to decode.
963 * This method is called when an event notification is received for the phy
964 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. -
965 * decode the event - link failure events restart the starting state machine -
966 * sata spinup hold events are ignored since they are expected - sata phy
967 * detected event change to the wait speed event - any other events log a
968 * warning message and set a failure status enum sci_status SCI_SUCCESS on a link
969 * failure event SCI_FAILURE on any unexpected event notifation
971 static enum sci_status scic_sds_phy_starting_substate_await_sata_phy_event_handler(
972 struct scic_sds_phy *sci_phy, u32 event_code)
974 u32 result = SCI_SUCCESS;
976 switch (scu_get_event_code(event_code)) {
977 case SCU_EVENT_LINK_FAILURE:
978 /* Link failure change state back to the starting state */
979 scic_sds_phy_restart_starting_state(sci_phy);
982 case SCU_EVENT_SATA_SPINUP_HOLD:
983 /* These events might be received since we dont know how many may be in
984 * the completion queue while waiting for power
988 case SCU_EVENT_SATA_PHY_DETECTED:
989 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
991 /* We have received the SATA PHY notification change state */
992 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
993 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN);
996 case SCU_EVENT_SAS_PHY_DETECTED:
997 /* There has been a change in the phy type before OOB/SN for the
998 * SATA finished start down the SAS link traning path.
1000 scic_sds_phy_start_sas_link_training(sci_phy);
1004 dev_warn(sciphy_to_dev(sci_phy),
1005 "%s: PHY starting substate machine received "
1006 "unexpected event_code %x\n",
1010 result = SCI_FAILURE;
1019 * @phy: This struct scic_sds_phy object which has received an event.
1020 * @event_code: This is the event code which the phy object is to decode.
1022 * This method is called when an event notification is received for the phy
1023 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
1024 * - decode the event - sata phy detected returns us back to this state. -
1025 * speed event detected causes a state transition to the wait for signature. -
1026 * link failure events restart the starting state machine - any other events
1027 * log a warning message and set a failure status enum sci_status SCI_SUCCESS on any
1028 * valid event notification SCI_FAILURE on any unexpected event notifation
1030 static enum sci_status scic_sds_phy_starting_substate_await_sata_speed_event_handler(
1031 struct scic_sds_phy *sci_phy,
1034 u32 result = SCI_SUCCESS;
1036 switch (scu_get_event_code(event_code)) {
1037 case SCU_EVENT_SATA_PHY_DETECTED:
1039 * The hardware reports multiple SATA PHY detected events
1040 * ignore the extras */
1043 case SCU_EVENT_SATA_15:
1044 case SCU_EVENT_SATA_15_SSC:
1045 scic_sds_phy_complete_link_training(
1047 SAS_LINK_RATE_1_5_GBPS,
1048 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF);
1051 case SCU_EVENT_SATA_30:
1052 case SCU_EVENT_SATA_30_SSC:
1053 scic_sds_phy_complete_link_training(
1055 SAS_LINK_RATE_3_0_GBPS,
1056 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF);
1059 case SCU_EVENT_SATA_60:
1060 case SCU_EVENT_SATA_60_SSC:
1061 scic_sds_phy_complete_link_training(
1063 SAS_LINK_RATE_6_0_GBPS,
1064 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF);
1067 case SCU_EVENT_LINK_FAILURE:
1068 /* Link failure change state back to the starting state */
1069 scic_sds_phy_restart_starting_state(sci_phy);
1072 case SCU_EVENT_SAS_PHY_DETECTED:
1074 * There has been a change in the phy type before OOB/SN for the
1075 * SATA finished start down the SAS link traning path. */
1076 scic_sds_phy_start_sas_link_training(sci_phy);
1080 dev_warn(sciphy_to_dev(sci_phy),
1081 "%s: PHY starting substate machine received "
1082 "unexpected event_code %x\n",
1086 result = SCI_FAILURE;
1094 * scic_sds_phy_starting_substate_await_sig_fis_event_handler -
1095 * @phy: This struct scic_sds_phy object which has received an event.
1096 * @event_code: This is the event code which the phy object is to decode.
1098 * This method is called when an event notification is received for the phy
1099 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. -
1100 * decode the event - sas phy detected event backs up the state machine to the
1101 * await speed notification. - identify timeout is an un-expected event and the
1102 * state machine is restarted. - link failure events restart the starting state
1103 * machine - any other events log a warning message and set a failure status
1104 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
1105 * unexpected event notifation
1107 static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_event_handler(
1108 struct scic_sds_phy *sci_phy, u32 event_code)
1110 u32 result = SCI_SUCCESS;
1112 switch (scu_get_event_code(event_code)) {
1113 case SCU_EVENT_SATA_PHY_DETECTED:
1114 /* Backup the state machine */
1115 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
1116 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN);
1119 case SCU_EVENT_LINK_FAILURE:
1120 /* Link failure change state back to the starting state */
1121 scic_sds_phy_restart_starting_state(sci_phy);
1125 dev_warn(sciphy_to_dev(sci_phy),
1126 "%s: PHY starting substate machine received "
1127 "unexpected event_code %x\n",
1131 result = SCI_FAILURE;
1140 * *****************************************************************************
1141 * * SCIC SDS PHY FRAME_HANDLERS
1142 * ***************************************************************************** */
1146 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1148 * @frame_index: This is the index of the unsolicited frame which was received
1151 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1152 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Get the UF Header - If the UF
1153 * is an IAF - Copy IAF data to local phy object IAF data buffer. - Change
1154 * starting substate to wait power. - else - log warning message of unexpected
1155 * unsolicted frame - release frame buffer enum sci_status SCI_SUCCESS
1157 static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler(
1158 struct scic_sds_phy *sci_phy, u32 frame_index)
1160 enum sci_status result;
1162 struct sas_identify_frame *identify_frame;
1164 result = scic_sds_unsolicited_frame_control_get_header(
1165 &(scic_sds_phy_get_controller(sci_phy)->uf_control),
1167 (void **)&frame_words);
1169 if (result != SCI_SUCCESS) {
1173 frame_words[0] = SCIC_SWAP_DWORD(frame_words[0]);
1174 identify_frame = (struct sas_identify_frame *)frame_words;
1176 if (identify_frame->frame_type == 0) {
1179 /* Byte swap the rest of the frame so we can make
1180 * a copy of the buffer
1182 frame_words[1] = SCIC_SWAP_DWORD(frame_words[1]);
1183 frame_words[2] = SCIC_SWAP_DWORD(frame_words[2]);
1184 frame_words[3] = SCIC_SWAP_DWORD(frame_words[3]);
1185 frame_words[4] = SCIC_SWAP_DWORD(frame_words[4]);
1186 frame_words[5] = SCIC_SWAP_DWORD(frame_words[5]);
1188 memcpy(&sci_phy->phy_type.sas.identify_address_frame_buffer,
1190 sizeof(struct sas_identify_frame));
1192 if (identify_frame->smp_tport) {
1193 /* We got the IAF for an expander PHY go to the final state since
1194 * there are no power requirements for expander phys.
1196 state = SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL;
1198 /* We got the IAF we can now go to the await spinup semaphore state */
1199 state = SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER;
1201 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
1203 result = SCI_SUCCESS;
1205 dev_warn(sciphy_to_dev(sci_phy),
1206 "%s: PHY starting substate machine received "
1207 "unexpected frame id %x\n",
1211 /* Regardless of the result release this frame since we are done with it */
1212 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy),
1220 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1222 * @frame_index: This is the index of the unsolicited frame which was received
1225 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1226 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Get the UF Header - If
1227 * the UF is an SIGNATURE FIS - Copy IAF data to local phy object SIGNATURE FIS
1228 * data buffer. - else - log warning message of unexpected unsolicted frame -
1229 * release frame buffer enum sci_status SCI_SUCCESS Must decode the SIGNATURE FIS
1232 static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_frame_handler(
1233 struct scic_sds_phy *sci_phy,
1236 enum sci_status result;
1237 struct dev_to_host_fis *frame_header;
1238 u32 *fis_frame_data;
1240 result = scic_sds_unsolicited_frame_control_get_header(
1241 &(scic_sds_phy_get_controller(sci_phy)->uf_control),
1243 (void **)&frame_header);
1245 if (result != SCI_SUCCESS)
1248 if ((frame_header->fis_type == FIS_REGD2H) &&
1249 !(frame_header->status & ATA_BUSY)) {
1250 scic_sds_unsolicited_frame_control_get_buffer(
1251 &(scic_sds_phy_get_controller(sci_phy)->uf_control),
1253 (void **)&fis_frame_data);
1255 scic_sds_controller_copy_sata_response(
1256 &sci_phy->phy_type.sata.signature_fis_buffer,
1260 /* got IAF we can now go to the await spinup semaphore state */
1261 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
1262 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL);
1264 result = SCI_SUCCESS;
1266 dev_warn(sciphy_to_dev(sci_phy),
1267 "%s: PHY starting substate machine received "
1268 "unexpected frame id %x\n",
1272 /* Regardless of the result we are done with this frame with it */
1273 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy),
1280 * *****************************************************************************
1281 * * SCIC SDS PHY POWER_HANDLERS
1282 * ***************************************************************************** */
1285 * This method is called by the struct scic_sds_controller when the phy object is
1286 * granted power. - The notify enable spinups are turned on for this phy object
1287 * - The phy state machine is transitioned to the
1288 * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. enum sci_status SCI_SUCCESS
1290 static enum sci_status scic_sds_phy_starting_substate_await_sas_power_consume_power_handler(
1291 struct scic_sds_phy *sci_phy)
1295 enable_spinup = readl(&sci_phy->link_layer_registers->notify_enable_spinup_control);
1296 enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
1297 writel(enable_spinup, &sci_phy->link_layer_registers->notify_enable_spinup_control);
1299 /* Change state to the final state this substate machine has run to completion */
1300 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
1301 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL);
1307 * This method is called by the struct scic_sds_controller when the phy object is
1308 * granted power. - The phy state machine is transitioned to the
1309 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. enum sci_status SCI_SUCCESS
1311 static enum sci_status scic_sds_phy_starting_substate_await_sata_power_consume_power_handler(
1312 struct scic_sds_phy *sci_phy)
1314 u32 scu_sas_pcfg_value;
1316 /* Release the spinup hold state and reset the OOB state machine */
1317 scu_sas_pcfg_value =
1318 readl(&sci_phy->link_layer_registers->phy_configuration);
1319 scu_sas_pcfg_value &=
1320 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
1321 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1322 writel(scu_sas_pcfg_value,
1323 &sci_phy->link_layer_registers->phy_configuration);
1325 /* Now restart the OOB operation */
1326 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1327 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
1328 writel(scu_sas_pcfg_value,
1329 &sci_phy->link_layer_registers->phy_configuration);
1331 /* Change state to the final state this substate machine has run to completion */
1332 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
1333 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN);
1338 static enum sci_status default_phy_handler(struct scic_sds_phy *sci_phy,
1341 dev_dbg(sciphy_to_dev(sci_phy),
1342 "%s: in wrong state: %d\n", func,
1343 sci_base_state_machine_get_state(&sci_phy->state_machine));
1344 return SCI_FAILURE_INVALID_STATE;
1347 static enum sci_status
1348 scic_sds_phy_default_start_handler(struct scic_sds_phy *sci_phy)
1350 return default_phy_handler(sci_phy, __func__);
1353 static enum sci_status
1354 scic_sds_phy_default_stop_handler(struct scic_sds_phy *sci_phy)
1356 return default_phy_handler(sci_phy, __func__);
1359 static enum sci_status
1360 scic_sds_phy_default_reset_handler(struct scic_sds_phy *sci_phy)
1362 return default_phy_handler(sci_phy, __func__);
1365 static enum sci_status
1366 scic_sds_phy_default_destroy_handler(struct scic_sds_phy *sci_phy)
1368 return default_phy_handler(sci_phy, __func__);
1371 static enum sci_status
1372 scic_sds_phy_default_frame_handler(struct scic_sds_phy *sci_phy,
1375 struct scic_sds_controller *scic = scic_sds_phy_get_controller(sci_phy);
1377 default_phy_handler(sci_phy, __func__);
1378 scic_sds_controller_release_frame(scic, frame_index);
1380 return SCI_FAILURE_INVALID_STATE;
1383 static enum sci_status
1384 scic_sds_phy_default_event_handler(struct scic_sds_phy *sci_phy,
1387 return default_phy_handler(sci_phy, __func__);
1390 static enum sci_status
1391 scic_sds_phy_default_consume_power_handler(struct scic_sds_phy *sci_phy)
1393 return default_phy_handler(sci_phy, __func__);
1398 static const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[] = {
1399 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
1400 .start_handler = scic_sds_phy_default_start_handler,
1401 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1402 .reset_handler = scic_sds_phy_default_reset_handler,
1403 .destruct_handler = scic_sds_phy_default_destroy_handler,
1404 .frame_handler = scic_sds_phy_default_frame_handler,
1405 .event_handler = scic_sds_phy_default_event_handler,
1406 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1408 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
1409 .start_handler = scic_sds_phy_default_start_handler,
1410 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1411 .reset_handler = scic_sds_phy_default_reset_handler,
1412 .destruct_handler = scic_sds_phy_default_destroy_handler,
1413 .frame_handler = scic_sds_phy_default_frame_handler,
1414 .event_handler = scic_sds_phy_starting_substate_await_ossp_event_handler,
1415 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1417 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
1418 .start_handler = scic_sds_phy_default_start_handler,
1419 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1420 .reset_handler = scic_sds_phy_default_reset_handler,
1421 .destruct_handler = scic_sds_phy_default_destroy_handler,
1422 .frame_handler = scic_sds_phy_default_frame_handler,
1423 .event_handler = scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler,
1424 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1426 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = {
1427 .start_handler = scic_sds_phy_default_start_handler,
1428 .stop_handler = scic_sds_phy_default_stop_handler,
1429 .reset_handler = scic_sds_phy_default_reset_handler,
1430 .destruct_handler = scic_sds_phy_default_destroy_handler,
1431 .frame_handler = scic_sds_phy_starting_substate_await_iaf_uf_frame_handler,
1432 .event_handler = scic_sds_phy_starting_substate_await_iaf_uf_event_handler,
1433 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1435 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
1436 .start_handler = scic_sds_phy_default_start_handler,
1437 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1438 .reset_handler = scic_sds_phy_default_reset_handler,
1439 .destruct_handler = scic_sds_phy_default_destroy_handler,
1440 .frame_handler = scic_sds_phy_default_frame_handler,
1441 .event_handler = scic_sds_phy_starting_substate_await_sas_power_event_handler,
1442 .consume_power_handler = scic_sds_phy_starting_substate_await_sas_power_consume_power_handler
1444 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
1445 .start_handler = scic_sds_phy_default_start_handler,
1446 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1447 .reset_handler = scic_sds_phy_default_reset_handler,
1448 .destruct_handler = scic_sds_phy_default_destroy_handler,
1449 .frame_handler = scic_sds_phy_default_frame_handler,
1450 .event_handler = scic_sds_phy_starting_substate_await_sata_power_event_handler,
1451 .consume_power_handler = scic_sds_phy_starting_substate_await_sata_power_consume_power_handler
1453 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
1454 .start_handler = scic_sds_phy_default_start_handler,
1455 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1456 .reset_handler = scic_sds_phy_default_reset_handler,
1457 .destruct_handler = scic_sds_phy_default_destroy_handler,
1458 .frame_handler = scic_sds_phy_default_frame_handler,
1459 .event_handler = scic_sds_phy_starting_substate_await_sata_phy_event_handler,
1460 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1462 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
1463 .start_handler = scic_sds_phy_default_start_handler,
1464 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1465 .reset_handler = scic_sds_phy_default_reset_handler,
1466 .destruct_handler = scic_sds_phy_default_destroy_handler,
1467 .frame_handler = scic_sds_phy_default_frame_handler,
1468 .event_handler = scic_sds_phy_starting_substate_await_sata_speed_event_handler,
1469 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1471 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
1472 .start_handler = scic_sds_phy_default_start_handler,
1473 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1474 .reset_handler = scic_sds_phy_default_reset_handler,
1475 .destruct_handler = scic_sds_phy_default_destroy_handler,
1476 .frame_handler = scic_sds_phy_starting_substate_await_sig_fis_frame_handler,
1477 .event_handler = scic_sds_phy_starting_substate_await_sig_fis_event_handler,
1478 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1480 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
1481 .start_handler = scic_sds_phy_default_start_handler,
1482 .stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
1483 .reset_handler = scic_sds_phy_default_reset_handler,
1484 .destruct_handler = scic_sds_phy_default_destroy_handler,
1485 .frame_handler = scic_sds_phy_default_frame_handler,
1486 .event_handler = scic_sds_phy_default_event_handler,
1487 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1492 * scic_sds_phy_set_starting_substate_handlers() -
1494 * This macro sets the starting substate handlers by state_id
1496 #define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \
1497 scic_sds_phy_set_state_handlers(\
1499 &scic_sds_phy_starting_substate_handler_table[(state_id)] \
1503 * ****************************************************************************
1504 * * PHY STARTING SUBSTATE METHODS
1505 * **************************************************************************** */
1508 * scic_sds_phy_starting_initial_substate_enter -
1509 * @object: This is the object which is cast to a struct scic_sds_phy object.
1511 * This method will perform the actions required by the struct scic_sds_phy on
1512 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL. - The initial state
1513 * handlers are put in place for the struct scic_sds_phy object. - The state is
1514 * changed to the wait phy type event notification. none
1516 static void scic_sds_phy_starting_initial_substate_enter(void *object)
1518 struct scic_sds_phy *sci_phy = object;
1520 scic_sds_phy_set_starting_substate_handlers(
1521 sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
1523 /* This is just an temporary state go off to the starting state */
1524 sci_base_state_machine_change_state(&sci_phy->starting_substate_machine,
1525 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN);
1530 * @object: This is the object which is cast to a struct scic_sds_phy object.
1532 * This method will perform the actions required by the struct scic_sds_phy on
1533 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_PHY_TYPE_EN. - Set the
1534 * struct scic_sds_phy object state handlers for this state. none
1536 static void scic_sds_phy_starting_await_ossp_en_substate_enter(void *object)
1538 struct scic_sds_phy *sci_phy = object;
1540 scic_sds_phy_set_starting_substate_handlers(
1541 sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1547 * @object: This is the object which is cast to a struct scic_sds_phy object.
1549 * This method will perform the actions required by the struct scic_sds_phy on
1550 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - Set the
1551 * struct scic_sds_phy object state handlers for this state. none
1553 static void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
1556 struct scic_sds_phy *sci_phy = object;
1558 scic_sds_phy_set_starting_substate_handlers(
1559 sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
1565 * @object: This is the object which is cast to a struct scic_sds_phy object.
1567 * This method will perform the actions required by the struct scic_sds_phy on
1568 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Set the
1569 * struct scic_sds_phy object state handlers for this state. none
1571 static void scic_sds_phy_starting_await_iaf_uf_substate_enter(void *object)
1573 struct scic_sds_phy *sci_phy = object;
1575 scic_sds_phy_set_starting_substate_handlers(
1576 sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
1582 * @object: This is the object which is cast to a struct scic_sds_phy object.
1584 * This method will perform the actions required by the struct scic_sds_phy on
1585 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Set the
1586 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1587 * the power control queue none
1589 static void scic_sds_phy_starting_await_sas_power_substate_enter(void *object)
1591 struct scic_sds_phy *sci_phy = object;
1593 scic_sds_phy_set_starting_substate_handlers(
1594 sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1597 scic_sds_controller_power_control_queue_insert(
1598 scic_sds_phy_get_controller(sci_phy),
1605 * @object: This is the object which is cast to a struct scic_sds_phy object.
1607 * This method will perform the actions required by the struct scic_sds_phy on exiting
1608 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Remove the
1609 * struct scic_sds_phy object from the power control queue. none
1611 static void scic_sds_phy_starting_await_sas_power_substate_exit(void *object)
1613 struct scic_sds_phy *sci_phy = object;
1615 scic_sds_controller_power_control_queue_remove(
1616 scic_sds_phy_get_controller(sci_phy), sci_phy
1622 * @object: This is the object which is cast to a struct scic_sds_phy object.
1624 * This method will perform the actions required by the struct scic_sds_phy on
1625 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Set the
1626 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1627 * the power control queue none
1629 static void scic_sds_phy_starting_await_sata_power_substate_enter(void *object)
1631 struct scic_sds_phy *sci_phy = object;
1633 scic_sds_phy_set_starting_substate_handlers(
1634 sci_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
1637 scic_sds_controller_power_control_queue_insert(
1638 scic_sds_phy_get_controller(sci_phy),
1645 * @object: This is the object which is cast to a struct scic_sds_phy object.
1647 * This method will perform the actions required by the struct scic_sds_phy on exiting
1648 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Remove the
1649 * struct scic_sds_phy object from the power control queue. none
1651 static void scic_sds_phy_starting_await_sata_power_substate_exit(void *object)
1653 struct scic_sds_phy *sci_phy = object;
1655 scic_sds_controller_power_control_queue_remove(
1656 scic_sds_phy_get_controller(sci_phy),
1663 * @object: This is the object which is cast to a struct scic_sds_phy object.
1665 * This function will perform the actions required by the struct scic_sds_phy on
1666 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. - Set the
1667 * struct scic_sds_phy object state handlers for this state. none
1669 static void scic_sds_phy_starting_await_sata_phy_substate_enter(void *object)
1671 struct scic_sds_phy *sci_phy = object;
1673 scic_sds_phy_set_starting_substate_handlers(
1675 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN);
1677 isci_timer_start(sci_phy->sata_timeout_timer,
1678 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
1683 * @object: This is the object which is cast to a struct scic_sds_phy object.
1685 * This method will perform the actions required by the struct scic_sds_phy
1687 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1688 * that was started on entry to await sata phy event notification none
1690 static inline void scic_sds_phy_starting_await_sata_phy_substate_exit(
1693 struct scic_sds_phy *sci_phy = object;
1695 isci_timer_stop(sci_phy->sata_timeout_timer);
1700 * @object: This is the object which is cast to a struct scic_sds_phy object.
1702 * This method will perform the actions required by the struct scic_sds_phy on
1703 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - Set the
1704 * struct scic_sds_phy object state handlers for this state. none
1706 static void scic_sds_phy_starting_await_sata_speed_substate_enter(void *object)
1708 struct scic_sds_phy *sci_phy = object;
1710 scic_sds_phy_set_starting_substate_handlers(
1712 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN);
1714 isci_timer_start(sci_phy->sata_timeout_timer,
1715 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
1720 * @object: This is the object which is cast to a struct scic_sds_phy object.
1722 * This function will perform the actions required by the
1723 * struct scic_sds_phy on exiting
1724 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1725 * that was started on entry to await sata phy event notification none
1727 static inline void scic_sds_phy_starting_await_sata_speed_substate_exit(
1730 struct scic_sds_phy *sci_phy = object;
1732 isci_timer_stop(sci_phy->sata_timeout_timer);
1737 * @object: This is the object which is cast to a struct scic_sds_phy object.
1739 * This function will perform the actions required by the struct scic_sds_phy on
1740 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Set the
1741 * struct scic_sds_phy object state handlers for this state.
1742 * - Start the SIGNATURE FIS
1743 * timeout timer none
1745 static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(void *object)
1747 bool continue_to_ready_state;
1748 struct scic_sds_phy *sci_phy = object;
1750 scic_sds_phy_set_starting_substate_handlers(
1752 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF);
1754 continue_to_ready_state = scic_sds_port_link_detected(
1755 sci_phy->owning_port,
1758 if (continue_to_ready_state) {
1760 * Clear the PE suspend condition so we can actually
1762 * The hardware will not respond to the XRDY until the PE
1763 * suspend condition is cleared.
1765 scic_sds_phy_resume(sci_phy);
1767 isci_timer_start(sci_phy->sata_timeout_timer,
1768 SCIC_SDS_SIGNATURE_FIS_TIMEOUT);
1770 sci_phy->is_in_link_training = false;
1775 * @object: This is the object which is cast to a struct scic_sds_phy object.
1777 * This function will perform the actions required by the
1778 * struct scic_sds_phy on exiting
1779 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Stop the SIGNATURE
1780 * FIS timeout timer. none
1782 static inline void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(
1785 struct scic_sds_phy *sci_phy = object;
1787 isci_timer_stop(sci_phy->sata_timeout_timer);
1792 * @object: This is the object which is cast to a struct scic_sds_phy object.
1794 * This method will perform the actions required by the struct scic_sds_phy on
1795 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. - Set the struct scic_sds_phy
1796 * object state handlers for this state. - Change base state machine to the
1799 static void scic_sds_phy_starting_final_substate_enter(void *object)
1801 struct scic_sds_phy *sci_phy = object;
1803 scic_sds_phy_set_starting_substate_handlers(sci_phy,
1804 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL);
1806 /* State machine has run to completion so exit out and change
1807 * the base state machine to the ready state
1809 sci_base_state_machine_change_state(&sci_phy->state_machine,
1810 SCI_BASE_PHY_STATE_READY);
1813 /* --------------------------------------------------------------------------- */
1815 static const struct sci_base_state scic_sds_phy_starting_substates[] = {
1816 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
1817 .enter_state = scic_sds_phy_starting_initial_substate_enter,
1819 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
1820 .enter_state = scic_sds_phy_starting_await_ossp_en_substate_enter,
1822 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
1823 .enter_state = scic_sds_phy_starting_await_sas_speed_en_substate_enter,
1825 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = {
1826 .enter_state = scic_sds_phy_starting_await_iaf_uf_substate_enter,
1828 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
1829 .enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
1830 .exit_state = scic_sds_phy_starting_await_sas_power_substate_exit,
1832 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
1833 .enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
1834 .exit_state = scic_sds_phy_starting_await_sata_power_substate_exit
1836 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
1837 .enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
1838 .exit_state = scic_sds_phy_starting_await_sata_phy_substate_exit
1840 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
1841 .enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
1842 .exit_state = scic_sds_phy_starting_await_sata_speed_substate_exit
1844 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
1845 .enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
1846 .exit_state = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
1848 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
1849 .enter_state = scic_sds_phy_starting_final_substate_enter,
1854 * This method takes the struct scic_sds_phy from a stopped state and
1855 * attempts to start it. - The phy state machine is transitioned to the
1856 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
1858 static enum sci_status
1859 scic_sds_phy_stopped_state_start_handler(struct scic_sds_phy *sci_phy)
1861 struct isci_host *ihost;
1862 struct scic_sds_controller *scic;
1864 scic = scic_sds_phy_get_controller(sci_phy),
1865 ihost = scic->ihost;
1867 /* Create the SIGNATURE FIS Timeout timer for this phy */
1868 sci_phy->sata_timeout_timer = isci_timer_create(ihost, sci_phy,
1869 scic_sds_phy_sata_timeout);
1871 if (sci_phy->sata_timeout_timer)
1872 sci_base_state_machine_change_state(&sci_phy->state_machine,
1873 SCI_BASE_PHY_STATE_STARTING);
1878 static enum sci_status
1879 scic_sds_phy_stopped_state_destroy_handler(struct scic_sds_phy *sci_phy)
1884 static enum sci_status
1885 scic_sds_phy_ready_state_stop_handler(struct scic_sds_phy *sci_phy)
1887 sci_base_state_machine_change_state(&sci_phy->state_machine,
1888 SCI_BASE_PHY_STATE_STOPPED);
1893 static enum sci_status
1894 scic_sds_phy_ready_state_reset_handler(struct scic_sds_phy *sci_phy)
1896 sci_base_state_machine_change_state(&sci_phy->state_machine,
1897 SCI_BASE_PHY_STATE_RESETTING);
1903 * scic_sds_phy_ready_state_event_handler -
1904 * @phy: This is the struct scic_sds_phy object which has received the event.
1906 * This method request the struct scic_sds_phy handle the received event. The only
1907 * event that we are interested in while in the ready state is the link failure
1908 * event. - decoded event is a link failure - transition the struct scic_sds_phy back
1909 * to the SCI_BASE_PHY_STATE_STARTING state. - any other event received will
1910 * report a warning message enum sci_status SCI_SUCCESS if the event received is a
1911 * link failure SCI_FAILURE_INVALID_STATE for any other event received.
1913 static enum sci_status scic_sds_phy_ready_state_event_handler(struct scic_sds_phy *sci_phy,
1916 enum sci_status result = SCI_FAILURE;
1918 switch (scu_get_event_code(event_code)) {
1919 case SCU_EVENT_LINK_FAILURE:
1920 /* Link failure change state back to the starting state */
1921 sci_base_state_machine_change_state(&sci_phy->state_machine,
1922 SCI_BASE_PHY_STATE_STARTING);
1923 result = SCI_SUCCESS;
1926 case SCU_EVENT_BROADCAST_CHANGE:
1927 /* Broadcast change received. Notify the port. */
1928 if (scic_sds_phy_get_port(sci_phy) != NULL)
1929 scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy);
1931 sci_phy->bcn_received_while_port_unassigned = true;
1935 dev_warn(sciphy_to_dev(sci_phy),
1936 "%sP SCIC PHY 0x%p ready state machine received "
1937 "unexpected event_code %x\n",
1938 __func__, sci_phy, event_code);
1940 result = SCI_FAILURE_INVALID_STATE;
1947 static enum sci_status scic_sds_phy_resetting_state_event_handler(struct scic_sds_phy *sci_phy,
1950 enum sci_status result = SCI_FAILURE;
1952 switch (scu_get_event_code(event_code)) {
1953 case SCU_EVENT_HARD_RESET_TRANSMITTED:
1954 /* Link failure change state back to the starting state */
1955 sci_base_state_machine_change_state(&sci_phy->state_machine,
1956 SCI_BASE_PHY_STATE_STARTING);
1957 result = SCI_SUCCESS;
1961 dev_warn(sciphy_to_dev(sci_phy),
1962 "%s: SCIC PHY 0x%p resetting state machine received "
1963 "unexpected event_code %x\n",
1964 __func__, sci_phy, event_code);
1966 result = SCI_FAILURE_INVALID_STATE;
1973 /* --------------------------------------------------------------------------- */
1975 static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[] = {
1976 [SCI_BASE_PHY_STATE_INITIAL] = {
1977 .start_handler = scic_sds_phy_default_start_handler,
1978 .stop_handler = scic_sds_phy_default_stop_handler,
1979 .reset_handler = scic_sds_phy_default_reset_handler,
1980 .destruct_handler = scic_sds_phy_default_destroy_handler,
1981 .frame_handler = scic_sds_phy_default_frame_handler,
1982 .event_handler = scic_sds_phy_default_event_handler,
1983 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1985 [SCI_BASE_PHY_STATE_STOPPED] = {
1986 .start_handler = scic_sds_phy_stopped_state_start_handler,
1987 .stop_handler = scic_sds_phy_default_stop_handler,
1988 .reset_handler = scic_sds_phy_default_reset_handler,
1989 .destruct_handler = scic_sds_phy_stopped_state_destroy_handler,
1990 .frame_handler = scic_sds_phy_default_frame_handler,
1991 .event_handler = scic_sds_phy_default_event_handler,
1992 .consume_power_handler = scic_sds_phy_default_consume_power_handler
1994 [SCI_BASE_PHY_STATE_STARTING] = {
1995 .start_handler = scic_sds_phy_default_start_handler,
1996 .stop_handler = scic_sds_phy_default_stop_handler,
1997 .reset_handler = scic_sds_phy_default_reset_handler,
1998 .destruct_handler = scic_sds_phy_default_destroy_handler,
1999 .frame_handler = scic_sds_phy_default_frame_handler,
2000 .event_handler = scic_sds_phy_default_event_handler,
2001 .consume_power_handler = scic_sds_phy_default_consume_power_handler
2003 [SCI_BASE_PHY_STATE_READY] = {
2004 .start_handler = scic_sds_phy_default_start_handler,
2005 .stop_handler = scic_sds_phy_ready_state_stop_handler,
2006 .reset_handler = scic_sds_phy_ready_state_reset_handler,
2007 .destruct_handler = scic_sds_phy_default_destroy_handler,
2008 .frame_handler = scic_sds_phy_default_frame_handler,
2009 .event_handler = scic_sds_phy_ready_state_event_handler,
2010 .consume_power_handler = scic_sds_phy_default_consume_power_handler
2012 [SCI_BASE_PHY_STATE_RESETTING] = {
2013 .start_handler = scic_sds_phy_default_start_handler,
2014 .stop_handler = scic_sds_phy_default_stop_handler,
2015 .reset_handler = scic_sds_phy_default_reset_handler,
2016 .destruct_handler = scic_sds_phy_default_destroy_handler,
2017 .frame_handler = scic_sds_phy_default_frame_handler,
2018 .event_handler = scic_sds_phy_resetting_state_event_handler,
2019 .consume_power_handler = scic_sds_phy_default_consume_power_handler
2021 [SCI_BASE_PHY_STATE_FINAL] = {
2022 .start_handler = scic_sds_phy_default_start_handler,
2023 .stop_handler = scic_sds_phy_default_stop_handler,
2024 .reset_handler = scic_sds_phy_default_reset_handler,
2025 .destruct_handler = scic_sds_phy_default_destroy_handler,
2026 .frame_handler = scic_sds_phy_default_frame_handler,
2027 .event_handler = scic_sds_phy_default_event_handler,
2028 .consume_power_handler = scic_sds_phy_default_consume_power_handler
2033 * ****************************************************************************
2034 * * PHY STATE PRIVATE METHODS
2035 * **************************************************************************** */
2039 * @sci_phy: This is the struct scic_sds_phy object to stop.
2041 * This method will stop the struct scic_sds_phy object. This does not reset the
2042 * protocol engine it just suspends it and places it in a state where it will
2043 * not cause the end device to power up. none
2045 static void scu_link_layer_stop_protocol_engine(
2046 struct scic_sds_phy *sci_phy)
2048 u32 scu_sas_pcfg_value;
2049 u32 enable_spinup_value;
2051 /* Suspend the protocol engine and place it in a sata spinup hold state */
2052 scu_sas_pcfg_value =
2053 readl(&sci_phy->link_layer_registers->phy_configuration);
2054 scu_sas_pcfg_value |=
2055 (SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
2056 SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE) |
2057 SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD));
2058 writel(scu_sas_pcfg_value,
2059 &sci_phy->link_layer_registers->phy_configuration);
2061 /* Disable the notify enable spinup primitives */
2062 enable_spinup_value = readl(&sci_phy->link_layer_registers->notify_enable_spinup_control);
2063 enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
2064 writel(enable_spinup_value, &sci_phy->link_layer_registers->notify_enable_spinup_control);
2070 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
2072 static void scu_link_layer_start_oob(
2073 struct scic_sds_phy *sci_phy)
2075 u32 scu_sas_pcfg_value;
2077 scu_sas_pcfg_value =
2078 readl(&sci_phy->link_layer_registers->phy_configuration);
2079 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2080 scu_sas_pcfg_value &=
2081 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
2082 SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
2083 writel(scu_sas_pcfg_value,
2084 &sci_phy->link_layer_registers->phy_configuration);
2090 * This method will transmit a hard reset request on the specified phy. The SCU
2091 * hardware requires that we reset the OOB state machine and set the hard reset
2092 * bit in the phy configuration register. We then must start OOB over with the
2093 * hard reset bit set.
2095 static void scu_link_layer_tx_hard_reset(
2096 struct scic_sds_phy *sci_phy)
2098 u32 phy_configuration_value;
2101 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
2102 * to the starting state. */
2103 phy_configuration_value =
2104 readl(&sci_phy->link_layer_registers->phy_configuration);
2105 phy_configuration_value |=
2106 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) |
2107 SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
2108 writel(phy_configuration_value,
2109 &sci_phy->link_layer_registers->phy_configuration);
2111 /* Now take the OOB state machine out of reset */
2112 phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2113 phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
2114 writel(phy_configuration_value,
2115 &sci_phy->link_layer_registers->phy_configuration);
2119 * ****************************************************************************
2120 * * PHY BASE STATE METHODS
2121 * **************************************************************************** */
2125 * @object: This is the object which is cast to a struct scic_sds_phy object.
2127 * This method will perform the actions required by the struct scic_sds_phy on
2128 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2129 * handlers for the phy object base state machine initial state. none
2131 static void scic_sds_phy_initial_state_enter(void *object)
2133 struct scic_sds_phy *sci_phy = object;
2135 scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_INITIAL);
2140 * @object: This is the object which is cast to a struct scic_sds_phy object.
2142 * This function will perform the actions required by the struct scic_sds_phy on
2143 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2144 * handlers for the phy object base state machine initial state. - The SCU
2145 * hardware is requested to stop the protocol engine. none
2147 static void scic_sds_phy_stopped_state_enter(void *object)
2149 struct scic_sds_phy *sci_phy = object;
2150 struct scic_sds_controller *scic = scic_sds_phy_get_controller(sci_phy);
2151 struct isci_host *ihost = scic->ihost;
2154 * @todo We need to get to the controller to place this PE in a
2158 scic_sds_phy_set_base_state_handlers(sci_phy,
2159 SCI_BASE_PHY_STATE_STOPPED);
2161 if (sci_phy->sata_timeout_timer != NULL) {
2162 isci_del_timer(ihost, sci_phy->sata_timeout_timer);
2164 sci_phy->sata_timeout_timer = NULL;
2167 scu_link_layer_stop_protocol_engine(sci_phy);
2169 if (sci_phy->state_machine.previous_state_id !=
2170 SCI_BASE_PHY_STATE_INITIAL)
2171 scic_sds_controller_link_down(
2172 scic_sds_phy_get_controller(sci_phy),
2173 scic_sds_phy_get_port(sci_phy),
2179 * @object: This is the object which is cast to a struct scic_sds_phy object.
2181 * This method will perform the actions required by the struct scic_sds_phy on
2182 * entering the SCI_BASE_PHY_STATE_STARTING. - This function sets the state
2183 * handlers for the phy object base state machine starting state. - The SCU
2184 * hardware is requested to start OOB/SN on this protocl engine. - The phy
2185 * starting substate machine is started. - If the previous state was the ready
2186 * state then the struct scic_sds_controller is informed that the phy has gone link
2189 static void scic_sds_phy_starting_state_enter(void *object)
2191 struct scic_sds_phy *sci_phy = object;
2193 scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_STARTING);
2195 scu_link_layer_stop_protocol_engine(sci_phy);
2196 scu_link_layer_start_oob(sci_phy);
2198 /* We don't know what kind of phy we are going to be just yet */
2199 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
2200 sci_phy->bcn_received_while_port_unassigned = false;
2202 /* Change over to the starting substate machine to continue */
2203 sci_base_state_machine_start(&sci_phy->starting_substate_machine);
2205 if (sci_phy->state_machine.previous_state_id
2206 == SCI_BASE_PHY_STATE_READY) {
2207 scic_sds_controller_link_down(
2208 scic_sds_phy_get_controller(sci_phy),
2209 scic_sds_phy_get_port(sci_phy),
2217 * @object: This is the object which is cast to a struct scic_sds_phy object.
2219 * This method will perform the actions required by the struct scic_sds_phy on
2220 * entering the SCI_BASE_PHY_STATE_READY. - This function sets the state
2221 * handlers for the phy object base state machine ready state. - The SCU
2222 * hardware protocol engine is resumed. - The struct scic_sds_controller is informed
2223 * that the phy object has gone link up. none
2225 static void scic_sds_phy_ready_state_enter(void *object)
2227 struct scic_sds_phy *sci_phy = object;
2229 scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_READY);
2231 scic_sds_controller_link_up(
2232 scic_sds_phy_get_controller(sci_phy),
2233 scic_sds_phy_get_port(sci_phy),
2240 * @object: This is the object which is cast to a struct scic_sds_phy object.
2242 * This method will perform the actions required by the struct scic_sds_phy on exiting
2243 * the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU hardware
2244 * protocol engine represented by this struct scic_sds_phy object. none
2246 static void scic_sds_phy_ready_state_exit(void *object)
2248 struct scic_sds_phy *sci_phy = object;
2250 scic_sds_phy_suspend(sci_phy);
2255 * @object: This is the object which is cast to a struct scic_sds_phy object.
2257 * This method will perform the actions required by the struct scic_sds_phy on
2258 * entering the SCI_BASE_PHY_STATE_RESETTING. - This function sets the state
2259 * handlers for the phy object base state machine resetting state. none
2261 static void scic_sds_phy_resetting_state_enter(void *object)
2263 struct scic_sds_phy *sci_phy = object;
2265 scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_RESETTING);
2268 * The phy is being reset, therefore deactivate it from the port.
2269 * In the resetting state we don't notify the user regarding
2270 * link up and link down notifications. */
2271 scic_sds_port_deactivate_phy(sci_phy->owning_port, sci_phy, false);
2273 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
2274 scu_link_layer_tx_hard_reset(sci_phy);
2277 * The SCU does not need to have a discrete reset state so
2278 * just go back to the starting state.
2280 sci_base_state_machine_change_state(
2281 &sci_phy->state_machine,
2282 SCI_BASE_PHY_STATE_STARTING);
2288 * @object: This is the object which is cast to a struct scic_sds_phy object.
2290 * This method will perform the actions required by the struct scic_sds_phy on
2291 * entering the SCI_BASE_PHY_STATE_FINAL. - This function sets the state
2292 * handlers for the phy object base state machine final state. none
2294 static void scic_sds_phy_final_state_enter(void *object)
2296 struct scic_sds_phy *sci_phy = object;
2298 scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_FINAL);
2300 /* Nothing to do here */
2303 /* --------------------------------------------------------------------------- */
2305 static const struct sci_base_state scic_sds_phy_state_table[] = {
2306 [SCI_BASE_PHY_STATE_INITIAL] = {
2307 .enter_state = scic_sds_phy_initial_state_enter,
2309 [SCI_BASE_PHY_STATE_STOPPED] = {
2310 .enter_state = scic_sds_phy_stopped_state_enter,
2312 [SCI_BASE_PHY_STATE_STARTING] = {
2313 .enter_state = scic_sds_phy_starting_state_enter,
2315 [SCI_BASE_PHY_STATE_READY] = {
2316 .enter_state = scic_sds_phy_ready_state_enter,
2317 .exit_state = scic_sds_phy_ready_state_exit,
2319 [SCI_BASE_PHY_STATE_RESETTING] = {
2320 .enter_state = scic_sds_phy_resetting_state_enter,
2322 [SCI_BASE_PHY_STATE_FINAL] = {
2323 .enter_state = scic_sds_phy_final_state_enter,
2327 void scic_sds_phy_construct(struct scic_sds_phy *sci_phy,
2328 struct scic_sds_port *owning_port, u8 phy_index)
2331 sci_base_state_machine_construct(&sci_phy->state_machine,
2333 scic_sds_phy_state_table,
2334 SCI_BASE_PHY_STATE_INITIAL);
2336 sci_base_state_machine_start(&sci_phy->state_machine);
2338 /* Copy the rest of the input data to our locals */
2339 sci_phy->owning_port = owning_port;
2340 sci_phy->phy_index = phy_index;
2341 sci_phy->bcn_received_while_port_unassigned = false;
2342 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
2343 sci_phy->link_layer_registers = NULL;
2344 sci_phy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
2345 sci_phy->sata_timeout_timer = NULL;
2347 /* Clear out the identification buffer data */
2348 memset(&sci_phy->phy_type, 0, sizeof(sci_phy->phy_type));
2350 /* Initialize the the substate machines */
2351 sci_base_state_machine_construct(&sci_phy->starting_substate_machine,
2353 scic_sds_phy_starting_substates,
2354 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);