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
=
126 sci_phy
->owning_port
->owning_controller
;
127 int phy_idx
= sci_phy
->phy_index
;
128 struct sci_phy_user_params
*phy_user
=
129 &scic
->user_parameters
.sds1
.phys
[phy_idx
];
130 struct sci_phy_oem_params
*phy_oem
=
131 &scic
->oem_parameters
.sds1
.phys
[phy_idx
];
132 u32 phy_configuration
;
133 struct scic_phy_cap phy_cap
;
134 u32 parity_check
= 0;
135 u32 parity_count
= 0;
136 u32 llctl
, link_rate
;
139 sci_phy
->link_layer_registers
= link_layer_registers
;
141 /* Set our IDENTIFY frame data */
142 #define SCI_END_DEVICE 0x01
144 writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR
) |
145 SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR
) |
146 SCU_SAS_TIID_GEN_BIT(STP_INITIATOR
) |
147 SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST
) |
148 SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE
, SCI_END_DEVICE
),
149 &sci_phy
->link_layer_registers
->transmit_identification
);
151 /* Write the device SAS Address */
153 &sci_phy
->link_layer_registers
->sas_device_name_high
);
154 writel(phy_idx
, &sci_phy
->link_layer_registers
->sas_device_name_low
);
156 /* Write the source SAS Address */
157 writel(phy_oem
->sas_address
.high
,
158 &sci_phy
->link_layer_registers
->source_sas_address_high
);
159 writel(phy_oem
->sas_address
.low
,
160 &sci_phy
->link_layer_registers
->source_sas_address_low
);
162 /* Clear and Set the PHY Identifier */
163 writel(0, &sci_phy
->link_layer_registers
->identify_frame_phy_id
);
164 writel(SCU_SAS_TIPID_GEN_VALUE(ID
, phy_idx
),
165 &sci_phy
->link_layer_registers
->identify_frame_phy_id
);
167 /* Change the initial state of the phy configuration register */
169 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
171 /* Hold OOB state machine in reset */
172 phy_configuration
|= SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
173 writel(phy_configuration
,
174 &sci_phy
->link_layer_registers
->phy_configuration
);
176 /* Configure the SNW capabilities */
179 phy_cap
.gen3_no_ssc
= 1;
180 phy_cap
.gen2_no_ssc
= 1;
181 phy_cap
.gen1_no_ssc
= 1;
182 if (scic
->oem_parameters
.sds1
.controller
.do_enable_ssc
== true) {
183 phy_cap
.gen3_ssc
= 1;
184 phy_cap
.gen2_ssc
= 1;
185 phy_cap
.gen1_ssc
= 1;
189 * The SAS specification indicates that the phy_capabilities that
190 * are transmitted shall have an even parity. Calculate the parity. */
191 parity_check
= phy_cap
.all
;
192 while (parity_check
!= 0) {
193 if (parity_check
& 0x1)
199 * If parity indicates there are an odd number of bits set, then
200 * set the parity bit to 1 in the phy capabilities. */
201 if ((parity_count
% 2) != 0)
204 writel(phy_cap
.all
, &sci_phy
->link_layer_registers
->phy_capabilities
);
206 /* Set the enable spinup period but disable the ability to send
207 * notify enable spinup
209 writel(SCU_ENSPINUP_GEN_VAL(COUNT
,
210 phy_user
->notify_enable_spin_up_insertion_frequency
),
211 &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
213 /* Write the ALIGN Insertion Ferequency for connected phy and
214 * inpendent of connected state
216 clksm_value
= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED
,
217 phy_user
->in_connection_align_insertion_frequency
);
219 clksm_value
|= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL
,
220 phy_user
->align_insertion_frequency
);
222 writel(clksm_value
, &sci_phy
->link_layer_registers
->clock_skew_management
);
224 /* @todo Provide a way to write this register correctly */
226 &sci_phy
->link_layer_registers
->afe_lookup_table_control
);
228 llctl
= SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT
,
229 (u8
)scic
->user_parameters
.sds1
.no_outbound_task_timeout
);
231 switch(phy_user
->max_speed_generation
) {
232 case SCIC_SDS_PARM_GEN3_SPEED
:
233 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3
;
235 case SCIC_SDS_PARM_GEN2_SPEED
:
236 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2
;
239 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1
;
242 llctl
|= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE
, link_rate
);
243 writel(llctl
, &sci_phy
->link_layer_registers
->link_layer_control
);
245 if (is_a0() || is_a2()) {
246 /* Program the max ARB time for the PHY to 700us so we inter-operate with
247 * the PMC expander which shuts down PHYs if the expander PHY generates too
248 * many breaks. This time value will guarantee that the initiator PHY will
249 * generate the break.
251 writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME
,
252 &sci_phy
->link_layer_registers
->maximum_arbitration_wait_timer_timeout
);
256 * Set the link layer hang detection to 500ms (0x1F4) from its default
257 * value of 128ms. Max value is 511 ms.
259 writel(0x1F4, &sci_phy
->link_layer_registers
->link_layer_hang_detection_timeout
);
261 /* We can exit the initial state to the stopped state */
262 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
263 SCI_BASE_PHY_STATE_STOPPED
);
269 * This function will handle the sata SIGNATURE FIS timeout condition. It will
270 * restart the starting substate machine since we dont know what has actually
273 static void scic_sds_phy_sata_timeout(void *phy
)
275 struct scic_sds_phy
*sci_phy
= phy
;
277 dev_dbg(sciphy_to_dev(sci_phy
),
278 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
283 sci_base_state_machine_stop(&sci_phy
->starting_substate_machine
);
285 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
286 SCI_BASE_PHY_STATE_STARTING
);
290 * This method returns the port currently containing this phy. If the phy is
291 * currently contained by the dummy port, then the phy is considered to not
293 * @sci_phy: This parameter specifies the phy for which to retrieve the
296 * This method returns a handle to a port that contains the supplied phy.
297 * NULL This value is returned if the phy is not part of a real
298 * port (i.e. it's contained in the dummy port). !NULL All other
299 * values indicate a handle/pointer to the port containing the phy.
301 struct scic_sds_port
*scic_sds_phy_get_port(
302 struct scic_sds_phy
*sci_phy
)
304 if (scic_sds_port_get_index(sci_phy
->owning_port
) == SCIC_SDS_DUMMY_PORT
)
307 return sci_phy
->owning_port
;
311 * This method will assign a port to the phy object.
312 * @out]: sci_phy This parameter specifies the phy for which to assign a port
317 void scic_sds_phy_set_port(
318 struct scic_sds_phy
*sci_phy
,
319 struct scic_sds_port
*sci_port
)
321 sci_phy
->owning_port
= sci_port
;
323 if (sci_phy
->bcn_received_while_port_unassigned
) {
324 sci_phy
->bcn_received_while_port_unassigned
= false;
325 scic_sds_port_broadcast_change_received(sci_phy
->owning_port
, sci_phy
);
330 * This method will initialize the constructed phy
332 * @link_layer_registers:
336 enum sci_status
scic_sds_phy_initialize(
337 struct scic_sds_phy
*sci_phy
,
338 struct scu_transport_layer_registers __iomem
*transport_layer_registers
,
339 struct scu_link_layer_registers __iomem
*link_layer_registers
)
341 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
342 struct isci_host
*ihost
= scic
->ihost
;
344 /* Create the SIGNATURE FIS Timeout timer for this phy */
345 sci_phy
->sata_timeout_timer
=
349 scic_sds_phy_sata_timeout
);
351 /* Perfrom the initialization of the TL hardware */
352 scic_sds_phy_transport_layer_initialization(
354 transport_layer_registers
);
356 /* Perofrm the initialization of the PE hardware */
357 scic_sds_phy_link_layer_initialization(sci_phy
, link_layer_registers
);
360 * There is nothing that needs to be done in this state just
361 * transition to the stopped state. */
362 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
363 SCI_BASE_PHY_STATE_STOPPED
);
369 * This method assigns the direct attached device ID for this phy.
371 * @sci_phy The phy for which the direct attached device id is to
373 * @device_id The direct attached device ID to assign to the phy.
374 * This will either be the RNi for the device or an invalid RNi if there
375 * is no current device assigned to the phy.
377 void scic_sds_phy_setup_transport(
378 struct scic_sds_phy
*sci_phy
,
383 writel(device_id
, &sci_phy
->transport_layer_registers
->stp_rni
);
386 * The read should guarantee that the first write gets posted
387 * before the next write
389 tl_control
= readl(&sci_phy
->transport_layer_registers
->control
);
390 tl_control
|= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE
);
391 writel(tl_control
, &sci_phy
->transport_layer_registers
->control
);
396 * @sci_phy: The phy object to be suspended.
398 * This function will perform the register reads/writes to suspend the SCU
399 * hardware protocol engine. none
401 static void scic_sds_phy_suspend(
402 struct scic_sds_phy
*sci_phy
)
404 u32 scu_sas_pcfg_value
;
407 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
408 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
);
409 writel(scu_sas_pcfg_value
,
410 &sci_phy
->link_layer_registers
->phy_configuration
);
412 scic_sds_phy_setup_transport(
414 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
);
417 void scic_sds_phy_resume(struct scic_sds_phy
*sci_phy
)
419 u32 scu_sas_pcfg_value
;
422 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
423 scu_sas_pcfg_value
&= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
);
424 writel(scu_sas_pcfg_value
,
425 &sci_phy
->link_layer_registers
->phy_configuration
);
428 void scic_sds_phy_get_sas_address(struct scic_sds_phy
*sci_phy
,
429 struct sci_sas_address
*sas_address
)
431 sas_address
->high
= readl(&sci_phy
->link_layer_registers
->source_sas_address_high
);
432 sas_address
->low
= readl(&sci_phy
->link_layer_registers
->source_sas_address_low
);
435 void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy
*sci_phy
,
436 struct sci_sas_address
*sas_address
)
438 struct sas_identify_frame
*iaf
;
439 struct isci_phy
*iphy
= sci_phy
->iphy
;
441 iaf
= &iphy
->frame_rcvd
.iaf
;
442 memcpy(sas_address
, iaf
->sas_addr
, SAS_ADDR_SIZE
);
445 void scic_sds_phy_get_protocols(
446 struct scic_sds_phy
*sci_phy
,
447 struct sci_sas_identify_address_frame_protocols
*protocols
)
450 (u16
)(readl(&sci_phy
->
451 link_layer_registers
->transmit_identification
) &
455 void scic_sds_phy_get_attached_phy_protocols(
456 struct scic_sds_phy
*sci_phy
,
457 struct sci_sas_identify_address_frame_protocols
*protocols
)
459 protocols
->u
.all
= 0;
461 if (sci_phy
->protocol
== SCIC_SDS_PHY_PROTOCOL_SAS
) {
462 struct isci_phy
*iphy
= sci_phy
->iphy
;
463 struct sas_identify_frame
*iaf
;
465 iaf
= &iphy
->frame_rcvd
.iaf
;
466 memcpy(&protocols
->u
.all
, &iaf
->initiator_bits
, 2);
467 } else if (sci_phy
->protocol
== SCIC_SDS_PHY_PROTOCOL_SATA
)
468 protocols
->u
.bits
.stp_target
= 1;
472 * *****************************************************************************
473 * * SCIC SDS PHY Handler Redirects
474 * ***************************************************************************** */
477 * This method will attempt to start the phy object. This request is only valid
478 * when the phy is in the stopped state
483 enum sci_status
scic_sds_phy_start(struct scic_sds_phy
*sci_phy
)
485 return sci_phy
->state_handlers
->start_handler(sci_phy
);
489 * This method will attempt to stop the phy object.
492 * enum sci_status SCI_SUCCESS if the phy is going to stop SCI_INVALID_STATE
493 * if the phy is not in a valid state to stop
495 enum sci_status
scic_sds_phy_stop(struct scic_sds_phy
*sci_phy
)
497 return sci_phy
->state_handlers
->stop_handler(sci_phy
);
501 * This method will attempt to reset the phy. This request is only valid when
502 * the phy is in an ready state
507 enum sci_status
scic_sds_phy_reset(
508 struct scic_sds_phy
*sci_phy
)
510 return sci_phy
->state_handlers
->reset_handler(sci_phy
);
514 * This method will process the event code received.
520 enum sci_status
scic_sds_phy_event_handler(
521 struct scic_sds_phy
*sci_phy
,
524 return sci_phy
->state_handlers
->event_handler(sci_phy
, event_code
);
528 * This method will process the frame index received.
534 enum sci_status
scic_sds_phy_frame_handler(
535 struct scic_sds_phy
*sci_phy
,
538 return sci_phy
->state_handlers
->frame_handler(sci_phy
, frame_index
);
542 * This method will give the phy permission to consume power
547 enum sci_status
scic_sds_phy_consume_power_handler(
548 struct scic_sds_phy
*sci_phy
)
550 return sci_phy
->state_handlers
->consume_power_handler(sci_phy
);
554 * *****************************************************************************
555 * * SCIC SDS PHY HELPER FUNCTIONS
556 * ***************************************************************************** */
561 * @sci_phy: The phy object that received SAS PHY DETECTED.
563 * This method continues the link training for the phy as if it were a SAS PHY
564 * instead of a SATA PHY. This is done because the completion queue had a SAS
565 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
568 static void scic_sds_phy_start_sas_link_training(
569 struct scic_sds_phy
*sci_phy
)
574 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
575 phy_control
|= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
);
577 &sci_phy
->link_layer_registers
->phy_configuration
);
579 sci_base_state_machine_change_state(
580 &sci_phy
->starting_substate_machine
,
581 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
584 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SAS
;
589 * @sci_phy: The phy object that received a SATA SPINUP HOLD event
591 * This method continues the link training for the phy as if it were a SATA PHY
592 * instead of a SAS PHY. This is done because the completion queue had a SATA
593 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
595 static void scic_sds_phy_start_sata_link_training(
596 struct scic_sds_phy
*sci_phy
)
598 sci_base_state_machine_change_state(
599 &sci_phy
->starting_substate_machine
,
600 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
603 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SATA
;
607 * scic_sds_phy_complete_link_training - perform processing common to
608 * all protocols upon completion of link training.
609 * @sci_phy: This parameter specifies the phy object for which link training
611 * @max_link_rate: This parameter specifies the maximum link rate to be
612 * associated with this phy.
613 * @next_state: This parameter specifies the next state for the phy's starting
617 static void scic_sds_phy_complete_link_training(
618 struct scic_sds_phy
*sci_phy
,
619 enum sas_linkrate max_link_rate
,
622 sci_phy
->max_negotiated_speed
= max_link_rate
;
624 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
628 static void scic_sds_phy_restart_starting_state(
629 struct scic_sds_phy
*sci_phy
)
631 /* Stop the current substate machine */
632 sci_base_state_machine_stop(&sci_phy
->starting_substate_machine
);
634 /* Re-enter the base state machine starting state */
635 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
636 SCI_BASE_PHY_STATE_STARTING
);
639 /* ****************************************************************************
640 * SCIC SDS PHY general handlers
641 ************************************************************************** */
642 static enum sci_status
scic_sds_phy_starting_substate_general_stop_handler(
643 struct scic_sds_phy
*phy
)
645 sci_base_state_machine_stop(&phy
->starting_substate_machine
);
647 sci_base_state_machine_change_state(&phy
->state_machine
,
648 SCI_BASE_PHY_STATE_STOPPED
);
654 * *****************************************************************************
655 * * SCIC SDS PHY EVENT_HANDLERS
656 * ***************************************************************************** */
660 * @phy: This struct scic_sds_phy object which has received an event.
661 * @event_code: This is the event code which the phy object is to decode.
663 * This method is called when an event notification is received for the phy
664 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
665 * decode the event - sas phy detected causes a state transition to the wait
666 * for speed event notification. - any other events log a warning message and
667 * set a failure status enum sci_status SCI_SUCCESS on any valid event notification
668 * SCI_FAILURE on any unexpected event notifation
670 static enum sci_status
scic_sds_phy_starting_substate_await_ossp_event_handler(
671 struct scic_sds_phy
*sci_phy
,
674 u32 result
= SCI_SUCCESS
;
676 switch (scu_get_event_code(event_code
)) {
677 case SCU_EVENT_SAS_PHY_DETECTED
:
678 scic_sds_phy_start_sas_link_training(sci_phy
);
679 sci_phy
->is_in_link_training
= true;
682 case SCU_EVENT_SATA_SPINUP_HOLD
:
683 scic_sds_phy_start_sata_link_training(sci_phy
);
684 sci_phy
->is_in_link_training
= true;
688 dev_dbg(sciphy_to_dev(sci_phy
),
689 "%s: PHY starting substate machine received "
690 "unexpected event_code %x\n",
694 result
= SCI_FAILURE
;
703 * @phy: This struct scic_sds_phy object which has received an event.
704 * @event_code: This is the event code which the phy object is to decode.
706 * This method is called when an event notification is received for the phy
707 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
708 * decode the event - sas phy detected returns us back to this state. - speed
709 * event detected causes a state transition to the wait for iaf. - identify
710 * timeout is an un-expected event and the state machine is restarted. - link
711 * failure events restart the starting state machine - any other events log a
712 * warning message and set a failure status enum sci_status SCI_SUCCESS on any valid
713 * event notification SCI_FAILURE on any unexpected event notifation
715 static enum sci_status
scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler(
716 struct scic_sds_phy
*sci_phy
,
719 u32 result
= SCI_SUCCESS
;
721 switch (scu_get_event_code(event_code
)) {
722 case SCU_EVENT_SAS_PHY_DETECTED
:
724 * Why is this being reported again by the controller?
725 * We would re-enter this state so just stay here */
728 case SCU_EVENT_SAS_15
:
729 case SCU_EVENT_SAS_15_SSC
:
730 scic_sds_phy_complete_link_training(
732 SAS_LINK_RATE_1_5_GBPS
,
733 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
736 case SCU_EVENT_SAS_30
:
737 case SCU_EVENT_SAS_30_SSC
:
738 scic_sds_phy_complete_link_training(
740 SAS_LINK_RATE_3_0_GBPS
,
741 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
744 case SCU_EVENT_SAS_60
:
745 case SCU_EVENT_SAS_60_SSC
:
746 scic_sds_phy_complete_link_training(
748 SAS_LINK_RATE_6_0_GBPS
,
749 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
752 case SCU_EVENT_SATA_SPINUP_HOLD
:
754 * We were doing SAS PHY link training and received a SATA PHY event
755 * continue OOB/SN as if this were a SATA PHY */
756 scic_sds_phy_start_sata_link_training(sci_phy
);
759 case SCU_EVENT_LINK_FAILURE
:
760 /* Link failure change state back to the starting state */
761 scic_sds_phy_restart_starting_state(sci_phy
);
765 dev_warn(sciphy_to_dev(sci_phy
),
766 "%s: PHY starting substate machine received "
767 "unexpected event_code %x\n",
771 result
= SCI_FAILURE
;
780 * @phy: This struct scic_sds_phy object which has received an event.
781 * @event_code: This is the event code which the phy object is to decode.
783 * This method is called when an event notification is received for the phy
784 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. -
785 * decode the event - sas phy detected event backs up the state machine to the
786 * await speed notification. - identify timeout is an un-expected event and the
787 * state machine is restarted. - link failure events restart the starting state
788 * machine - any other events log a warning message and set a failure status
789 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
790 * unexpected event notifation
792 static enum sci_status
scic_sds_phy_starting_substate_await_iaf_uf_event_handler(
793 struct scic_sds_phy
*sci_phy
,
796 u32 result
= SCI_SUCCESS
;
798 switch (scu_get_event_code(event_code
)) {
799 case SCU_EVENT_SAS_PHY_DETECTED
:
800 /* Backup the state machine */
801 scic_sds_phy_start_sas_link_training(sci_phy
);
804 case SCU_EVENT_SATA_SPINUP_HOLD
:
806 * We were doing SAS PHY link training and received a SATA PHY event
807 * continue OOB/SN as if this were a SATA PHY */
808 scic_sds_phy_start_sata_link_training(sci_phy
);
811 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT
:
812 case SCU_EVENT_LINK_FAILURE
:
813 case SCU_EVENT_HARD_RESET_RECEIVED
:
814 /* Start the oob/sn state machine over again */
815 scic_sds_phy_restart_starting_state(sci_phy
);
819 dev_warn(sciphy_to_dev(sci_phy
),
820 "%s: PHY starting substate machine received "
821 "unexpected event_code %x\n",
825 result
= SCI_FAILURE
;
834 * @phy: This struct scic_sds_phy object which has received an event.
835 * @event_code: This is the event code which the phy object is to decode.
837 * This method is called when an event notification is received for the phy
838 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. -
839 * decode the event - link failure events restart the starting state machine -
840 * any other events log a warning message and set a failure status enum sci_status
841 * SCI_SUCCESS on a link failure event SCI_FAILURE on any unexpected event
844 static enum sci_status
scic_sds_phy_starting_substate_await_sas_power_event_handler(
845 struct scic_sds_phy
*sci_phy
,
848 u32 result
= SCI_SUCCESS
;
850 switch (scu_get_event_code(event_code
)) {
851 case SCU_EVENT_LINK_FAILURE
:
852 /* Link failure change state back to the starting state */
853 scic_sds_phy_restart_starting_state(sci_phy
);
857 dev_warn(sciphy_to_dev(sci_phy
),
858 "%s: PHY starting substate machine received unexpected "
863 result
= SCI_FAILURE
;
872 * @phy: This struct scic_sds_phy object which has received an event.
873 * @event_code: This is the event code which the phy object is to decode.
875 * This method is called when an event notification is received for the phy
876 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. -
877 * decode the event - link failure events restart the starting state machine -
878 * sata spinup hold events are ignored since they are expected - any other
879 * events log a warning message and set a failure status enum sci_status SCI_SUCCESS
880 * on a link failure event SCI_FAILURE on any unexpected event notifation
882 static enum sci_status
scic_sds_phy_starting_substate_await_sata_power_event_handler(
883 struct scic_sds_phy
*sci_phy
,
886 u32 result
= SCI_SUCCESS
;
888 switch (scu_get_event_code(event_code
)) {
889 case SCU_EVENT_LINK_FAILURE
:
890 /* Link failure change state back to the starting state */
891 scic_sds_phy_restart_starting_state(sci_phy
);
894 case SCU_EVENT_SATA_SPINUP_HOLD
:
895 /* These events are received every 10ms and are expected while in this state */
898 case SCU_EVENT_SAS_PHY_DETECTED
:
900 * There has been a change in the phy type before OOB/SN for the
901 * SATA finished start down the SAS link traning path. */
902 scic_sds_phy_start_sas_link_training(sci_phy
);
906 dev_warn(sciphy_to_dev(sci_phy
),
907 "%s: PHY starting substate machine received "
908 "unexpected event_code %x\n",
912 result
= SCI_FAILURE
;
920 * scic_sds_phy_starting_substate_await_sata_phy_event_handler -
921 * @phy: This struct scic_sds_phy object which has received an event.
922 * @event_code: This is the event code which the phy object is to decode.
924 * This method is called when an event notification is received for the phy
925 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. -
926 * decode the event - link failure events restart the starting state machine -
927 * sata spinup hold events are ignored since they are expected - sata phy
928 * detected event change to the wait speed event - any other events log a
929 * warning message and set a failure status enum sci_status SCI_SUCCESS on a link
930 * failure event SCI_FAILURE on any unexpected event notifation
932 static enum sci_status
scic_sds_phy_starting_substate_await_sata_phy_event_handler(
933 struct scic_sds_phy
*sci_phy
, u32 event_code
)
935 u32 result
= SCI_SUCCESS
;
937 switch (scu_get_event_code(event_code
)) {
938 case SCU_EVENT_LINK_FAILURE
:
939 /* Link failure change state back to the starting state */
940 scic_sds_phy_restart_starting_state(sci_phy
);
943 case SCU_EVENT_SATA_SPINUP_HOLD
:
944 /* These events might be received since we dont know how many may be in
945 * the completion queue while waiting for power
949 case SCU_EVENT_SATA_PHY_DETECTED
:
950 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SATA
;
952 /* We have received the SATA PHY notification change state */
953 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
954 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
957 case SCU_EVENT_SAS_PHY_DETECTED
:
958 /* There has been a change in the phy type before OOB/SN for the
959 * SATA finished start down the SAS link traning path.
961 scic_sds_phy_start_sas_link_training(sci_phy
);
965 dev_warn(sciphy_to_dev(sci_phy
),
966 "%s: PHY starting substate machine received "
967 "unexpected event_code %x\n",
971 result
= SCI_FAILURE
;
980 * @phy: This struct scic_sds_phy object which has received an event.
981 * @event_code: This is the event code which the phy object is to decode.
983 * This method is called when an event notification is received for the phy
984 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
985 * - decode the event - sata phy detected returns us back to this state. -
986 * speed event detected causes a state transition to the wait for signature. -
987 * link failure events restart the starting state machine - any other events
988 * log a warning message and set a failure status enum sci_status SCI_SUCCESS on any
989 * valid event notification SCI_FAILURE on any unexpected event notifation
991 static enum sci_status
scic_sds_phy_starting_substate_await_sata_speed_event_handler(
992 struct scic_sds_phy
*sci_phy
,
995 u32 result
= SCI_SUCCESS
;
997 switch (scu_get_event_code(event_code
)) {
998 case SCU_EVENT_SATA_PHY_DETECTED
:
1000 * The hardware reports multiple SATA PHY detected events
1001 * ignore the extras */
1004 case SCU_EVENT_SATA_15
:
1005 case SCU_EVENT_SATA_15_SSC
:
1006 scic_sds_phy_complete_link_training(
1008 SAS_LINK_RATE_1_5_GBPS
,
1009 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
1012 case SCU_EVENT_SATA_30
:
1013 case SCU_EVENT_SATA_30_SSC
:
1014 scic_sds_phy_complete_link_training(
1016 SAS_LINK_RATE_3_0_GBPS
,
1017 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
1020 case SCU_EVENT_SATA_60
:
1021 case SCU_EVENT_SATA_60_SSC
:
1022 scic_sds_phy_complete_link_training(
1024 SAS_LINK_RATE_6_0_GBPS
,
1025 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
1028 case SCU_EVENT_LINK_FAILURE
:
1029 /* Link failure change state back to the starting state */
1030 scic_sds_phy_restart_starting_state(sci_phy
);
1033 case SCU_EVENT_SAS_PHY_DETECTED
:
1035 * There has been a change in the phy type before OOB/SN for the
1036 * SATA finished start down the SAS link traning path. */
1037 scic_sds_phy_start_sas_link_training(sci_phy
);
1041 dev_warn(sciphy_to_dev(sci_phy
),
1042 "%s: PHY starting substate machine received "
1043 "unexpected event_code %x\n",
1047 result
= SCI_FAILURE
;
1055 * scic_sds_phy_starting_substate_await_sig_fis_event_handler -
1056 * @phy: This struct scic_sds_phy object which has received an event.
1057 * @event_code: This is the event code which the phy object is to decode.
1059 * This method is called when an event notification is received for the phy
1060 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. -
1061 * decode the event - sas phy detected event backs up the state machine to the
1062 * await speed notification. - identify timeout is an un-expected event and the
1063 * state machine is restarted. - link failure events restart the starting state
1064 * machine - any other events log a warning message and set a failure status
1065 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
1066 * unexpected event notifation
1068 static enum sci_status
scic_sds_phy_starting_substate_await_sig_fis_event_handler(
1069 struct scic_sds_phy
*sci_phy
, u32 event_code
)
1071 u32 result
= SCI_SUCCESS
;
1073 switch (scu_get_event_code(event_code
)) {
1074 case SCU_EVENT_SATA_PHY_DETECTED
:
1075 /* Backup the state machine */
1076 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1077 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
1080 case SCU_EVENT_LINK_FAILURE
:
1081 /* Link failure change state back to the starting state */
1082 scic_sds_phy_restart_starting_state(sci_phy
);
1086 dev_warn(sciphy_to_dev(sci_phy
),
1087 "%s: PHY starting substate machine received "
1088 "unexpected event_code %x\n",
1092 result
= SCI_FAILURE
;
1101 * *****************************************************************************
1102 * * SCIC SDS PHY FRAME_HANDLERS
1103 * ***************************************************************************** */
1107 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1109 * @frame_index: This is the index of the unsolicited frame which was received
1112 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1113 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Get the UF Header - If the UF
1114 * is an IAF - Copy IAF data to local phy object IAF data buffer. - Change
1115 * starting substate to wait power. - else - log warning message of unexpected
1116 * unsolicted frame - release frame buffer enum sci_status SCI_SUCCESS
1118 static enum sci_status
scic_sds_phy_starting_substate_await_iaf_uf_frame_handler(
1119 struct scic_sds_phy
*sci_phy
, u32 frame_index
)
1121 enum sci_status result
;
1123 struct sas_identify_frame
*identify_frame
;
1124 struct isci_phy
*iphy
= sci_phy
->iphy
;
1126 result
= scic_sds_unsolicited_frame_control_get_header(
1127 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1129 (void **)&frame_words
);
1131 if (result
!= SCI_SUCCESS
) {
1135 frame_words
[0] = SCIC_SWAP_DWORD(frame_words
[0]);
1136 identify_frame
= (struct sas_identify_frame
*)frame_words
;
1138 if (identify_frame
->frame_type
== 0) {
1141 /* Byte swap the rest of the frame so we can make
1142 * a copy of the buffer
1144 frame_words
[1] = SCIC_SWAP_DWORD(frame_words
[1]);
1145 frame_words
[2] = SCIC_SWAP_DWORD(frame_words
[2]);
1146 frame_words
[3] = SCIC_SWAP_DWORD(frame_words
[3]);
1147 frame_words
[4] = SCIC_SWAP_DWORD(frame_words
[4]);
1148 frame_words
[5] = SCIC_SWAP_DWORD(frame_words
[5]);
1150 memcpy(&iphy
->frame_rcvd
.iaf
, identify_frame
, sizeof(*identify_frame
));
1152 if (identify_frame
->smp_tport
) {
1153 /* We got the IAF for an expander PHY go to the final state since
1154 * there are no power requirements for expander phys.
1156 state
= SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
;
1158 /* We got the IAF we can now go to the await spinup semaphore state */
1159 state
= SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
;
1161 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1163 result
= SCI_SUCCESS
;
1165 dev_warn(sciphy_to_dev(sci_phy
),
1166 "%s: PHY starting substate machine received "
1167 "unexpected frame id %x\n",
1171 /* Regardless of the result release this frame since we are done with it */
1172 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy
),
1180 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1182 * @frame_index: This is the index of the unsolicited frame which was received
1185 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1186 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Get the UF Header - If
1187 * the UF is an SIGNATURE FIS - Copy IAF data to local phy object SIGNATURE FIS
1188 * data buffer. - else - log warning message of unexpected unsolicted frame -
1189 * release frame buffer enum sci_status SCI_SUCCESS Must decode the SIGNATURE FIS
1192 static enum sci_status
scic_sds_phy_starting_substate_await_sig_fis_frame_handler(
1193 struct scic_sds_phy
*sci_phy
,
1196 enum sci_status result
;
1197 struct dev_to_host_fis
*frame_header
;
1198 u32
*fis_frame_data
;
1199 struct isci_phy
*iphy
= sci_phy
->iphy
;
1201 result
= scic_sds_unsolicited_frame_control_get_header(
1202 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1204 (void **)&frame_header
);
1206 if (result
!= SCI_SUCCESS
)
1209 if ((frame_header
->fis_type
== FIS_REGD2H
) &&
1210 !(frame_header
->status
& ATA_BUSY
)) {
1211 scic_sds_unsolicited_frame_control_get_buffer(
1212 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1214 (void **)&fis_frame_data
);
1216 scic_sds_controller_copy_sata_response(&iphy
->frame_rcvd
.fis
,
1220 /* got IAF we can now go to the await spinup semaphore state */
1221 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1222 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1224 result
= SCI_SUCCESS
;
1226 dev_warn(sciphy_to_dev(sci_phy
),
1227 "%s: PHY starting substate machine received "
1228 "unexpected frame id %x\n",
1232 /* Regardless of the result we are done with this frame with it */
1233 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy
),
1240 * *****************************************************************************
1241 * * SCIC SDS PHY POWER_HANDLERS
1242 * ***************************************************************************** */
1245 * This method is called by the struct scic_sds_controller when the phy object is
1246 * granted power. - The notify enable spinups are turned on for this phy object
1247 * - The phy state machine is transitioned to the
1248 * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. enum sci_status SCI_SUCCESS
1250 static enum sci_status
scic_sds_phy_starting_substate_await_sas_power_consume_power_handler(
1251 struct scic_sds_phy
*sci_phy
)
1255 enable_spinup
= readl(&sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1256 enable_spinup
|= SCU_ENSPINUP_GEN_BIT(ENABLE
);
1257 writel(enable_spinup
, &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1259 /* Change state to the final state this substate machine has run to completion */
1260 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1261 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1267 * This method is called by the struct scic_sds_controller when the phy object is
1268 * granted power. - The phy state machine is transitioned to the
1269 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. enum sci_status SCI_SUCCESS
1271 static enum sci_status
scic_sds_phy_starting_substate_await_sata_power_consume_power_handler(
1272 struct scic_sds_phy
*sci_phy
)
1274 u32 scu_sas_pcfg_value
;
1276 /* Release the spinup hold state and reset the OOB state machine */
1277 scu_sas_pcfg_value
=
1278 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
1279 scu_sas_pcfg_value
&=
1280 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
));
1281 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
1282 writel(scu_sas_pcfg_value
,
1283 &sci_phy
->link_layer_registers
->phy_configuration
);
1285 /* Now restart the OOB operation */
1286 scu_sas_pcfg_value
&= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
1287 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
1288 writel(scu_sas_pcfg_value
,
1289 &sci_phy
->link_layer_registers
->phy_configuration
);
1291 /* Change state to the final state this substate machine has run to completion */
1292 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1293 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
);
1298 static enum sci_status
default_phy_handler(struct scic_sds_phy
*sci_phy
,
1301 dev_dbg(sciphy_to_dev(sci_phy
),
1302 "%s: in wrong state: %d\n", func
,
1303 sci_base_state_machine_get_state(&sci_phy
->state_machine
));
1304 return SCI_FAILURE_INVALID_STATE
;
1307 static enum sci_status
1308 scic_sds_phy_default_start_handler(struct scic_sds_phy
*sci_phy
)
1310 return default_phy_handler(sci_phy
, __func__
);
1313 static enum sci_status
1314 scic_sds_phy_default_stop_handler(struct scic_sds_phy
*sci_phy
)
1316 return default_phy_handler(sci_phy
, __func__
);
1319 static enum sci_status
1320 scic_sds_phy_default_reset_handler(struct scic_sds_phy
*sci_phy
)
1322 return default_phy_handler(sci_phy
, __func__
);
1325 static enum sci_status
1326 scic_sds_phy_default_destroy_handler(struct scic_sds_phy
*sci_phy
)
1328 return default_phy_handler(sci_phy
, __func__
);
1331 static enum sci_status
1332 scic_sds_phy_default_frame_handler(struct scic_sds_phy
*sci_phy
,
1335 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
1337 default_phy_handler(sci_phy
, __func__
);
1338 scic_sds_controller_release_frame(scic
, frame_index
);
1340 return SCI_FAILURE_INVALID_STATE
;
1343 static enum sci_status
1344 scic_sds_phy_default_event_handler(struct scic_sds_phy
*sci_phy
,
1347 return default_phy_handler(sci_phy
, __func__
);
1350 static enum sci_status
1351 scic_sds_phy_default_consume_power_handler(struct scic_sds_phy
*sci_phy
)
1353 return default_phy_handler(sci_phy
, __func__
);
1358 static const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table
[] = {
1359 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
] = {
1360 .start_handler
= scic_sds_phy_default_start_handler
,
1361 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1362 .reset_handler
= scic_sds_phy_default_reset_handler
,
1363 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1364 .frame_handler
= scic_sds_phy_default_frame_handler
,
1365 .event_handler
= scic_sds_phy_default_event_handler
,
1366 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1368 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
] = {
1369 .start_handler
= scic_sds_phy_default_start_handler
,
1370 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1371 .reset_handler
= scic_sds_phy_default_reset_handler
,
1372 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1373 .frame_handler
= scic_sds_phy_default_frame_handler
,
1374 .event_handler
= scic_sds_phy_starting_substate_await_ossp_event_handler
,
1375 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1377 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
] = {
1378 .start_handler
= scic_sds_phy_default_start_handler
,
1379 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1380 .reset_handler
= scic_sds_phy_default_reset_handler
,
1381 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1382 .frame_handler
= scic_sds_phy_default_frame_handler
,
1383 .event_handler
= scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler
,
1384 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1386 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
] = {
1387 .start_handler
= scic_sds_phy_default_start_handler
,
1388 .stop_handler
= scic_sds_phy_default_stop_handler
,
1389 .reset_handler
= scic_sds_phy_default_reset_handler
,
1390 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1391 .frame_handler
= scic_sds_phy_starting_substate_await_iaf_uf_frame_handler
,
1392 .event_handler
= scic_sds_phy_starting_substate_await_iaf_uf_event_handler
,
1393 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1395 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
] = {
1396 .start_handler
= scic_sds_phy_default_start_handler
,
1397 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1398 .reset_handler
= scic_sds_phy_default_reset_handler
,
1399 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1400 .frame_handler
= scic_sds_phy_default_frame_handler
,
1401 .event_handler
= scic_sds_phy_starting_substate_await_sas_power_event_handler
,
1402 .consume_power_handler
= scic_sds_phy_starting_substate_await_sas_power_consume_power_handler
1404 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
] = {
1405 .start_handler
= scic_sds_phy_default_start_handler
,
1406 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1407 .reset_handler
= scic_sds_phy_default_reset_handler
,
1408 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1409 .frame_handler
= scic_sds_phy_default_frame_handler
,
1410 .event_handler
= scic_sds_phy_starting_substate_await_sata_power_event_handler
,
1411 .consume_power_handler
= scic_sds_phy_starting_substate_await_sata_power_consume_power_handler
1413 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
] = {
1414 .start_handler
= scic_sds_phy_default_start_handler
,
1415 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1416 .reset_handler
= scic_sds_phy_default_reset_handler
,
1417 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1418 .frame_handler
= scic_sds_phy_default_frame_handler
,
1419 .event_handler
= scic_sds_phy_starting_substate_await_sata_phy_event_handler
,
1420 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1422 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
] = {
1423 .start_handler
= scic_sds_phy_default_start_handler
,
1424 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1425 .reset_handler
= scic_sds_phy_default_reset_handler
,
1426 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1427 .frame_handler
= scic_sds_phy_default_frame_handler
,
1428 .event_handler
= scic_sds_phy_starting_substate_await_sata_speed_event_handler
,
1429 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1431 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
] = {
1432 .start_handler
= scic_sds_phy_default_start_handler
,
1433 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1434 .reset_handler
= scic_sds_phy_default_reset_handler
,
1435 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1436 .frame_handler
= scic_sds_phy_starting_substate_await_sig_fis_frame_handler
,
1437 .event_handler
= scic_sds_phy_starting_substate_await_sig_fis_event_handler
,
1438 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1440 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
] = {
1441 .start_handler
= scic_sds_phy_default_start_handler
,
1442 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1443 .reset_handler
= scic_sds_phy_default_reset_handler
,
1444 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1445 .frame_handler
= scic_sds_phy_default_frame_handler
,
1446 .event_handler
= scic_sds_phy_default_event_handler
,
1447 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1452 * scic_sds_phy_set_starting_substate_handlers() -
1454 * This macro sets the starting substate handlers by state_id
1456 #define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \
1457 scic_sds_phy_set_state_handlers(\
1459 &scic_sds_phy_starting_substate_handler_table[(state_id)] \
1463 * ****************************************************************************
1464 * * PHY STARTING SUBSTATE METHODS
1465 * **************************************************************************** */
1468 * scic_sds_phy_starting_initial_substate_enter -
1469 * @object: This is the object which is cast to a struct scic_sds_phy object.
1471 * This method will perform the actions required by the struct scic_sds_phy on
1472 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL. - The initial state
1473 * handlers are put in place for the struct scic_sds_phy object. - The state is
1474 * changed to the wait phy type event notification. none
1476 static void scic_sds_phy_starting_initial_substate_enter(void *object
)
1478 struct scic_sds_phy
*sci_phy
= object
;
1480 scic_sds_phy_set_starting_substate_handlers(
1481 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
);
1483 /* This is just an temporary state go off to the starting state */
1484 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1485 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
);
1490 * @object: This is the object which is cast to a struct scic_sds_phy object.
1492 * This method will perform the actions required by the struct scic_sds_phy on
1493 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_PHY_TYPE_EN. - Set the
1494 * struct scic_sds_phy object state handlers for this state. none
1496 static void scic_sds_phy_starting_await_ossp_en_substate_enter(void *object
)
1498 struct scic_sds_phy
*sci_phy
= object
;
1500 scic_sds_phy_set_starting_substate_handlers(
1501 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1507 * @object: This is the object which is cast to a struct scic_sds_phy object.
1509 * This method will perform the actions required by the struct scic_sds_phy on
1510 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - Set the
1511 * struct scic_sds_phy object state handlers for this state. none
1513 static void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
1516 struct scic_sds_phy
*sci_phy
= object
;
1518 scic_sds_phy_set_starting_substate_handlers(
1519 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
1525 * @object: This is the object which is cast to a struct scic_sds_phy object.
1527 * This method will perform the actions required by the struct scic_sds_phy on
1528 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Set the
1529 * struct scic_sds_phy object state handlers for this state. none
1531 static void scic_sds_phy_starting_await_iaf_uf_substate_enter(void *object
)
1533 struct scic_sds_phy
*sci_phy
= object
;
1535 scic_sds_phy_set_starting_substate_handlers(
1536 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
1542 * @object: This is the object which is cast to a struct scic_sds_phy object.
1544 * This method will perform the actions required by the struct scic_sds_phy on
1545 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Set the
1546 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1547 * the power control queue none
1549 static void scic_sds_phy_starting_await_sas_power_substate_enter(void *object
)
1551 struct scic_sds_phy
*sci_phy
= object
;
1553 scic_sds_phy_set_starting_substate_handlers(
1554 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1557 scic_sds_controller_power_control_queue_insert(
1558 scic_sds_phy_get_controller(sci_phy
),
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 exiting
1568 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Remove the
1569 * struct scic_sds_phy object from the power control queue. none
1571 static void scic_sds_phy_starting_await_sas_power_substate_exit(void *object
)
1573 struct scic_sds_phy
*sci_phy
= object
;
1575 scic_sds_controller_power_control_queue_remove(
1576 scic_sds_phy_get_controller(sci_phy
), sci_phy
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_SATA_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_sata_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_SATA_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_SATA_POWER. - Remove the
1609 * struct scic_sds_phy object from the power control queue. none
1611 static void scic_sds_phy_starting_await_sata_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
),
1623 * @object: This is the object which is cast to a struct scic_sds_phy object.
1625 * This function will perform the actions required by the struct scic_sds_phy on
1626 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. - Set the
1627 * struct scic_sds_phy object state handlers for this state. none
1629 static void scic_sds_phy_starting_await_sata_phy_substate_enter(void *object
)
1631 struct scic_sds_phy
*sci_phy
= object
;
1633 scic_sds_phy_set_starting_substate_handlers(
1635 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
);
1637 isci_timer_start(sci_phy
->sata_timeout_timer
,
1638 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
);
1643 * @object: This is the object which is cast to a struct scic_sds_phy object.
1645 * This method will perform the actions required by the struct scic_sds_phy
1647 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1648 * that was started on entry to await sata phy event notification none
1650 static inline void scic_sds_phy_starting_await_sata_phy_substate_exit(
1653 struct scic_sds_phy
*sci_phy
= object
;
1655 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1660 * @object: This is the object which is cast to a struct scic_sds_phy object.
1662 * This method will perform the actions required by the struct scic_sds_phy on
1663 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - Set the
1664 * struct scic_sds_phy object state handlers for this state. none
1666 static void scic_sds_phy_starting_await_sata_speed_substate_enter(void *object
)
1668 struct scic_sds_phy
*sci_phy
= object
;
1670 scic_sds_phy_set_starting_substate_handlers(
1672 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
1674 isci_timer_start(sci_phy
->sata_timeout_timer
,
1675 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
);
1680 * @object: This is the object which is cast to a struct scic_sds_phy object.
1682 * This function will perform the actions required by the
1683 * struct scic_sds_phy on exiting
1684 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1685 * that was started on entry to await sata phy event notification none
1687 static inline void scic_sds_phy_starting_await_sata_speed_substate_exit(
1690 struct scic_sds_phy
*sci_phy
= object
;
1692 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1697 * @object: This is the object which is cast to a struct scic_sds_phy object.
1699 * This function will perform the actions required by the struct scic_sds_phy on
1700 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Set the
1701 * struct scic_sds_phy object state handlers for this state.
1702 * - Start the SIGNATURE FIS
1703 * timeout timer none
1705 static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(void *object
)
1707 bool continue_to_ready_state
;
1708 struct scic_sds_phy
*sci_phy
= object
;
1710 scic_sds_phy_set_starting_substate_handlers(
1712 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
1714 continue_to_ready_state
= scic_sds_port_link_detected(
1715 sci_phy
->owning_port
,
1718 if (continue_to_ready_state
) {
1720 * Clear the PE suspend condition so we can actually
1722 * The hardware will not respond to the XRDY until the PE
1723 * suspend condition is cleared.
1725 scic_sds_phy_resume(sci_phy
);
1727 isci_timer_start(sci_phy
->sata_timeout_timer
,
1728 SCIC_SDS_SIGNATURE_FIS_TIMEOUT
);
1730 sci_phy
->is_in_link_training
= false;
1735 * @object: This is the object which is cast to a struct scic_sds_phy object.
1737 * This function will perform the actions required by the
1738 * struct scic_sds_phy on exiting
1739 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Stop the SIGNATURE
1740 * FIS timeout timer. none
1742 static inline void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(
1745 struct scic_sds_phy
*sci_phy
= object
;
1747 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1752 * @object: This is the object which is cast to a struct scic_sds_phy object.
1754 * This method will perform the actions required by the struct scic_sds_phy on
1755 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. - Set the struct scic_sds_phy
1756 * object state handlers for this state. - Change base state machine to the
1759 static void scic_sds_phy_starting_final_substate_enter(void *object
)
1761 struct scic_sds_phy
*sci_phy
= object
;
1763 scic_sds_phy_set_starting_substate_handlers(sci_phy
,
1764 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1766 /* State machine has run to completion so exit out and change
1767 * the base state machine to the ready state
1769 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1770 SCI_BASE_PHY_STATE_READY
);
1773 /* --------------------------------------------------------------------------- */
1775 static const struct sci_base_state scic_sds_phy_starting_substates
[] = {
1776 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
] = {
1777 .enter_state
= scic_sds_phy_starting_initial_substate_enter
,
1779 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
] = {
1780 .enter_state
= scic_sds_phy_starting_await_ossp_en_substate_enter
,
1782 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
] = {
1783 .enter_state
= scic_sds_phy_starting_await_sas_speed_en_substate_enter
,
1785 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
] = {
1786 .enter_state
= scic_sds_phy_starting_await_iaf_uf_substate_enter
,
1788 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
] = {
1789 .enter_state
= scic_sds_phy_starting_await_sas_power_substate_enter
,
1790 .exit_state
= scic_sds_phy_starting_await_sas_power_substate_exit
,
1792 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
] = {
1793 .enter_state
= scic_sds_phy_starting_await_sata_power_substate_enter
,
1794 .exit_state
= scic_sds_phy_starting_await_sata_power_substate_exit
1796 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
] = {
1797 .enter_state
= scic_sds_phy_starting_await_sata_phy_substate_enter
,
1798 .exit_state
= scic_sds_phy_starting_await_sata_phy_substate_exit
1800 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
] = {
1801 .enter_state
= scic_sds_phy_starting_await_sata_speed_substate_enter
,
1802 .exit_state
= scic_sds_phy_starting_await_sata_speed_substate_exit
1804 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
] = {
1805 .enter_state
= scic_sds_phy_starting_await_sig_fis_uf_substate_enter
,
1806 .exit_state
= scic_sds_phy_starting_await_sig_fis_uf_substate_exit
1808 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
] = {
1809 .enter_state
= scic_sds_phy_starting_final_substate_enter
,
1814 * This method takes the struct scic_sds_phy from a stopped state and
1815 * attempts to start it. - The phy state machine is transitioned to the
1816 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
1818 static enum sci_status
1819 scic_sds_phy_stopped_state_start_handler(struct scic_sds_phy
*sci_phy
)
1821 struct isci_host
*ihost
;
1822 struct scic_sds_controller
*scic
;
1824 scic
= scic_sds_phy_get_controller(sci_phy
),
1825 ihost
= scic
->ihost
;
1827 /* Create the SIGNATURE FIS Timeout timer for this phy */
1828 sci_phy
->sata_timeout_timer
= isci_timer_create(ihost
, sci_phy
,
1829 scic_sds_phy_sata_timeout
);
1831 if (sci_phy
->sata_timeout_timer
)
1832 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1833 SCI_BASE_PHY_STATE_STARTING
);
1838 static enum sci_status
1839 scic_sds_phy_stopped_state_destroy_handler(struct scic_sds_phy
*sci_phy
)
1844 static enum sci_status
1845 scic_sds_phy_ready_state_stop_handler(struct scic_sds_phy
*sci_phy
)
1847 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1848 SCI_BASE_PHY_STATE_STOPPED
);
1853 static enum sci_status
1854 scic_sds_phy_ready_state_reset_handler(struct scic_sds_phy
*sci_phy
)
1856 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1857 SCI_BASE_PHY_STATE_RESETTING
);
1863 * scic_sds_phy_ready_state_event_handler -
1864 * @phy: This is the struct scic_sds_phy object which has received the event.
1866 * This method request the struct scic_sds_phy handle the received event. The only
1867 * event that we are interested in while in the ready state is the link failure
1868 * event. - decoded event is a link failure - transition the struct scic_sds_phy back
1869 * to the SCI_BASE_PHY_STATE_STARTING state. - any other event received will
1870 * report a warning message enum sci_status SCI_SUCCESS if the event received is a
1871 * link failure SCI_FAILURE_INVALID_STATE for any other event received.
1873 static enum sci_status
scic_sds_phy_ready_state_event_handler(struct scic_sds_phy
*sci_phy
,
1876 enum sci_status result
= SCI_FAILURE
;
1878 switch (scu_get_event_code(event_code
)) {
1879 case SCU_EVENT_LINK_FAILURE
:
1880 /* Link failure change state back to the starting state */
1881 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1882 SCI_BASE_PHY_STATE_STARTING
);
1883 result
= SCI_SUCCESS
;
1886 case SCU_EVENT_BROADCAST_CHANGE
:
1887 /* Broadcast change received. Notify the port. */
1888 if (scic_sds_phy_get_port(sci_phy
) != NULL
)
1889 scic_sds_port_broadcast_change_received(sci_phy
->owning_port
, sci_phy
);
1891 sci_phy
->bcn_received_while_port_unassigned
= true;
1895 dev_warn(sciphy_to_dev(sci_phy
),
1896 "%sP SCIC PHY 0x%p ready state machine received "
1897 "unexpected event_code %x\n",
1898 __func__
, sci_phy
, event_code
);
1900 result
= SCI_FAILURE_INVALID_STATE
;
1907 static enum sci_status
scic_sds_phy_resetting_state_event_handler(struct scic_sds_phy
*sci_phy
,
1910 enum sci_status result
= SCI_FAILURE
;
1912 switch (scu_get_event_code(event_code
)) {
1913 case SCU_EVENT_HARD_RESET_TRANSMITTED
:
1914 /* Link failure change state back to the starting state */
1915 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1916 SCI_BASE_PHY_STATE_STARTING
);
1917 result
= SCI_SUCCESS
;
1921 dev_warn(sciphy_to_dev(sci_phy
),
1922 "%s: SCIC PHY 0x%p resetting state machine received "
1923 "unexpected event_code %x\n",
1924 __func__
, sci_phy
, event_code
);
1926 result
= SCI_FAILURE_INVALID_STATE
;
1933 /* --------------------------------------------------------------------------- */
1935 static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table
[] = {
1936 [SCI_BASE_PHY_STATE_INITIAL
] = {
1937 .start_handler
= scic_sds_phy_default_start_handler
,
1938 .stop_handler
= scic_sds_phy_default_stop_handler
,
1939 .reset_handler
= scic_sds_phy_default_reset_handler
,
1940 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1941 .frame_handler
= scic_sds_phy_default_frame_handler
,
1942 .event_handler
= scic_sds_phy_default_event_handler
,
1943 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1945 [SCI_BASE_PHY_STATE_STOPPED
] = {
1946 .start_handler
= scic_sds_phy_stopped_state_start_handler
,
1947 .stop_handler
= scic_sds_phy_default_stop_handler
,
1948 .reset_handler
= scic_sds_phy_default_reset_handler
,
1949 .destruct_handler
= scic_sds_phy_stopped_state_destroy_handler
,
1950 .frame_handler
= scic_sds_phy_default_frame_handler
,
1951 .event_handler
= scic_sds_phy_default_event_handler
,
1952 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1954 [SCI_BASE_PHY_STATE_STARTING
] = {
1955 .start_handler
= scic_sds_phy_default_start_handler
,
1956 .stop_handler
= scic_sds_phy_default_stop_handler
,
1957 .reset_handler
= scic_sds_phy_default_reset_handler
,
1958 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1959 .frame_handler
= scic_sds_phy_default_frame_handler
,
1960 .event_handler
= scic_sds_phy_default_event_handler
,
1961 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1963 [SCI_BASE_PHY_STATE_READY
] = {
1964 .start_handler
= scic_sds_phy_default_start_handler
,
1965 .stop_handler
= scic_sds_phy_ready_state_stop_handler
,
1966 .reset_handler
= scic_sds_phy_ready_state_reset_handler
,
1967 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1968 .frame_handler
= scic_sds_phy_default_frame_handler
,
1969 .event_handler
= scic_sds_phy_ready_state_event_handler
,
1970 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1972 [SCI_BASE_PHY_STATE_RESETTING
] = {
1973 .start_handler
= scic_sds_phy_default_start_handler
,
1974 .stop_handler
= scic_sds_phy_default_stop_handler
,
1975 .reset_handler
= scic_sds_phy_default_reset_handler
,
1976 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1977 .frame_handler
= scic_sds_phy_default_frame_handler
,
1978 .event_handler
= scic_sds_phy_resetting_state_event_handler
,
1979 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1981 [SCI_BASE_PHY_STATE_FINAL
] = {
1982 .start_handler
= scic_sds_phy_default_start_handler
,
1983 .stop_handler
= scic_sds_phy_default_stop_handler
,
1984 .reset_handler
= scic_sds_phy_default_reset_handler
,
1985 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1986 .frame_handler
= scic_sds_phy_default_frame_handler
,
1987 .event_handler
= scic_sds_phy_default_event_handler
,
1988 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1993 * ****************************************************************************
1994 * * PHY STATE PRIVATE METHODS
1995 * **************************************************************************** */
1999 * @sci_phy: This is the struct scic_sds_phy object to stop.
2001 * This method will stop the struct scic_sds_phy object. This does not reset the
2002 * protocol engine it just suspends it and places it in a state where it will
2003 * not cause the end device to power up. none
2005 static void scu_link_layer_stop_protocol_engine(
2006 struct scic_sds_phy
*sci_phy
)
2008 u32 scu_sas_pcfg_value
;
2009 u32 enable_spinup_value
;
2011 /* Suspend the protocol engine and place it in a sata spinup hold state */
2012 scu_sas_pcfg_value
=
2013 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
2014 scu_sas_pcfg_value
|=
2015 (SCU_SAS_PCFG_GEN_BIT(OOB_RESET
) |
2016 SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
) |
2017 SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
));
2018 writel(scu_sas_pcfg_value
,
2019 &sci_phy
->link_layer_registers
->phy_configuration
);
2021 /* Disable the notify enable spinup primitives */
2022 enable_spinup_value
= readl(&sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
2023 enable_spinup_value
&= ~SCU_ENSPINUP_GEN_BIT(ENABLE
);
2024 writel(enable_spinup_value
, &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
2030 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
2032 static void scu_link_layer_start_oob(
2033 struct scic_sds_phy
*sci_phy
)
2035 u32 scu_sas_pcfg_value
;
2037 scu_sas_pcfg_value
=
2038 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
2039 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
2040 scu_sas_pcfg_value
&=
2041 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET
) |
2042 SCU_SAS_PCFG_GEN_BIT(HARD_RESET
));
2043 writel(scu_sas_pcfg_value
,
2044 &sci_phy
->link_layer_registers
->phy_configuration
);
2050 * This method will transmit a hard reset request on the specified phy. The SCU
2051 * hardware requires that we reset the OOB state machine and set the hard reset
2052 * bit in the phy configuration register. We then must start OOB over with the
2053 * hard reset bit set.
2055 static void scu_link_layer_tx_hard_reset(
2056 struct scic_sds_phy
*sci_phy
)
2058 u32 phy_configuration_value
;
2061 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
2062 * to the starting state. */
2063 phy_configuration_value
=
2064 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
2065 phy_configuration_value
|=
2066 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET
) |
2067 SCU_SAS_PCFG_GEN_BIT(OOB_RESET
));
2068 writel(phy_configuration_value
,
2069 &sci_phy
->link_layer_registers
->phy_configuration
);
2071 /* Now take the OOB state machine out of reset */
2072 phy_configuration_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
2073 phy_configuration_value
&= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
2074 writel(phy_configuration_value
,
2075 &sci_phy
->link_layer_registers
->phy_configuration
);
2079 * ****************************************************************************
2080 * * PHY BASE STATE METHODS
2081 * **************************************************************************** */
2085 * @object: This is the object which is cast to a struct scic_sds_phy object.
2087 * This method will perform the actions required by the struct scic_sds_phy on
2088 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2089 * handlers for the phy object base state machine initial state. none
2091 static void scic_sds_phy_initial_state_enter(void *object
)
2093 struct scic_sds_phy
*sci_phy
= object
;
2095 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_INITIAL
);
2100 * @object: This is the object which is cast to a struct scic_sds_phy object.
2102 * This function will perform the actions required by the struct scic_sds_phy on
2103 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2104 * handlers for the phy object base state machine initial state. - The SCU
2105 * hardware is requested to stop the protocol engine. none
2107 static void scic_sds_phy_stopped_state_enter(void *object
)
2109 struct scic_sds_phy
*sci_phy
= object
;
2110 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
2111 struct isci_host
*ihost
= scic
->ihost
;
2114 * @todo We need to get to the controller to place this PE in a
2118 scic_sds_phy_set_base_state_handlers(sci_phy
,
2119 SCI_BASE_PHY_STATE_STOPPED
);
2121 if (sci_phy
->sata_timeout_timer
!= NULL
) {
2122 isci_del_timer(ihost
, sci_phy
->sata_timeout_timer
);
2124 sci_phy
->sata_timeout_timer
= NULL
;
2127 scu_link_layer_stop_protocol_engine(sci_phy
);
2129 if (sci_phy
->state_machine
.previous_state_id
!=
2130 SCI_BASE_PHY_STATE_INITIAL
)
2131 scic_sds_controller_link_down(
2132 scic_sds_phy_get_controller(sci_phy
),
2133 scic_sds_phy_get_port(sci_phy
),
2139 * @object: This is the object which is cast to a struct scic_sds_phy object.
2141 * This method will perform the actions required by the struct scic_sds_phy on
2142 * entering the SCI_BASE_PHY_STATE_STARTING. - This function sets the state
2143 * handlers for the phy object base state machine starting state. - The SCU
2144 * hardware is requested to start OOB/SN on this protocl engine. - The phy
2145 * starting substate machine is started. - If the previous state was the ready
2146 * state then the struct scic_sds_controller is informed that the phy has gone link
2149 static void scic_sds_phy_starting_state_enter(void *object
)
2151 struct scic_sds_phy
*sci_phy
= object
;
2153 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_STARTING
);
2155 scu_link_layer_stop_protocol_engine(sci_phy
);
2156 scu_link_layer_start_oob(sci_phy
);
2158 /* We don't know what kind of phy we are going to be just yet */
2159 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_UNKNOWN
;
2160 sci_phy
->bcn_received_while_port_unassigned
= false;
2162 /* Change over to the starting substate machine to continue */
2163 sci_base_state_machine_start(&sci_phy
->starting_substate_machine
);
2165 if (sci_phy
->state_machine
.previous_state_id
2166 == SCI_BASE_PHY_STATE_READY
) {
2167 scic_sds_controller_link_down(
2168 scic_sds_phy_get_controller(sci_phy
),
2169 scic_sds_phy_get_port(sci_phy
),
2177 * @object: This is the object which is cast to a struct scic_sds_phy object.
2179 * This method will perform the actions required by the struct scic_sds_phy on
2180 * entering the SCI_BASE_PHY_STATE_READY. - This function sets the state
2181 * handlers for the phy object base state machine ready state. - The SCU
2182 * hardware protocol engine is resumed. - The struct scic_sds_controller is informed
2183 * that the phy object has gone link up. none
2185 static void scic_sds_phy_ready_state_enter(void *object
)
2187 struct scic_sds_phy
*sci_phy
= object
;
2189 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_READY
);
2191 scic_sds_controller_link_up(
2192 scic_sds_phy_get_controller(sci_phy
),
2193 scic_sds_phy_get_port(sci_phy
),
2200 * @object: This is the object which is cast to a struct scic_sds_phy object.
2202 * This method will perform the actions required by the struct scic_sds_phy on exiting
2203 * the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU hardware
2204 * protocol engine represented by this struct scic_sds_phy object. none
2206 static void scic_sds_phy_ready_state_exit(void *object
)
2208 struct scic_sds_phy
*sci_phy
= object
;
2210 scic_sds_phy_suspend(sci_phy
);
2215 * @object: This is the object which is cast to a struct scic_sds_phy object.
2217 * This method will perform the actions required by the struct scic_sds_phy on
2218 * entering the SCI_BASE_PHY_STATE_RESETTING. - This function sets the state
2219 * handlers for the phy object base state machine resetting state. none
2221 static void scic_sds_phy_resetting_state_enter(void *object
)
2223 struct scic_sds_phy
*sci_phy
= object
;
2225 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_RESETTING
);
2228 * The phy is being reset, therefore deactivate it from the port.
2229 * In the resetting state we don't notify the user regarding
2230 * link up and link down notifications. */
2231 scic_sds_port_deactivate_phy(sci_phy
->owning_port
, sci_phy
, false);
2233 if (sci_phy
->protocol
== SCIC_SDS_PHY_PROTOCOL_SAS
) {
2234 scu_link_layer_tx_hard_reset(sci_phy
);
2237 * The SCU does not need to have a discrete reset state so
2238 * just go back to the starting state.
2240 sci_base_state_machine_change_state(
2241 &sci_phy
->state_machine
,
2242 SCI_BASE_PHY_STATE_STARTING
);
2248 * @object: This is the object which is cast to a struct scic_sds_phy object.
2250 * This method will perform the actions required by the struct scic_sds_phy on
2251 * entering the SCI_BASE_PHY_STATE_FINAL. - This function sets the state
2252 * handlers for the phy object base state machine final state. none
2254 static void scic_sds_phy_final_state_enter(void *object
)
2256 struct scic_sds_phy
*sci_phy
= object
;
2258 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_FINAL
);
2260 /* Nothing to do here */
2263 /* --------------------------------------------------------------------------- */
2265 static const struct sci_base_state scic_sds_phy_state_table
[] = {
2266 [SCI_BASE_PHY_STATE_INITIAL
] = {
2267 .enter_state
= scic_sds_phy_initial_state_enter
,
2269 [SCI_BASE_PHY_STATE_STOPPED
] = {
2270 .enter_state
= scic_sds_phy_stopped_state_enter
,
2272 [SCI_BASE_PHY_STATE_STARTING
] = {
2273 .enter_state
= scic_sds_phy_starting_state_enter
,
2275 [SCI_BASE_PHY_STATE_READY
] = {
2276 .enter_state
= scic_sds_phy_ready_state_enter
,
2277 .exit_state
= scic_sds_phy_ready_state_exit
,
2279 [SCI_BASE_PHY_STATE_RESETTING
] = {
2280 .enter_state
= scic_sds_phy_resetting_state_enter
,
2282 [SCI_BASE_PHY_STATE_FINAL
] = {
2283 .enter_state
= scic_sds_phy_final_state_enter
,
2287 void scic_sds_phy_construct(struct scic_sds_phy
*sci_phy
,
2288 struct scic_sds_port
*owning_port
, u8 phy_index
)
2290 sci_base_state_machine_construct(&sci_phy
->state_machine
,
2292 scic_sds_phy_state_table
,
2293 SCI_BASE_PHY_STATE_INITIAL
);
2295 sci_base_state_machine_start(&sci_phy
->state_machine
);
2297 /* Copy the rest of the input data to our locals */
2298 sci_phy
->owning_port
= owning_port
;
2299 sci_phy
->phy_index
= phy_index
;
2300 sci_phy
->bcn_received_while_port_unassigned
= false;
2301 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_UNKNOWN
;
2302 sci_phy
->link_layer_registers
= NULL
;
2303 sci_phy
->max_negotiated_speed
= SAS_LINK_RATE_UNKNOWN
;
2304 sci_phy
->sata_timeout_timer
= NULL
;
2306 /* Initialize the the substate machines */
2307 sci_base_state_machine_construct(&sci_phy
->starting_substate_machine
,
2309 scic_sds_phy_starting_substates
,
2310 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
);