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
);