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.
59 #include "scu_event_codes.h"
60 #include "scic_port.h"
61 #include "scic_config_parameters.h"
64 /* Maximum arbitration wait time in micro-seconds */
65 #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
67 enum sas_linkrate
sci_phy_linkrate(struct scic_sds_phy
*sci_phy
)
69 return sci_phy
->max_negotiated_speed
;
73 * *****************************************************************************
74 * * SCIC SDS PHY Internal Methods
75 * ***************************************************************************** */
78 * This method will initialize the phy transport layer registers
80 * @transport_layer_registers
84 static enum sci_status
scic_sds_phy_transport_layer_initialization(
85 struct scic_sds_phy
*sci_phy
,
86 struct scu_transport_layer_registers __iomem
*transport_layer_registers
)
90 sci_phy
->transport_layer_registers
= transport_layer_registers
;
92 writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
,
93 &sci_phy
->transport_layer_registers
->stp_rni
);
96 * Hardware team recommends that we enable the STP prefetch for all
99 tl_control
= readl(&sci_phy
->transport_layer_registers
->control
);
100 tl_control
|= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH
);
101 writel(tl_control
, &sci_phy
->transport_layer_registers
->control
);
107 * This method will initialize the phy link layer registers
109 * @link_layer_registers:
113 static enum sci_status
114 scic_sds_phy_link_layer_initialization(struct scic_sds_phy
*sci_phy
,
115 struct scu_link_layer_registers __iomem
*link_layer_registers
)
117 struct scic_sds_controller
*scic
=
118 sci_phy
->owning_port
->owning_controller
;
119 int phy_idx
= sci_phy
->phy_index
;
120 struct sci_phy_user_params
*phy_user
=
121 &scic
->user_parameters
.sds1
.phys
[phy_idx
];
122 struct sci_phy_oem_params
*phy_oem
=
123 &scic
->oem_parameters
.sds1
.phys
[phy_idx
];
124 u32 phy_configuration
;
125 struct scic_phy_cap phy_cap
;
126 u32 parity_check
= 0;
127 u32 parity_count
= 0;
128 u32 llctl
, link_rate
;
131 sci_phy
->link_layer_registers
= link_layer_registers
;
133 /* Set our IDENTIFY frame data */
134 #define SCI_END_DEVICE 0x01
136 writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR
) |
137 SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR
) |
138 SCU_SAS_TIID_GEN_BIT(STP_INITIATOR
) |
139 SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST
) |
140 SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE
, SCI_END_DEVICE
),
141 &sci_phy
->link_layer_registers
->transmit_identification
);
143 /* Write the device SAS Address */
145 &sci_phy
->link_layer_registers
->sas_device_name_high
);
146 writel(phy_idx
, &sci_phy
->link_layer_registers
->sas_device_name_low
);
148 /* Write the source SAS Address */
149 writel(phy_oem
->sas_address
.high
,
150 &sci_phy
->link_layer_registers
->source_sas_address_high
);
151 writel(phy_oem
->sas_address
.low
,
152 &sci_phy
->link_layer_registers
->source_sas_address_low
);
154 /* Clear and Set the PHY Identifier */
155 writel(0, &sci_phy
->link_layer_registers
->identify_frame_phy_id
);
156 writel(SCU_SAS_TIPID_GEN_VALUE(ID
, phy_idx
),
157 &sci_phy
->link_layer_registers
->identify_frame_phy_id
);
159 /* Change the initial state of the phy configuration register */
161 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
163 /* Hold OOB state machine in reset */
164 phy_configuration
|= SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
165 writel(phy_configuration
,
166 &sci_phy
->link_layer_registers
->phy_configuration
);
168 /* Configure the SNW capabilities */
171 phy_cap
.gen3_no_ssc
= 1;
172 phy_cap
.gen2_no_ssc
= 1;
173 phy_cap
.gen1_no_ssc
= 1;
174 if (scic
->oem_parameters
.sds1
.controller
.do_enable_ssc
== true) {
175 phy_cap
.gen3_ssc
= 1;
176 phy_cap
.gen2_ssc
= 1;
177 phy_cap
.gen1_ssc
= 1;
181 * The SAS specification indicates that the phy_capabilities that
182 * are transmitted shall have an even parity. Calculate the parity. */
183 parity_check
= phy_cap
.all
;
184 while (parity_check
!= 0) {
185 if (parity_check
& 0x1)
191 * If parity indicates there are an odd number of bits set, then
192 * set the parity bit to 1 in the phy capabilities. */
193 if ((parity_count
% 2) != 0)
196 writel(phy_cap
.all
, &sci_phy
->link_layer_registers
->phy_capabilities
);
198 /* Set the enable spinup period but disable the ability to send
199 * notify enable spinup
201 writel(SCU_ENSPINUP_GEN_VAL(COUNT
,
202 phy_user
->notify_enable_spin_up_insertion_frequency
),
203 &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
205 /* Write the ALIGN Insertion Ferequency for connected phy and
206 * inpendent of connected state
208 clksm_value
= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED
,
209 phy_user
->in_connection_align_insertion_frequency
);
211 clksm_value
|= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL
,
212 phy_user
->align_insertion_frequency
);
214 writel(clksm_value
, &sci_phy
->link_layer_registers
->clock_skew_management
);
216 /* @todo Provide a way to write this register correctly */
218 &sci_phy
->link_layer_registers
->afe_lookup_table_control
);
220 llctl
= SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT
,
221 (u8
)scic
->user_parameters
.sds1
.no_outbound_task_timeout
);
223 switch(phy_user
->max_speed_generation
) {
224 case SCIC_SDS_PARM_GEN3_SPEED
:
225 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3
;
227 case SCIC_SDS_PARM_GEN2_SPEED
:
228 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2
;
231 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1
;
234 llctl
|= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE
, link_rate
);
235 writel(llctl
, &sci_phy
->link_layer_registers
->link_layer_control
);
237 if (is_a0() || is_a2()) {
238 /* Program the max ARB time for the PHY to 700us so we inter-operate with
239 * the PMC expander which shuts down PHYs if the expander PHY generates too
240 * many breaks. This time value will guarantee that the initiator PHY will
241 * generate the break.
243 writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME
,
244 &sci_phy
->link_layer_registers
->maximum_arbitration_wait_timer_timeout
);
248 * Set the link layer hang detection to 500ms (0x1F4) from its default
249 * value of 128ms. Max value is 511 ms.
251 writel(0x1F4, &sci_phy
->link_layer_registers
->link_layer_hang_detection_timeout
);
253 /* We can exit the initial state to the stopped state */
254 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
255 SCI_BASE_PHY_STATE_STOPPED
);
261 * This function will handle the sata SIGNATURE FIS timeout condition. It will
262 * restart the starting substate machine since we dont know what has actually
265 static void scic_sds_phy_sata_timeout(void *phy
)
267 struct scic_sds_phy
*sci_phy
= phy
;
269 dev_dbg(sciphy_to_dev(sci_phy
),
270 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
275 sci_base_state_machine_stop(&sci_phy
->starting_substate_machine
);
277 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
278 SCI_BASE_PHY_STATE_STARTING
);
282 * This method returns the port currently containing this phy. If the phy is
283 * currently contained by the dummy port, then the phy is considered to not
285 * @sci_phy: This parameter specifies the phy for which to retrieve the
288 * This method returns a handle to a port that contains the supplied phy.
289 * NULL This value is returned if the phy is not part of a real
290 * port (i.e. it's contained in the dummy port). !NULL All other
291 * values indicate a handle/pointer to the port containing the phy.
293 struct scic_sds_port
*scic_sds_phy_get_port(
294 struct scic_sds_phy
*sci_phy
)
296 if (scic_sds_port_get_index(sci_phy
->owning_port
) == SCIC_SDS_DUMMY_PORT
)
299 return sci_phy
->owning_port
;
303 * This method will assign a port to the phy object.
304 * @out]: sci_phy This parameter specifies the phy for which to assign a port
309 void scic_sds_phy_set_port(
310 struct scic_sds_phy
*sci_phy
,
311 struct scic_sds_port
*sci_port
)
313 sci_phy
->owning_port
= sci_port
;
315 if (sci_phy
->bcn_received_while_port_unassigned
) {
316 sci_phy
->bcn_received_while_port_unassigned
= false;
317 scic_sds_port_broadcast_change_received(sci_phy
->owning_port
, sci_phy
);
322 * This method will initialize the constructed phy
324 * @link_layer_registers:
328 enum sci_status
scic_sds_phy_initialize(
329 struct scic_sds_phy
*sci_phy
,
330 struct scu_transport_layer_registers __iomem
*transport_layer_registers
,
331 struct scu_link_layer_registers __iomem
*link_layer_registers
)
333 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
334 struct isci_host
*ihost
= scic_to_ihost(scic
);
336 /* Create the SIGNATURE FIS Timeout timer for this phy */
337 sci_phy
->sata_timeout_timer
=
341 scic_sds_phy_sata_timeout
);
343 /* Perfrom the initialization of the TL hardware */
344 scic_sds_phy_transport_layer_initialization(
346 transport_layer_registers
);
348 /* Perofrm the initialization of the PE hardware */
349 scic_sds_phy_link_layer_initialization(sci_phy
, link_layer_registers
);
352 * There is nothing that needs to be done in this state just
353 * transition to the stopped state. */
354 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
355 SCI_BASE_PHY_STATE_STOPPED
);
361 * This method assigns the direct attached device ID for this phy.
363 * @sci_phy The phy for which the direct attached device id is to
365 * @device_id The direct attached device ID to assign to the phy.
366 * This will either be the RNi for the device or an invalid RNi if there
367 * is no current device assigned to the phy.
369 void scic_sds_phy_setup_transport(
370 struct scic_sds_phy
*sci_phy
,
375 writel(device_id
, &sci_phy
->transport_layer_registers
->stp_rni
);
378 * The read should guarantee that the first write gets posted
379 * before the next write
381 tl_control
= readl(&sci_phy
->transport_layer_registers
->control
);
382 tl_control
|= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE
);
383 writel(tl_control
, &sci_phy
->transport_layer_registers
->control
);
388 * @sci_phy: The phy object to be suspended.
390 * This function will perform the register reads/writes to suspend the SCU
391 * hardware protocol engine. none
393 static void scic_sds_phy_suspend(
394 struct scic_sds_phy
*sci_phy
)
396 u32 scu_sas_pcfg_value
;
399 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
400 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
);
401 writel(scu_sas_pcfg_value
,
402 &sci_phy
->link_layer_registers
->phy_configuration
);
404 scic_sds_phy_setup_transport(
406 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
);
409 void scic_sds_phy_resume(struct scic_sds_phy
*sci_phy
)
411 u32 scu_sas_pcfg_value
;
414 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
415 scu_sas_pcfg_value
&= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
);
416 writel(scu_sas_pcfg_value
,
417 &sci_phy
->link_layer_registers
->phy_configuration
);
420 void scic_sds_phy_get_sas_address(struct scic_sds_phy
*sci_phy
,
421 struct sci_sas_address
*sas_address
)
423 sas_address
->high
= readl(&sci_phy
->link_layer_registers
->source_sas_address_high
);
424 sas_address
->low
= readl(&sci_phy
->link_layer_registers
->source_sas_address_low
);
427 void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy
*sci_phy
,
428 struct sci_sas_address
*sas_address
)
430 struct sas_identify_frame
*iaf
;
431 struct isci_phy
*iphy
= sci_phy_to_iphy(sci_phy
);
433 iaf
= &iphy
->frame_rcvd
.iaf
;
434 memcpy(sas_address
, iaf
->sas_addr
, SAS_ADDR_SIZE
);
437 void scic_sds_phy_get_protocols(struct scic_sds_phy
*sci_phy
,
438 struct scic_phy_proto
*protocols
)
441 (u16
)(readl(&sci_phy
->
442 link_layer_registers
->transmit_identification
) &
447 * This method will attempt to start the phy object. This request is only valid
448 * when the phy is in the stopped state
453 enum sci_status
scic_sds_phy_start(struct scic_sds_phy
*sci_phy
)
455 return sci_phy
->state_handlers
->start_handler(sci_phy
);
459 * This method will attempt to stop the phy object.
462 * enum sci_status SCI_SUCCESS if the phy is going to stop SCI_INVALID_STATE
463 * if the phy is not in a valid state to stop
465 enum sci_status
scic_sds_phy_stop(struct scic_sds_phy
*sci_phy
)
467 return sci_phy
->state_handlers
->stop_handler(sci_phy
);
471 * This method will attempt to reset the phy. This request is only valid when
472 * the phy is in an ready state
477 enum sci_status
scic_sds_phy_reset(
478 struct scic_sds_phy
*sci_phy
)
480 return sci_phy
->state_handlers
->reset_handler(sci_phy
);
484 * This method will process the event code received.
490 enum sci_status
scic_sds_phy_event_handler(
491 struct scic_sds_phy
*sci_phy
,
494 return sci_phy
->state_handlers
->event_handler(sci_phy
, event_code
);
498 * This method will process the frame index received.
504 enum sci_status
scic_sds_phy_frame_handler(
505 struct scic_sds_phy
*sci_phy
,
508 return sci_phy
->state_handlers
->frame_handler(sci_phy
, frame_index
);
512 * This method will give the phy permission to consume power
517 enum sci_status
scic_sds_phy_consume_power_handler(
518 struct scic_sds_phy
*sci_phy
)
520 return sci_phy
->state_handlers
->consume_power_handler(sci_phy
);
524 * *****************************************************************************
525 * * SCIC SDS PHY HELPER FUNCTIONS
526 * ***************************************************************************** */
531 * @sci_phy: The phy object that received SAS PHY DETECTED.
533 * This method continues the link training for the phy as if it were a SAS PHY
534 * instead of a SATA PHY. This is done because the completion queue had a SAS
535 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
538 static void scic_sds_phy_start_sas_link_training(
539 struct scic_sds_phy
*sci_phy
)
544 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
545 phy_control
|= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
);
547 &sci_phy
->link_layer_registers
->phy_configuration
);
549 sci_base_state_machine_change_state(
550 &sci_phy
->starting_substate_machine
,
551 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
554 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SAS
;
559 * @sci_phy: The phy object that received a SATA SPINUP HOLD event
561 * This method continues the link training for the phy as if it were a SATA PHY
562 * instead of a SAS PHY. This is done because the completion queue had a SATA
563 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
565 static void scic_sds_phy_start_sata_link_training(
566 struct scic_sds_phy
*sci_phy
)
568 sci_base_state_machine_change_state(
569 &sci_phy
->starting_substate_machine
,
570 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
573 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SATA
;
577 * scic_sds_phy_complete_link_training - perform processing common to
578 * all protocols upon completion of link training.
579 * @sci_phy: This parameter specifies the phy object for which link training
581 * @max_link_rate: This parameter specifies the maximum link rate to be
582 * associated with this phy.
583 * @next_state: This parameter specifies the next state for the phy's starting
587 static void scic_sds_phy_complete_link_training(
588 struct scic_sds_phy
*sci_phy
,
589 enum sas_linkrate max_link_rate
,
592 sci_phy
->max_negotiated_speed
= max_link_rate
;
594 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
598 static void scic_sds_phy_restart_starting_state(
599 struct scic_sds_phy
*sci_phy
)
601 /* Stop the current substate machine */
602 sci_base_state_machine_stop(&sci_phy
->starting_substate_machine
);
604 /* Re-enter the base state machine starting state */
605 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
606 SCI_BASE_PHY_STATE_STARTING
);
609 /* ****************************************************************************
610 * SCIC SDS PHY general handlers
611 ************************************************************************** */
612 static enum sci_status
scic_sds_phy_starting_substate_general_stop_handler(
613 struct scic_sds_phy
*phy
)
615 sci_base_state_machine_stop(&phy
->starting_substate_machine
);
617 sci_base_state_machine_change_state(&phy
->state_machine
,
618 SCI_BASE_PHY_STATE_STOPPED
);
624 * *****************************************************************************
625 * * SCIC SDS PHY EVENT_HANDLERS
626 * ***************************************************************************** */
630 * @phy: This struct scic_sds_phy object which has received an event.
631 * @event_code: This is the event code which the phy object is to decode.
633 * This method is called when an event notification is received for the phy
634 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
635 * decode the event - sas phy detected causes a state transition to the wait
636 * for speed event notification. - any other events log a warning message and
637 * set a failure status enum sci_status SCI_SUCCESS on any valid event notification
638 * SCI_FAILURE on any unexpected event notifation
640 static enum sci_status
scic_sds_phy_starting_substate_await_ossp_event_handler(
641 struct scic_sds_phy
*sci_phy
,
644 u32 result
= SCI_SUCCESS
;
646 switch (scu_get_event_code(event_code
)) {
647 case SCU_EVENT_SAS_PHY_DETECTED
:
648 scic_sds_phy_start_sas_link_training(sci_phy
);
649 sci_phy
->is_in_link_training
= true;
652 case SCU_EVENT_SATA_SPINUP_HOLD
:
653 scic_sds_phy_start_sata_link_training(sci_phy
);
654 sci_phy
->is_in_link_training
= true;
658 dev_dbg(sciphy_to_dev(sci_phy
),
659 "%s: PHY starting substate machine received "
660 "unexpected event_code %x\n",
664 result
= SCI_FAILURE
;
673 * @phy: This struct scic_sds_phy object which has received an event.
674 * @event_code: This is the event code which the phy object is to decode.
676 * This method is called when an event notification is received for the phy
677 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
678 * decode the event - sas phy detected returns us back to this state. - speed
679 * event detected causes a state transition to the wait for iaf. - identify
680 * timeout is an un-expected event and the state machine is restarted. - link
681 * failure events restart the starting state machine - any other events log a
682 * warning message and set a failure status enum sci_status SCI_SUCCESS on any valid
683 * event notification SCI_FAILURE on any unexpected event notifation
685 static enum sci_status
scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler(
686 struct scic_sds_phy
*sci_phy
,
689 u32 result
= SCI_SUCCESS
;
691 switch (scu_get_event_code(event_code
)) {
692 case SCU_EVENT_SAS_PHY_DETECTED
:
694 * Why is this being reported again by the controller?
695 * We would re-enter this state so just stay here */
698 case SCU_EVENT_SAS_15
:
699 case SCU_EVENT_SAS_15_SSC
:
700 scic_sds_phy_complete_link_training(
702 SAS_LINK_RATE_1_5_GBPS
,
703 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
706 case SCU_EVENT_SAS_30
:
707 case SCU_EVENT_SAS_30_SSC
:
708 scic_sds_phy_complete_link_training(
710 SAS_LINK_RATE_3_0_GBPS
,
711 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
714 case SCU_EVENT_SAS_60
:
715 case SCU_EVENT_SAS_60_SSC
:
716 scic_sds_phy_complete_link_training(
718 SAS_LINK_RATE_6_0_GBPS
,
719 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
722 case SCU_EVENT_SATA_SPINUP_HOLD
:
724 * We were doing SAS PHY link training and received a SATA PHY event
725 * continue OOB/SN as if this were a SATA PHY */
726 scic_sds_phy_start_sata_link_training(sci_phy
);
729 case SCU_EVENT_LINK_FAILURE
:
730 /* Link failure change state back to the starting state */
731 scic_sds_phy_restart_starting_state(sci_phy
);
735 dev_warn(sciphy_to_dev(sci_phy
),
736 "%s: PHY starting substate machine received "
737 "unexpected event_code %x\n",
741 result
= SCI_FAILURE
;
750 * @phy: This struct scic_sds_phy object which has received an event.
751 * @event_code: This is the event code which the phy object is to decode.
753 * This method is called when an event notification is received for the phy
754 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. -
755 * decode the event - sas phy detected event backs up the state machine to the
756 * await speed notification. - identify timeout is an un-expected event and the
757 * state machine is restarted. - link failure events restart the starting state
758 * machine - any other events log a warning message and set a failure status
759 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
760 * unexpected event notifation
762 static enum sci_status
scic_sds_phy_starting_substate_await_iaf_uf_event_handler(
763 struct scic_sds_phy
*sci_phy
,
766 u32 result
= SCI_SUCCESS
;
768 switch (scu_get_event_code(event_code
)) {
769 case SCU_EVENT_SAS_PHY_DETECTED
:
770 /* Backup the state machine */
771 scic_sds_phy_start_sas_link_training(sci_phy
);
774 case SCU_EVENT_SATA_SPINUP_HOLD
:
776 * We were doing SAS PHY link training and received a SATA PHY event
777 * continue OOB/SN as if this were a SATA PHY */
778 scic_sds_phy_start_sata_link_training(sci_phy
);
781 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT
:
782 case SCU_EVENT_LINK_FAILURE
:
783 case SCU_EVENT_HARD_RESET_RECEIVED
:
784 /* Start the oob/sn state machine over again */
785 scic_sds_phy_restart_starting_state(sci_phy
);
789 dev_warn(sciphy_to_dev(sci_phy
),
790 "%s: PHY starting substate machine received "
791 "unexpected event_code %x\n",
795 result
= SCI_FAILURE
;
804 * @phy: This struct scic_sds_phy object which has received an event.
805 * @event_code: This is the event code which the phy object is to decode.
807 * This method is called when an event notification is received for the phy
808 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. -
809 * decode the event - link failure events restart the starting state machine -
810 * any other events log a warning message and set a failure status enum sci_status
811 * SCI_SUCCESS on a link failure event SCI_FAILURE on any unexpected event
814 static enum sci_status
scic_sds_phy_starting_substate_await_sas_power_event_handler(
815 struct scic_sds_phy
*sci_phy
,
818 u32 result
= SCI_SUCCESS
;
820 switch (scu_get_event_code(event_code
)) {
821 case SCU_EVENT_LINK_FAILURE
:
822 /* Link failure change state back to the starting state */
823 scic_sds_phy_restart_starting_state(sci_phy
);
827 dev_warn(sciphy_to_dev(sci_phy
),
828 "%s: PHY starting substate machine received unexpected "
833 result
= SCI_FAILURE
;
842 * @phy: This struct scic_sds_phy object which has received an event.
843 * @event_code: This is the event code which the phy object is to decode.
845 * This method is called when an event notification is received for the phy
846 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. -
847 * decode the event - link failure events restart the starting state machine -
848 * sata spinup hold events are ignored since they are expected - any other
849 * events log a warning message and set a failure status enum sci_status SCI_SUCCESS
850 * on a link failure event SCI_FAILURE on any unexpected event notifation
852 static enum sci_status
scic_sds_phy_starting_substate_await_sata_power_event_handler(
853 struct scic_sds_phy
*sci_phy
,
856 u32 result
= SCI_SUCCESS
;
858 switch (scu_get_event_code(event_code
)) {
859 case SCU_EVENT_LINK_FAILURE
:
860 /* Link failure change state back to the starting state */
861 scic_sds_phy_restart_starting_state(sci_phy
);
864 case SCU_EVENT_SATA_SPINUP_HOLD
:
865 /* These events are received every 10ms and are expected while in this state */
868 case SCU_EVENT_SAS_PHY_DETECTED
:
870 * There has been a change in the phy type before OOB/SN for the
871 * SATA finished start down the SAS link traning path. */
872 scic_sds_phy_start_sas_link_training(sci_phy
);
876 dev_warn(sciphy_to_dev(sci_phy
),
877 "%s: PHY starting substate machine received "
878 "unexpected event_code %x\n",
882 result
= SCI_FAILURE
;
890 * scic_sds_phy_starting_substate_await_sata_phy_event_handler -
891 * @phy: This struct scic_sds_phy object which has received an event.
892 * @event_code: This is the event code which the phy object is to decode.
894 * This method is called when an event notification is received for the phy
895 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. -
896 * decode the event - link failure events restart the starting state machine -
897 * sata spinup hold events are ignored since they are expected - sata phy
898 * detected event change to the wait speed event - any other events log a
899 * warning message and set a failure status enum sci_status SCI_SUCCESS on a link
900 * failure event SCI_FAILURE on any unexpected event notifation
902 static enum sci_status
scic_sds_phy_starting_substate_await_sata_phy_event_handler(
903 struct scic_sds_phy
*sci_phy
, u32 event_code
)
905 u32 result
= SCI_SUCCESS
;
907 switch (scu_get_event_code(event_code
)) {
908 case SCU_EVENT_LINK_FAILURE
:
909 /* Link failure change state back to the starting state */
910 scic_sds_phy_restart_starting_state(sci_phy
);
913 case SCU_EVENT_SATA_SPINUP_HOLD
:
914 /* These events might be received since we dont know how many may be in
915 * the completion queue while waiting for power
919 case SCU_EVENT_SATA_PHY_DETECTED
:
920 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SATA
;
922 /* We have received the SATA PHY notification change state */
923 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
924 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
927 case SCU_EVENT_SAS_PHY_DETECTED
:
928 /* There has been a change in the phy type before OOB/SN for the
929 * SATA finished start down the SAS link traning path.
931 scic_sds_phy_start_sas_link_training(sci_phy
);
935 dev_warn(sciphy_to_dev(sci_phy
),
936 "%s: PHY starting substate machine received "
937 "unexpected event_code %x\n",
941 result
= SCI_FAILURE
;
950 * @phy: This struct scic_sds_phy object which has received an event.
951 * @event_code: This is the event code which the phy object is to decode.
953 * This method is called when an event notification is received for the phy
954 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
955 * - decode the event - sata phy detected returns us back to this state. -
956 * speed event detected causes a state transition to the wait for signature. -
957 * link failure events restart the starting state machine - any other events
958 * log a warning message and set a failure status enum sci_status SCI_SUCCESS on any
959 * valid event notification SCI_FAILURE on any unexpected event notifation
961 static enum sci_status
scic_sds_phy_starting_substate_await_sata_speed_event_handler(
962 struct scic_sds_phy
*sci_phy
,
965 u32 result
= SCI_SUCCESS
;
967 switch (scu_get_event_code(event_code
)) {
968 case SCU_EVENT_SATA_PHY_DETECTED
:
970 * The hardware reports multiple SATA PHY detected events
971 * ignore the extras */
974 case SCU_EVENT_SATA_15
:
975 case SCU_EVENT_SATA_15_SSC
:
976 scic_sds_phy_complete_link_training(
978 SAS_LINK_RATE_1_5_GBPS
,
979 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
982 case SCU_EVENT_SATA_30
:
983 case SCU_EVENT_SATA_30_SSC
:
984 scic_sds_phy_complete_link_training(
986 SAS_LINK_RATE_3_0_GBPS
,
987 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
990 case SCU_EVENT_SATA_60
:
991 case SCU_EVENT_SATA_60_SSC
:
992 scic_sds_phy_complete_link_training(
994 SAS_LINK_RATE_6_0_GBPS
,
995 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
998 case SCU_EVENT_LINK_FAILURE
:
999 /* Link failure change state back to the starting state */
1000 scic_sds_phy_restart_starting_state(sci_phy
);
1003 case SCU_EVENT_SAS_PHY_DETECTED
:
1005 * There has been a change in the phy type before OOB/SN for the
1006 * SATA finished start down the SAS link traning path. */
1007 scic_sds_phy_start_sas_link_training(sci_phy
);
1011 dev_warn(sciphy_to_dev(sci_phy
),
1012 "%s: PHY starting substate machine received "
1013 "unexpected event_code %x\n",
1017 result
= SCI_FAILURE
;
1025 * scic_sds_phy_starting_substate_await_sig_fis_event_handler -
1026 * @phy: This struct scic_sds_phy object which has received an event.
1027 * @event_code: This is the event code which the phy object is to decode.
1029 * This method is called when an event notification is received for the phy
1030 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. -
1031 * decode the event - sas phy detected event backs up the state machine to the
1032 * await speed notification. - identify timeout is an un-expected event and the
1033 * state machine is restarted. - link failure events restart the starting state
1034 * machine - any other events log a warning message and set a failure status
1035 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
1036 * unexpected event notifation
1038 static enum sci_status
scic_sds_phy_starting_substate_await_sig_fis_event_handler(
1039 struct scic_sds_phy
*sci_phy
, u32 event_code
)
1041 u32 result
= SCI_SUCCESS
;
1043 switch (scu_get_event_code(event_code
)) {
1044 case SCU_EVENT_SATA_PHY_DETECTED
:
1045 /* Backup the state machine */
1046 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1047 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
1050 case SCU_EVENT_LINK_FAILURE
:
1051 /* Link failure change state back to the starting state */
1052 scic_sds_phy_restart_starting_state(sci_phy
);
1056 dev_warn(sciphy_to_dev(sci_phy
),
1057 "%s: PHY starting substate machine received "
1058 "unexpected event_code %x\n",
1062 result
= SCI_FAILURE
;
1071 * *****************************************************************************
1072 * * SCIC SDS PHY FRAME_HANDLERS
1073 * ***************************************************************************** */
1077 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1079 * @frame_index: This is the index of the unsolicited frame which was received
1082 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1083 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Get the UF Header - If the UF
1084 * is an IAF - Copy IAF data to local phy object IAF data buffer. - Change
1085 * starting substate to wait power. - else - log warning message of unexpected
1086 * unsolicted frame - release frame buffer enum sci_status SCI_SUCCESS
1088 static enum sci_status
scic_sds_phy_starting_substate_await_iaf_uf_frame_handler(
1089 struct scic_sds_phy
*sci_phy
, u32 frame_index
)
1091 enum sci_status result
;
1093 struct sas_identify_frame iaf
;
1094 struct isci_phy
*iphy
= sci_phy_to_iphy(sci_phy
);
1096 result
= scic_sds_unsolicited_frame_control_get_header(
1097 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1099 (void **)&frame_words
);
1101 if (result
!= SCI_SUCCESS
)
1104 sci_swab32_cpy(&iaf
, frame_words
, sizeof(iaf
) / sizeof(u32
));
1105 if (iaf
.frame_type
== 0) {
1108 memcpy(&iphy
->frame_rcvd
.iaf
, &iaf
, sizeof(iaf
));
1109 if (iaf
.smp_tport
) {
1110 /* We got the IAF for an expander PHY go to the final
1111 * state since there are no power requirements for
1114 state
= SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
;
1116 /* We got the IAF we can now go to the await spinup
1119 state
= SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
;
1121 sci_base_state_machine_change_state(
1122 &sci_phy
->starting_substate_machine
,
1124 result
= SCI_SUCCESS
;
1126 dev_warn(sciphy_to_dev(sci_phy
),
1127 "%s: PHY starting substate machine received "
1128 "unexpected frame id %x\n",
1132 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy
),
1140 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1142 * @frame_index: This is the index of the unsolicited frame which was received
1145 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1146 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Get the UF Header - If
1147 * the UF is an SIGNATURE FIS - Copy IAF data to local phy object SIGNATURE FIS
1148 * data buffer. - else - log warning message of unexpected unsolicted frame -
1149 * release frame buffer enum sci_status SCI_SUCCESS Must decode the SIGNATURE FIS
1152 static enum sci_status
scic_sds_phy_starting_substate_await_sig_fis_frame_handler(
1153 struct scic_sds_phy
*sci_phy
,
1156 enum sci_status result
;
1157 struct dev_to_host_fis
*frame_header
;
1158 u32
*fis_frame_data
;
1159 struct isci_phy
*iphy
= sci_phy_to_iphy(sci_phy
);
1161 result
= scic_sds_unsolicited_frame_control_get_header(
1162 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1164 (void **)&frame_header
);
1166 if (result
!= SCI_SUCCESS
)
1169 if ((frame_header
->fis_type
== FIS_REGD2H
) &&
1170 !(frame_header
->status
& ATA_BUSY
)) {
1171 scic_sds_unsolicited_frame_control_get_buffer(
1172 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1174 (void **)&fis_frame_data
);
1176 scic_sds_controller_copy_sata_response(&iphy
->frame_rcvd
.fis
,
1180 /* got IAF we can now go to the await spinup semaphore state */
1181 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1182 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1184 result
= SCI_SUCCESS
;
1186 dev_warn(sciphy_to_dev(sci_phy
),
1187 "%s: PHY starting substate machine received "
1188 "unexpected frame id %x\n",
1192 /* Regardless of the result we are done with this frame with it */
1193 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy
),
1200 * *****************************************************************************
1201 * * SCIC SDS PHY POWER_HANDLERS
1202 * ***************************************************************************** */
1205 * This method is called by the struct scic_sds_controller when the phy object is
1206 * granted power. - The notify enable spinups are turned on for this phy object
1207 * - The phy state machine is transitioned to the
1208 * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. enum sci_status SCI_SUCCESS
1210 static enum sci_status
scic_sds_phy_starting_substate_await_sas_power_consume_power_handler(
1211 struct scic_sds_phy
*sci_phy
)
1215 enable_spinup
= readl(&sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1216 enable_spinup
|= SCU_ENSPINUP_GEN_BIT(ENABLE
);
1217 writel(enable_spinup
, &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1219 /* Change state to the final state this substate machine has run to completion */
1220 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1221 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1227 * This method is called by the struct scic_sds_controller when the phy object is
1228 * granted power. - The phy state machine is transitioned to the
1229 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. enum sci_status SCI_SUCCESS
1231 static enum sci_status
scic_sds_phy_starting_substate_await_sata_power_consume_power_handler(
1232 struct scic_sds_phy
*sci_phy
)
1234 u32 scu_sas_pcfg_value
;
1236 /* Release the spinup hold state and reset the OOB state machine */
1237 scu_sas_pcfg_value
=
1238 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
1239 scu_sas_pcfg_value
&=
1240 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
));
1241 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
1242 writel(scu_sas_pcfg_value
,
1243 &sci_phy
->link_layer_registers
->phy_configuration
);
1245 /* Now restart the OOB operation */
1246 scu_sas_pcfg_value
&= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
1247 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
1248 writel(scu_sas_pcfg_value
,
1249 &sci_phy
->link_layer_registers
->phy_configuration
);
1251 /* Change state to the final state this substate machine has run to completion */
1252 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1253 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
);
1258 static enum sci_status
default_phy_handler(struct scic_sds_phy
*sci_phy
,
1261 dev_dbg(sciphy_to_dev(sci_phy
),
1262 "%s: in wrong state: %d\n", func
,
1263 sci_base_state_machine_get_state(&sci_phy
->state_machine
));
1264 return SCI_FAILURE_INVALID_STATE
;
1267 static enum sci_status
1268 scic_sds_phy_default_start_handler(struct scic_sds_phy
*sci_phy
)
1270 return default_phy_handler(sci_phy
, __func__
);
1273 static enum sci_status
1274 scic_sds_phy_default_stop_handler(struct scic_sds_phy
*sci_phy
)
1276 return default_phy_handler(sci_phy
, __func__
);
1279 static enum sci_status
1280 scic_sds_phy_default_reset_handler(struct scic_sds_phy
*sci_phy
)
1282 return default_phy_handler(sci_phy
, __func__
);
1285 static enum sci_status
1286 scic_sds_phy_default_destroy_handler(struct scic_sds_phy
*sci_phy
)
1288 return default_phy_handler(sci_phy
, __func__
);
1291 static enum sci_status
1292 scic_sds_phy_default_frame_handler(struct scic_sds_phy
*sci_phy
,
1295 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
1297 default_phy_handler(sci_phy
, __func__
);
1298 scic_sds_controller_release_frame(scic
, frame_index
);
1300 return SCI_FAILURE_INVALID_STATE
;
1303 static enum sci_status
1304 scic_sds_phy_default_event_handler(struct scic_sds_phy
*sci_phy
,
1307 return default_phy_handler(sci_phy
, __func__
);
1310 static enum sci_status
1311 scic_sds_phy_default_consume_power_handler(struct scic_sds_phy
*sci_phy
)
1313 return default_phy_handler(sci_phy
, __func__
);
1318 static const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table
[] = {
1319 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
] = {
1320 .start_handler
= scic_sds_phy_default_start_handler
,
1321 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1322 .reset_handler
= scic_sds_phy_default_reset_handler
,
1323 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1324 .frame_handler
= scic_sds_phy_default_frame_handler
,
1325 .event_handler
= scic_sds_phy_default_event_handler
,
1326 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1328 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
] = {
1329 .start_handler
= scic_sds_phy_default_start_handler
,
1330 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1331 .reset_handler
= scic_sds_phy_default_reset_handler
,
1332 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1333 .frame_handler
= scic_sds_phy_default_frame_handler
,
1334 .event_handler
= scic_sds_phy_starting_substate_await_ossp_event_handler
,
1335 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1337 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
] = {
1338 .start_handler
= scic_sds_phy_default_start_handler
,
1339 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1340 .reset_handler
= scic_sds_phy_default_reset_handler
,
1341 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1342 .frame_handler
= scic_sds_phy_default_frame_handler
,
1343 .event_handler
= scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler
,
1344 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1346 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
] = {
1347 .start_handler
= scic_sds_phy_default_start_handler
,
1348 .stop_handler
= scic_sds_phy_default_stop_handler
,
1349 .reset_handler
= scic_sds_phy_default_reset_handler
,
1350 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1351 .frame_handler
= scic_sds_phy_starting_substate_await_iaf_uf_frame_handler
,
1352 .event_handler
= scic_sds_phy_starting_substate_await_iaf_uf_event_handler
,
1353 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1355 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
] = {
1356 .start_handler
= scic_sds_phy_default_start_handler
,
1357 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1358 .reset_handler
= scic_sds_phy_default_reset_handler
,
1359 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1360 .frame_handler
= scic_sds_phy_default_frame_handler
,
1361 .event_handler
= scic_sds_phy_starting_substate_await_sas_power_event_handler
,
1362 .consume_power_handler
= scic_sds_phy_starting_substate_await_sas_power_consume_power_handler
1364 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
] = {
1365 .start_handler
= scic_sds_phy_default_start_handler
,
1366 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1367 .reset_handler
= scic_sds_phy_default_reset_handler
,
1368 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1369 .frame_handler
= scic_sds_phy_default_frame_handler
,
1370 .event_handler
= scic_sds_phy_starting_substate_await_sata_power_event_handler
,
1371 .consume_power_handler
= scic_sds_phy_starting_substate_await_sata_power_consume_power_handler
1373 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
] = {
1374 .start_handler
= scic_sds_phy_default_start_handler
,
1375 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1376 .reset_handler
= scic_sds_phy_default_reset_handler
,
1377 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1378 .frame_handler
= scic_sds_phy_default_frame_handler
,
1379 .event_handler
= scic_sds_phy_starting_substate_await_sata_phy_event_handler
,
1380 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1382 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
] = {
1383 .start_handler
= scic_sds_phy_default_start_handler
,
1384 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1385 .reset_handler
= scic_sds_phy_default_reset_handler
,
1386 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1387 .frame_handler
= scic_sds_phy_default_frame_handler
,
1388 .event_handler
= scic_sds_phy_starting_substate_await_sata_speed_event_handler
,
1389 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1391 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
] = {
1392 .start_handler
= scic_sds_phy_default_start_handler
,
1393 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1394 .reset_handler
= scic_sds_phy_default_reset_handler
,
1395 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1396 .frame_handler
= scic_sds_phy_starting_substate_await_sig_fis_frame_handler
,
1397 .event_handler
= scic_sds_phy_starting_substate_await_sig_fis_event_handler
,
1398 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1400 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
] = {
1401 .start_handler
= scic_sds_phy_default_start_handler
,
1402 .stop_handler
= scic_sds_phy_starting_substate_general_stop_handler
,
1403 .reset_handler
= scic_sds_phy_default_reset_handler
,
1404 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1405 .frame_handler
= scic_sds_phy_default_frame_handler
,
1406 .event_handler
= scic_sds_phy_default_event_handler
,
1407 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1412 * scic_sds_phy_set_starting_substate_handlers() -
1414 * This macro sets the starting substate handlers by state_id
1416 #define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \
1417 scic_sds_phy_set_state_handlers(\
1419 &scic_sds_phy_starting_substate_handler_table[(state_id)] \
1423 * ****************************************************************************
1424 * * PHY STARTING SUBSTATE METHODS
1425 * **************************************************************************** */
1428 * scic_sds_phy_starting_initial_substate_enter -
1429 * @object: This is the object which is cast to a struct scic_sds_phy object.
1431 * This method will perform the actions required by the struct scic_sds_phy on
1432 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL. - The initial state
1433 * handlers are put in place for the struct scic_sds_phy object. - The state is
1434 * changed to the wait phy type event notification. none
1436 static void scic_sds_phy_starting_initial_substate_enter(void *object
)
1438 struct scic_sds_phy
*sci_phy
= object
;
1440 scic_sds_phy_set_starting_substate_handlers(
1441 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
);
1443 /* This is just an temporary state go off to the starting state */
1444 sci_base_state_machine_change_state(&sci_phy
->starting_substate_machine
,
1445 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
);
1450 * @object: This is the object which is cast to a struct scic_sds_phy object.
1452 * This method will perform the actions required by the struct scic_sds_phy on
1453 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_PHY_TYPE_EN. - Set the
1454 * struct scic_sds_phy object state handlers for this state. none
1456 static void scic_sds_phy_starting_await_ossp_en_substate_enter(void *object
)
1458 struct scic_sds_phy
*sci_phy
= object
;
1460 scic_sds_phy_set_starting_substate_handlers(
1461 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1467 * @object: This is the object which is cast to a struct scic_sds_phy object.
1469 * This method will perform the actions required by the struct scic_sds_phy on
1470 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - Set the
1471 * struct scic_sds_phy object state handlers for this state. none
1473 static void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
1476 struct scic_sds_phy
*sci_phy
= object
;
1478 scic_sds_phy_set_starting_substate_handlers(
1479 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
1485 * @object: This is the object which is cast to a struct scic_sds_phy object.
1487 * This method will perform the actions required by the struct scic_sds_phy on
1488 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Set the
1489 * struct scic_sds_phy object state handlers for this state. none
1491 static void scic_sds_phy_starting_await_iaf_uf_substate_enter(void *object
)
1493 struct scic_sds_phy
*sci_phy
= object
;
1495 scic_sds_phy_set_starting_substate_handlers(
1496 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
1502 * @object: This is the object which is cast to a struct scic_sds_phy object.
1504 * This method will perform the actions required by the struct scic_sds_phy on
1505 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Set the
1506 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1507 * the power control queue none
1509 static void scic_sds_phy_starting_await_sas_power_substate_enter(void *object
)
1511 struct scic_sds_phy
*sci_phy
= object
;
1513 scic_sds_phy_set_starting_substate_handlers(
1514 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1517 scic_sds_controller_power_control_queue_insert(
1518 scic_sds_phy_get_controller(sci_phy
),
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 exiting
1528 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Remove the
1529 * struct scic_sds_phy object from the power control queue. none
1531 static void scic_sds_phy_starting_await_sas_power_substate_exit(void *object
)
1533 struct scic_sds_phy
*sci_phy
= object
;
1535 scic_sds_controller_power_control_queue_remove(
1536 scic_sds_phy_get_controller(sci_phy
), sci_phy
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_SATA_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_sata_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_SATA_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_SATA_POWER. - Remove the
1569 * struct scic_sds_phy object from the power control queue. none
1571 static void scic_sds_phy_starting_await_sata_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
),
1583 * @object: This is the object which is cast to a struct scic_sds_phy object.
1585 * This function will perform the actions required by the struct scic_sds_phy on
1586 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. - Set the
1587 * struct scic_sds_phy object state handlers for this state. none
1589 static void scic_sds_phy_starting_await_sata_phy_substate_enter(void *object
)
1591 struct scic_sds_phy
*sci_phy
= object
;
1593 scic_sds_phy_set_starting_substate_handlers(
1595 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
);
1597 isci_timer_start(sci_phy
->sata_timeout_timer
,
1598 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
);
1603 * @object: This is the object which is cast to a struct scic_sds_phy object.
1605 * This method will perform the actions required by the struct scic_sds_phy
1607 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1608 * that was started on entry to await sata phy event notification none
1610 static inline void scic_sds_phy_starting_await_sata_phy_substate_exit(
1613 struct scic_sds_phy
*sci_phy
= object
;
1615 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1620 * @object: This is the object which is cast to a struct scic_sds_phy object.
1622 * This method will perform the actions required by the struct scic_sds_phy on
1623 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - Set the
1624 * struct scic_sds_phy object state handlers for this state. none
1626 static void scic_sds_phy_starting_await_sata_speed_substate_enter(void *object
)
1628 struct scic_sds_phy
*sci_phy
= object
;
1630 scic_sds_phy_set_starting_substate_handlers(
1632 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
1634 isci_timer_start(sci_phy
->sata_timeout_timer
,
1635 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
);
1640 * @object: This is the object which is cast to a struct scic_sds_phy object.
1642 * This function will perform the actions required by the
1643 * struct scic_sds_phy on exiting
1644 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1645 * that was started on entry to await sata phy event notification none
1647 static inline void scic_sds_phy_starting_await_sata_speed_substate_exit(
1650 struct scic_sds_phy
*sci_phy
= object
;
1652 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1657 * @object: This is the object which is cast to a struct scic_sds_phy object.
1659 * This function will perform the actions required by the struct scic_sds_phy on
1660 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Set the
1661 * struct scic_sds_phy object state handlers for this state.
1662 * - Start the SIGNATURE FIS
1663 * timeout timer none
1665 static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(void *object
)
1667 bool continue_to_ready_state
;
1668 struct scic_sds_phy
*sci_phy
= object
;
1670 scic_sds_phy_set_starting_substate_handlers(
1672 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
1674 continue_to_ready_state
= scic_sds_port_link_detected(
1675 sci_phy
->owning_port
,
1678 if (continue_to_ready_state
) {
1680 * Clear the PE suspend condition so we can actually
1682 * The hardware will not respond to the XRDY until the PE
1683 * suspend condition is cleared.
1685 scic_sds_phy_resume(sci_phy
);
1687 isci_timer_start(sci_phy
->sata_timeout_timer
,
1688 SCIC_SDS_SIGNATURE_FIS_TIMEOUT
);
1690 sci_phy
->is_in_link_training
= false;
1695 * @object: This is the object which is cast to a struct scic_sds_phy object.
1697 * This function will perform the actions required by the
1698 * struct scic_sds_phy on exiting
1699 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Stop the SIGNATURE
1700 * FIS timeout timer. none
1702 static inline void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(
1705 struct scic_sds_phy
*sci_phy
= object
;
1707 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1712 * @object: This is the object which is cast to a struct scic_sds_phy object.
1714 * This method will perform the actions required by the struct scic_sds_phy on
1715 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. - Set the struct scic_sds_phy
1716 * object state handlers for this state. - Change base state machine to the
1719 static void scic_sds_phy_starting_final_substate_enter(void *object
)
1721 struct scic_sds_phy
*sci_phy
= object
;
1723 scic_sds_phy_set_starting_substate_handlers(sci_phy
,
1724 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1726 /* State machine has run to completion so exit out and change
1727 * the base state machine to the ready state
1729 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1730 SCI_BASE_PHY_STATE_READY
);
1733 /* --------------------------------------------------------------------------- */
1735 static const struct sci_base_state scic_sds_phy_starting_substates
[] = {
1736 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
] = {
1737 .enter_state
= scic_sds_phy_starting_initial_substate_enter
,
1739 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
] = {
1740 .enter_state
= scic_sds_phy_starting_await_ossp_en_substate_enter
,
1742 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
] = {
1743 .enter_state
= scic_sds_phy_starting_await_sas_speed_en_substate_enter
,
1745 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
] = {
1746 .enter_state
= scic_sds_phy_starting_await_iaf_uf_substate_enter
,
1748 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
] = {
1749 .enter_state
= scic_sds_phy_starting_await_sas_power_substate_enter
,
1750 .exit_state
= scic_sds_phy_starting_await_sas_power_substate_exit
,
1752 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
] = {
1753 .enter_state
= scic_sds_phy_starting_await_sata_power_substate_enter
,
1754 .exit_state
= scic_sds_phy_starting_await_sata_power_substate_exit
1756 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
] = {
1757 .enter_state
= scic_sds_phy_starting_await_sata_phy_substate_enter
,
1758 .exit_state
= scic_sds_phy_starting_await_sata_phy_substate_exit
1760 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
] = {
1761 .enter_state
= scic_sds_phy_starting_await_sata_speed_substate_enter
,
1762 .exit_state
= scic_sds_phy_starting_await_sata_speed_substate_exit
1764 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
] = {
1765 .enter_state
= scic_sds_phy_starting_await_sig_fis_uf_substate_enter
,
1766 .exit_state
= scic_sds_phy_starting_await_sig_fis_uf_substate_exit
1768 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
] = {
1769 .enter_state
= scic_sds_phy_starting_final_substate_enter
,
1774 * This method takes the struct scic_sds_phy from a stopped state and
1775 * attempts to start it. - The phy state machine is transitioned to the
1776 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
1778 static enum sci_status
1779 scic_sds_phy_stopped_state_start_handler(struct scic_sds_phy
*sci_phy
)
1781 struct isci_host
*ihost
;
1782 struct scic_sds_controller
*scic
;
1784 scic
= scic_sds_phy_get_controller(sci_phy
),
1785 ihost
= scic_to_ihost(scic
);
1787 /* Create the SIGNATURE FIS Timeout timer for this phy */
1788 sci_phy
->sata_timeout_timer
= isci_timer_create(ihost
, sci_phy
,
1789 scic_sds_phy_sata_timeout
);
1791 if (sci_phy
->sata_timeout_timer
)
1792 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1793 SCI_BASE_PHY_STATE_STARTING
);
1798 static enum sci_status
1799 scic_sds_phy_stopped_state_destroy_handler(struct scic_sds_phy
*sci_phy
)
1804 static enum sci_status
1805 scic_sds_phy_ready_state_stop_handler(struct scic_sds_phy
*sci_phy
)
1807 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1808 SCI_BASE_PHY_STATE_STOPPED
);
1813 static enum sci_status
1814 scic_sds_phy_ready_state_reset_handler(struct scic_sds_phy
*sci_phy
)
1816 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1817 SCI_BASE_PHY_STATE_RESETTING
);
1823 * scic_sds_phy_ready_state_event_handler -
1824 * @phy: This is the struct scic_sds_phy object which has received the event.
1826 * This method request the struct scic_sds_phy handle the received event. The only
1827 * event that we are interested in while in the ready state is the link failure
1828 * event. - decoded event is a link failure - transition the struct scic_sds_phy back
1829 * to the SCI_BASE_PHY_STATE_STARTING state. - any other event received will
1830 * report a warning message enum sci_status SCI_SUCCESS if the event received is a
1831 * link failure SCI_FAILURE_INVALID_STATE for any other event received.
1833 static enum sci_status
scic_sds_phy_ready_state_event_handler(struct scic_sds_phy
*sci_phy
,
1836 enum sci_status result
= SCI_FAILURE
;
1838 switch (scu_get_event_code(event_code
)) {
1839 case SCU_EVENT_LINK_FAILURE
:
1840 /* Link failure change state back to the starting state */
1841 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1842 SCI_BASE_PHY_STATE_STARTING
);
1843 result
= SCI_SUCCESS
;
1846 case SCU_EVENT_BROADCAST_CHANGE
:
1847 /* Broadcast change received. Notify the port. */
1848 if (scic_sds_phy_get_port(sci_phy
) != NULL
)
1849 scic_sds_port_broadcast_change_received(sci_phy
->owning_port
, sci_phy
);
1851 sci_phy
->bcn_received_while_port_unassigned
= true;
1855 dev_warn(sciphy_to_dev(sci_phy
),
1856 "%sP SCIC PHY 0x%p ready state machine received "
1857 "unexpected event_code %x\n",
1858 __func__
, sci_phy
, event_code
);
1860 result
= SCI_FAILURE_INVALID_STATE
;
1867 static enum sci_status
scic_sds_phy_resetting_state_event_handler(struct scic_sds_phy
*sci_phy
,
1870 enum sci_status result
= SCI_FAILURE
;
1872 switch (scu_get_event_code(event_code
)) {
1873 case SCU_EVENT_HARD_RESET_TRANSMITTED
:
1874 /* Link failure change state back to the starting state */
1875 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1876 SCI_BASE_PHY_STATE_STARTING
);
1877 result
= SCI_SUCCESS
;
1881 dev_warn(sciphy_to_dev(sci_phy
),
1882 "%s: SCIC PHY 0x%p resetting state machine received "
1883 "unexpected event_code %x\n",
1884 __func__
, sci_phy
, event_code
);
1886 result
= SCI_FAILURE_INVALID_STATE
;
1893 /* --------------------------------------------------------------------------- */
1895 static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table
[] = {
1896 [SCI_BASE_PHY_STATE_INITIAL
] = {
1897 .start_handler
= scic_sds_phy_default_start_handler
,
1898 .stop_handler
= scic_sds_phy_default_stop_handler
,
1899 .reset_handler
= scic_sds_phy_default_reset_handler
,
1900 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1901 .frame_handler
= scic_sds_phy_default_frame_handler
,
1902 .event_handler
= scic_sds_phy_default_event_handler
,
1903 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1905 [SCI_BASE_PHY_STATE_STOPPED
] = {
1906 .start_handler
= scic_sds_phy_stopped_state_start_handler
,
1907 .stop_handler
= scic_sds_phy_default_stop_handler
,
1908 .reset_handler
= scic_sds_phy_default_reset_handler
,
1909 .destruct_handler
= scic_sds_phy_stopped_state_destroy_handler
,
1910 .frame_handler
= scic_sds_phy_default_frame_handler
,
1911 .event_handler
= scic_sds_phy_default_event_handler
,
1912 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1914 [SCI_BASE_PHY_STATE_STARTING
] = {
1915 .start_handler
= scic_sds_phy_default_start_handler
,
1916 .stop_handler
= scic_sds_phy_default_stop_handler
,
1917 .reset_handler
= scic_sds_phy_default_reset_handler
,
1918 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1919 .frame_handler
= scic_sds_phy_default_frame_handler
,
1920 .event_handler
= scic_sds_phy_default_event_handler
,
1921 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1923 [SCI_BASE_PHY_STATE_READY
] = {
1924 .start_handler
= scic_sds_phy_default_start_handler
,
1925 .stop_handler
= scic_sds_phy_ready_state_stop_handler
,
1926 .reset_handler
= scic_sds_phy_ready_state_reset_handler
,
1927 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1928 .frame_handler
= scic_sds_phy_default_frame_handler
,
1929 .event_handler
= scic_sds_phy_ready_state_event_handler
,
1930 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1932 [SCI_BASE_PHY_STATE_RESETTING
] = {
1933 .start_handler
= scic_sds_phy_default_start_handler
,
1934 .stop_handler
= scic_sds_phy_default_stop_handler
,
1935 .reset_handler
= scic_sds_phy_default_reset_handler
,
1936 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1937 .frame_handler
= scic_sds_phy_default_frame_handler
,
1938 .event_handler
= scic_sds_phy_resetting_state_event_handler
,
1939 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1941 [SCI_BASE_PHY_STATE_FINAL
] = {
1942 .start_handler
= scic_sds_phy_default_start_handler
,
1943 .stop_handler
= scic_sds_phy_default_stop_handler
,
1944 .reset_handler
= scic_sds_phy_default_reset_handler
,
1945 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1946 .frame_handler
= scic_sds_phy_default_frame_handler
,
1947 .event_handler
= scic_sds_phy_default_event_handler
,
1948 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1953 * ****************************************************************************
1954 * * PHY STATE PRIVATE METHODS
1955 * **************************************************************************** */
1959 * @sci_phy: This is the struct scic_sds_phy object to stop.
1961 * This method will stop the struct scic_sds_phy object. This does not reset the
1962 * protocol engine it just suspends it and places it in a state where it will
1963 * not cause the end device to power up. none
1965 static void scu_link_layer_stop_protocol_engine(
1966 struct scic_sds_phy
*sci_phy
)
1968 u32 scu_sas_pcfg_value
;
1969 u32 enable_spinup_value
;
1971 /* Suspend the protocol engine and place it in a sata spinup hold state */
1972 scu_sas_pcfg_value
=
1973 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
1974 scu_sas_pcfg_value
|=
1975 (SCU_SAS_PCFG_GEN_BIT(OOB_RESET
) |
1976 SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
) |
1977 SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
));
1978 writel(scu_sas_pcfg_value
,
1979 &sci_phy
->link_layer_registers
->phy_configuration
);
1981 /* Disable the notify enable spinup primitives */
1982 enable_spinup_value
= readl(&sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1983 enable_spinup_value
&= ~SCU_ENSPINUP_GEN_BIT(ENABLE
);
1984 writel(enable_spinup_value
, &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1990 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
1992 static void scu_link_layer_start_oob(
1993 struct scic_sds_phy
*sci_phy
)
1995 u32 scu_sas_pcfg_value
;
1997 scu_sas_pcfg_value
=
1998 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
1999 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
2000 scu_sas_pcfg_value
&=
2001 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET
) |
2002 SCU_SAS_PCFG_GEN_BIT(HARD_RESET
));
2003 writel(scu_sas_pcfg_value
,
2004 &sci_phy
->link_layer_registers
->phy_configuration
);
2010 * This method will transmit a hard reset request on the specified phy. The SCU
2011 * hardware requires that we reset the OOB state machine and set the hard reset
2012 * bit in the phy configuration register. We then must start OOB over with the
2013 * hard reset bit set.
2015 static void scu_link_layer_tx_hard_reset(
2016 struct scic_sds_phy
*sci_phy
)
2018 u32 phy_configuration_value
;
2021 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
2022 * to the starting state. */
2023 phy_configuration_value
=
2024 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
2025 phy_configuration_value
|=
2026 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET
) |
2027 SCU_SAS_PCFG_GEN_BIT(OOB_RESET
));
2028 writel(phy_configuration_value
,
2029 &sci_phy
->link_layer_registers
->phy_configuration
);
2031 /* Now take the OOB state machine out of reset */
2032 phy_configuration_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
2033 phy_configuration_value
&= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
2034 writel(phy_configuration_value
,
2035 &sci_phy
->link_layer_registers
->phy_configuration
);
2039 * ****************************************************************************
2040 * * PHY BASE STATE METHODS
2041 * **************************************************************************** */
2045 * @object: This is the object which is cast to a struct scic_sds_phy object.
2047 * This method will perform the actions required by the struct scic_sds_phy on
2048 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2049 * handlers for the phy object base state machine initial state. none
2051 static void scic_sds_phy_initial_state_enter(void *object
)
2053 struct scic_sds_phy
*sci_phy
= object
;
2055 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_INITIAL
);
2060 * @object: This is the object which is cast to a struct scic_sds_phy object.
2062 * This function will perform the actions required by the struct scic_sds_phy on
2063 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2064 * handlers for the phy object base state machine initial state. - The SCU
2065 * hardware is requested to stop the protocol engine. none
2067 static void scic_sds_phy_stopped_state_enter(void *object
)
2069 struct scic_sds_phy
*sci_phy
= object
;
2070 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
2071 struct isci_host
*ihost
= scic_to_ihost(scic
);
2074 * @todo We need to get to the controller to place this PE in a
2078 scic_sds_phy_set_base_state_handlers(sci_phy
,
2079 SCI_BASE_PHY_STATE_STOPPED
);
2081 if (sci_phy
->sata_timeout_timer
!= NULL
) {
2082 isci_del_timer(ihost
, sci_phy
->sata_timeout_timer
);
2084 sci_phy
->sata_timeout_timer
= NULL
;
2087 scu_link_layer_stop_protocol_engine(sci_phy
);
2089 if (sci_phy
->state_machine
.previous_state_id
!=
2090 SCI_BASE_PHY_STATE_INITIAL
)
2091 scic_sds_controller_link_down(
2092 scic_sds_phy_get_controller(sci_phy
),
2093 scic_sds_phy_get_port(sci_phy
),
2099 * @object: This is the object which is cast to a struct scic_sds_phy object.
2101 * This method will perform the actions required by the struct scic_sds_phy on
2102 * entering the SCI_BASE_PHY_STATE_STARTING. - This function sets the state
2103 * handlers for the phy object base state machine starting state. - The SCU
2104 * hardware is requested to start OOB/SN on this protocl engine. - The phy
2105 * starting substate machine is started. - If the previous state was the ready
2106 * state then the struct scic_sds_controller is informed that the phy has gone link
2109 static void scic_sds_phy_starting_state_enter(void *object
)
2111 struct scic_sds_phy
*sci_phy
= object
;
2113 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_STARTING
);
2115 scu_link_layer_stop_protocol_engine(sci_phy
);
2116 scu_link_layer_start_oob(sci_phy
);
2118 /* We don't know what kind of phy we are going to be just yet */
2119 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_UNKNOWN
;
2120 sci_phy
->bcn_received_while_port_unassigned
= false;
2122 /* Change over to the starting substate machine to continue */
2123 sci_base_state_machine_start(&sci_phy
->starting_substate_machine
);
2125 if (sci_phy
->state_machine
.previous_state_id
2126 == SCI_BASE_PHY_STATE_READY
) {
2127 scic_sds_controller_link_down(
2128 scic_sds_phy_get_controller(sci_phy
),
2129 scic_sds_phy_get_port(sci_phy
),
2137 * @object: This is the object which is cast to a struct scic_sds_phy object.
2139 * This method will perform the actions required by the struct scic_sds_phy on
2140 * entering the SCI_BASE_PHY_STATE_READY. - This function sets the state
2141 * handlers for the phy object base state machine ready state. - The SCU
2142 * hardware protocol engine is resumed. - The struct scic_sds_controller is informed
2143 * that the phy object has gone link up. none
2145 static void scic_sds_phy_ready_state_enter(void *object
)
2147 struct scic_sds_phy
*sci_phy
= object
;
2149 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_READY
);
2151 scic_sds_controller_link_up(
2152 scic_sds_phy_get_controller(sci_phy
),
2153 scic_sds_phy_get_port(sci_phy
),
2160 * @object: This is the object which is cast to a struct scic_sds_phy object.
2162 * This method will perform the actions required by the struct scic_sds_phy on exiting
2163 * the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU hardware
2164 * protocol engine represented by this struct scic_sds_phy object. none
2166 static void scic_sds_phy_ready_state_exit(void *object
)
2168 struct scic_sds_phy
*sci_phy
= object
;
2170 scic_sds_phy_suspend(sci_phy
);
2175 * @object: This is the object which is cast to a struct scic_sds_phy object.
2177 * This method will perform the actions required by the struct scic_sds_phy on
2178 * entering the SCI_BASE_PHY_STATE_RESETTING. - This function sets the state
2179 * handlers for the phy object base state machine resetting state. none
2181 static void scic_sds_phy_resetting_state_enter(void *object
)
2183 struct scic_sds_phy
*sci_phy
= object
;
2185 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_RESETTING
);
2188 * The phy is being reset, therefore deactivate it from the port.
2189 * In the resetting state we don't notify the user regarding
2190 * link up and link down notifications. */
2191 scic_sds_port_deactivate_phy(sci_phy
->owning_port
, sci_phy
, false);
2193 if (sci_phy
->protocol
== SCIC_SDS_PHY_PROTOCOL_SAS
) {
2194 scu_link_layer_tx_hard_reset(sci_phy
);
2197 * The SCU does not need to have a discrete reset state so
2198 * just go back to the starting state.
2200 sci_base_state_machine_change_state(
2201 &sci_phy
->state_machine
,
2202 SCI_BASE_PHY_STATE_STARTING
);
2208 * @object: This is the object which is cast to a struct scic_sds_phy object.
2210 * This method will perform the actions required by the struct scic_sds_phy on
2211 * entering the SCI_BASE_PHY_STATE_FINAL. - This function sets the state
2212 * handlers for the phy object base state machine final state. none
2214 static void scic_sds_phy_final_state_enter(void *object
)
2216 struct scic_sds_phy
*sci_phy
= object
;
2218 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_FINAL
);
2220 /* Nothing to do here */
2223 /* --------------------------------------------------------------------------- */
2225 static const struct sci_base_state scic_sds_phy_state_table
[] = {
2226 [SCI_BASE_PHY_STATE_INITIAL
] = {
2227 .enter_state
= scic_sds_phy_initial_state_enter
,
2229 [SCI_BASE_PHY_STATE_STOPPED
] = {
2230 .enter_state
= scic_sds_phy_stopped_state_enter
,
2232 [SCI_BASE_PHY_STATE_STARTING
] = {
2233 .enter_state
= scic_sds_phy_starting_state_enter
,
2235 [SCI_BASE_PHY_STATE_READY
] = {
2236 .enter_state
= scic_sds_phy_ready_state_enter
,
2237 .exit_state
= scic_sds_phy_ready_state_exit
,
2239 [SCI_BASE_PHY_STATE_RESETTING
] = {
2240 .enter_state
= scic_sds_phy_resetting_state_enter
,
2242 [SCI_BASE_PHY_STATE_FINAL
] = {
2243 .enter_state
= scic_sds_phy_final_state_enter
,
2247 void scic_sds_phy_construct(struct scic_sds_phy
*sci_phy
,
2248 struct scic_sds_port
*owning_port
, u8 phy_index
)
2250 sci_base_state_machine_construct(&sci_phy
->state_machine
,
2252 scic_sds_phy_state_table
,
2253 SCI_BASE_PHY_STATE_INITIAL
);
2255 sci_base_state_machine_start(&sci_phy
->state_machine
);
2257 /* Copy the rest of the input data to our locals */
2258 sci_phy
->owning_port
= owning_port
;
2259 sci_phy
->phy_index
= phy_index
;
2260 sci_phy
->bcn_received_while_port_unassigned
= false;
2261 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_UNKNOWN
;
2262 sci_phy
->link_layer_registers
= NULL
;
2263 sci_phy
->max_negotiated_speed
= SAS_LINK_RATE_UNKNOWN
;
2264 sci_phy
->sata_timeout_timer
= NULL
;
2266 /* Initialize the the substate machines */
2267 sci_base_state_machine_construct(&sci_phy
->starting_substate_machine
,
2269 scic_sds_phy_starting_substates
,
2270 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
);
2273 void isci_phy_init(struct isci_phy
*iphy
, struct isci_host
*ihost
, int index
)
2275 union scic_oem_parameters oem
;
2279 scic_oem_parameters_get(&ihost
->sci
, &oem
);
2280 sci_sas_addr
= oem
.sds1
.phys
[index
].sas_address
.high
;
2281 sci_sas_addr
<<= 32;
2282 sci_sas_addr
|= oem
.sds1
.phys
[index
].sas_address
.low
;
2283 sas_addr
= cpu_to_be64(sci_sas_addr
);
2284 memcpy(iphy
->sas_addr
, &sas_addr
, sizeof(sas_addr
));
2286 iphy
->isci_port
= NULL
;
2287 iphy
->sas_phy
.enabled
= 0;
2288 iphy
->sas_phy
.id
= index
;
2289 iphy
->sas_phy
.sas_addr
= &iphy
->sas_addr
[0];
2290 iphy
->sas_phy
.frame_rcvd
= (u8
*)&iphy
->frame_rcvd
;
2291 iphy
->sas_phy
.ha
= &ihost
->sas_ha
;
2292 iphy
->sas_phy
.lldd_phy
= iphy
;
2293 iphy
->sas_phy
.enabled
= 1;
2294 iphy
->sas_phy
.class = SAS
;
2295 iphy
->sas_phy
.iproto
= SAS_PROTOCOL_ALL
;
2296 iphy
->sas_phy
.tproto
= 0;
2297 iphy
->sas_phy
.type
= PHY_TYPE_PHYSICAL
;
2298 iphy
->sas_phy
.role
= PHY_ROLE_INITIATOR
;
2299 iphy
->sas_phy
.oob_mode
= OOB_NOT_CONNECTED
;
2300 iphy
->sas_phy
.linkrate
= SAS_LINK_RATE_UNKNOWN
;
2301 memset(&iphy
->frame_rcvd
, 0, sizeof(iphy
->frame_rcvd
));
2306 * isci_phy_control() - This function is one of the SAS Domain Template
2307 * functions. This is a phy management function.
2308 * @phy: This parameter specifies the sphy being controlled.
2309 * @func: This parameter specifies the phy control function being invoked.
2310 * @buf: This parameter is specific to the phy function being invoked.
2312 * status, zero indicates success.
2314 int isci_phy_control(struct asd_sas_phy
*sas_phy
,
2319 struct isci_phy
*iphy
= sas_phy
->lldd_phy
;
2320 struct isci_port
*iport
= iphy
->isci_port
;
2321 struct isci_host
*ihost
= sas_phy
->ha
->lldd_ha
;
2322 unsigned long flags
;
2324 dev_dbg(&ihost
->pdev
->dev
,
2325 "%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
2326 __func__
, sas_phy
, func
, buf
, iphy
, iport
);
2329 case PHY_FUNC_DISABLE
:
2330 spin_lock_irqsave(&ihost
->scic_lock
, flags
);
2331 scic_sds_phy_stop(&iphy
->sci
);
2332 spin_unlock_irqrestore(&ihost
->scic_lock
, flags
);
2335 case PHY_FUNC_LINK_RESET
:
2336 spin_lock_irqsave(&ihost
->scic_lock
, flags
);
2337 scic_sds_phy_stop(&iphy
->sci
);
2338 scic_sds_phy_start(&iphy
->sci
);
2339 spin_unlock_irqrestore(&ihost
->scic_lock
, flags
);
2342 case PHY_FUNC_HARD_RESET
:
2346 /* Perform the port reset. */
2347 ret
= isci_port_perform_hard_reset(ihost
, iport
, iphy
);
2352 dev_dbg(&ihost
->pdev
->dev
,
2353 "%s: phy %p; func %d NOT IMPLEMENTED!\n",
2354 __func__
, sas_phy
, func
);