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"
61 #include "probe_roms.h"
63 /* Maximum arbitration wait time in micro-seconds */
64 #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
66 enum sas_linkrate
sci_phy_linkrate(struct scic_sds_phy
*sci_phy
)
68 return sci_phy
->max_negotiated_speed
;
72 * *****************************************************************************
73 * * SCIC SDS PHY Internal Methods
74 * ***************************************************************************** */
77 * This method will initialize the phy transport layer registers
79 * @transport_layer_registers
83 static enum sci_status
scic_sds_phy_transport_layer_initialization(
84 struct scic_sds_phy
*sci_phy
,
85 struct scu_transport_layer_registers __iomem
*transport_layer_registers
)
89 sci_phy
->transport_layer_registers
= transport_layer_registers
;
91 writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
,
92 &sci_phy
->transport_layer_registers
->stp_rni
);
95 * Hardware team recommends that we enable the STP prefetch for all
98 tl_control
= readl(&sci_phy
->transport_layer_registers
->control
);
99 tl_control
|= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH
);
100 writel(tl_control
, &sci_phy
->transport_layer_registers
->control
);
106 * This method will initialize the phy link layer registers
108 * @link_layer_registers:
112 static enum sci_status
113 scic_sds_phy_link_layer_initialization(struct scic_sds_phy
*sci_phy
,
114 struct scu_link_layer_registers __iomem
*link_layer_registers
)
116 struct scic_sds_controller
*scic
=
117 sci_phy
->owning_port
->owning_controller
;
118 int phy_idx
= sci_phy
->phy_index
;
119 struct sci_phy_user_params
*phy_user
=
120 &scic
->user_parameters
.sds1
.phys
[phy_idx
];
121 struct sci_phy_oem_params
*phy_oem
=
122 &scic
->oem_parameters
.sds1
.phys
[phy_idx
];
123 u32 phy_configuration
;
124 struct scic_phy_cap phy_cap
;
125 u32 parity_check
= 0;
126 u32 parity_count
= 0;
127 u32 llctl
, link_rate
;
130 sci_phy
->link_layer_registers
= link_layer_registers
;
132 /* Set our IDENTIFY frame data */
133 #define SCI_END_DEVICE 0x01
135 writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR
) |
136 SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR
) |
137 SCU_SAS_TIID_GEN_BIT(STP_INITIATOR
) |
138 SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST
) |
139 SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE
, SCI_END_DEVICE
),
140 &sci_phy
->link_layer_registers
->transmit_identification
);
142 /* Write the device SAS Address */
144 &sci_phy
->link_layer_registers
->sas_device_name_high
);
145 writel(phy_idx
, &sci_phy
->link_layer_registers
->sas_device_name_low
);
147 /* Write the source SAS Address */
148 writel(phy_oem
->sas_address
.high
,
149 &sci_phy
->link_layer_registers
->source_sas_address_high
);
150 writel(phy_oem
->sas_address
.low
,
151 &sci_phy
->link_layer_registers
->source_sas_address_low
);
153 /* Clear and Set the PHY Identifier */
154 writel(0, &sci_phy
->link_layer_registers
->identify_frame_phy_id
);
155 writel(SCU_SAS_TIPID_GEN_VALUE(ID
, phy_idx
),
156 &sci_phy
->link_layer_registers
->identify_frame_phy_id
);
158 /* Change the initial state of the phy configuration register */
160 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
162 /* Hold OOB state machine in reset */
163 phy_configuration
|= SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
164 writel(phy_configuration
,
165 &sci_phy
->link_layer_registers
->phy_configuration
);
167 /* Configure the SNW capabilities */
170 phy_cap
.gen3_no_ssc
= 1;
171 phy_cap
.gen2_no_ssc
= 1;
172 phy_cap
.gen1_no_ssc
= 1;
173 if (scic
->oem_parameters
.sds1
.controller
.do_enable_ssc
== true) {
174 phy_cap
.gen3_ssc
= 1;
175 phy_cap
.gen2_ssc
= 1;
176 phy_cap
.gen1_ssc
= 1;
180 * The SAS specification indicates that the phy_capabilities that
181 * are transmitted shall have an even parity. Calculate the parity. */
182 parity_check
= phy_cap
.all
;
183 while (parity_check
!= 0) {
184 if (parity_check
& 0x1)
190 * If parity indicates there are an odd number of bits set, then
191 * set the parity bit to 1 in the phy capabilities. */
192 if ((parity_count
% 2) != 0)
195 writel(phy_cap
.all
, &sci_phy
->link_layer_registers
->phy_capabilities
);
197 /* Set the enable spinup period but disable the ability to send
198 * notify enable spinup
200 writel(SCU_ENSPINUP_GEN_VAL(COUNT
,
201 phy_user
->notify_enable_spin_up_insertion_frequency
),
202 &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
204 /* Write the ALIGN Insertion Ferequency for connected phy and
205 * inpendent of connected state
207 clksm_value
= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED
,
208 phy_user
->in_connection_align_insertion_frequency
);
210 clksm_value
|= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL
,
211 phy_user
->align_insertion_frequency
);
213 writel(clksm_value
, &sci_phy
->link_layer_registers
->clock_skew_management
);
215 /* @todo Provide a way to write this register correctly */
217 &sci_phy
->link_layer_registers
->afe_lookup_table_control
);
219 llctl
= SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT
,
220 (u8
)scic
->user_parameters
.sds1
.no_outbound_task_timeout
);
222 switch(phy_user
->max_speed_generation
) {
223 case SCIC_SDS_PARM_GEN3_SPEED
:
224 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3
;
226 case SCIC_SDS_PARM_GEN2_SPEED
:
227 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2
;
230 link_rate
= SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1
;
233 llctl
|= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE
, link_rate
);
234 writel(llctl
, &sci_phy
->link_layer_registers
->link_layer_control
);
236 if (is_a0() || is_a2()) {
237 /* Program the max ARB time for the PHY to 700us so we inter-operate with
238 * the PMC expander which shuts down PHYs if the expander PHY generates too
239 * many breaks. This time value will guarantee that the initiator PHY will
240 * generate the break.
242 writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME
,
243 &sci_phy
->link_layer_registers
->maximum_arbitration_wait_timer_timeout
);
247 * Set the link layer hang detection to 500ms (0x1F4) from its default
248 * value of 128ms. Max value is 511 ms.
250 writel(0x1F4, &sci_phy
->link_layer_registers
->link_layer_hang_detection_timeout
);
252 /* We can exit the initial state to the stopped state */
253 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
254 SCI_BASE_PHY_STATE_STOPPED
);
260 * This function will handle the sata SIGNATURE FIS timeout condition. It will
261 * restart the starting substate machine since we dont know what has actually
264 static void scic_sds_phy_sata_timeout(void *phy
)
266 struct scic_sds_phy
*sci_phy
= phy
;
268 dev_dbg(sciphy_to_dev(sci_phy
),
269 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
274 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
275 SCI_BASE_PHY_STATE_STARTING
);
279 * This method returns the port currently containing this phy. If the phy is
280 * currently contained by the dummy port, then the phy is considered to not
282 * @sci_phy: This parameter specifies the phy for which to retrieve the
285 * This method returns a handle to a port that contains the supplied phy.
286 * NULL This value is returned if the phy is not part of a real
287 * port (i.e. it's contained in the dummy port). !NULL All other
288 * values indicate a handle/pointer to the port containing the phy.
290 struct scic_sds_port
*scic_sds_phy_get_port(
291 struct scic_sds_phy
*sci_phy
)
293 if (scic_sds_port_get_index(sci_phy
->owning_port
) == SCIC_SDS_DUMMY_PORT
)
296 return sci_phy
->owning_port
;
300 * This method will assign a port to the phy object.
301 * @out]: sci_phy This parameter specifies the phy for which to assign a port
306 void scic_sds_phy_set_port(
307 struct scic_sds_phy
*sci_phy
,
308 struct scic_sds_port
*sci_port
)
310 sci_phy
->owning_port
= sci_port
;
312 if (sci_phy
->bcn_received_while_port_unassigned
) {
313 sci_phy
->bcn_received_while_port_unassigned
= false;
314 scic_sds_port_broadcast_change_received(sci_phy
->owning_port
, sci_phy
);
319 * This method will initialize the constructed phy
321 * @link_layer_registers:
325 enum sci_status
scic_sds_phy_initialize(
326 struct scic_sds_phy
*sci_phy
,
327 struct scu_transport_layer_registers __iomem
*transport_layer_registers
,
328 struct scu_link_layer_registers __iomem
*link_layer_registers
)
330 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
331 struct isci_host
*ihost
= scic_to_ihost(scic
);
333 /* Create the SIGNATURE FIS Timeout timer for this phy */
334 sci_phy
->sata_timeout_timer
=
338 scic_sds_phy_sata_timeout
);
340 /* Perfrom the initialization of the TL hardware */
341 scic_sds_phy_transport_layer_initialization(
343 transport_layer_registers
);
345 /* Perofrm the initialization of the PE hardware */
346 scic_sds_phy_link_layer_initialization(sci_phy
, link_layer_registers
);
349 * There is nothing that needs to be done in this state just
350 * transition to the stopped state. */
351 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
352 SCI_BASE_PHY_STATE_STOPPED
);
358 * This method assigns the direct attached device ID for this phy.
360 * @sci_phy The phy for which the direct attached device id is to
362 * @device_id The direct attached device ID to assign to the phy.
363 * This will either be the RNi for the device or an invalid RNi if there
364 * is no current device assigned to the phy.
366 void scic_sds_phy_setup_transport(
367 struct scic_sds_phy
*sci_phy
,
372 writel(device_id
, &sci_phy
->transport_layer_registers
->stp_rni
);
375 * The read should guarantee that the first write gets posted
376 * before the next write
378 tl_control
= readl(&sci_phy
->transport_layer_registers
->control
);
379 tl_control
|= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE
);
380 writel(tl_control
, &sci_phy
->transport_layer_registers
->control
);
385 * @sci_phy: The phy object to be suspended.
387 * This function will perform the register reads/writes to suspend the SCU
388 * hardware protocol engine. none
390 static void scic_sds_phy_suspend(
391 struct scic_sds_phy
*sci_phy
)
393 u32 scu_sas_pcfg_value
;
396 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
397 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
);
398 writel(scu_sas_pcfg_value
,
399 &sci_phy
->link_layer_registers
->phy_configuration
);
401 scic_sds_phy_setup_transport(
403 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
);
406 void scic_sds_phy_resume(struct scic_sds_phy
*sci_phy
)
408 u32 scu_sas_pcfg_value
;
411 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
412 scu_sas_pcfg_value
&= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
);
413 writel(scu_sas_pcfg_value
,
414 &sci_phy
->link_layer_registers
->phy_configuration
);
417 void scic_sds_phy_get_sas_address(struct scic_sds_phy
*sci_phy
,
418 struct sci_sas_address
*sas_address
)
420 sas_address
->high
= readl(&sci_phy
->link_layer_registers
->source_sas_address_high
);
421 sas_address
->low
= readl(&sci_phy
->link_layer_registers
->source_sas_address_low
);
424 void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy
*sci_phy
,
425 struct sci_sas_address
*sas_address
)
427 struct sas_identify_frame
*iaf
;
428 struct isci_phy
*iphy
= sci_phy_to_iphy(sci_phy
);
430 iaf
= &iphy
->frame_rcvd
.iaf
;
431 memcpy(sas_address
, iaf
->sas_addr
, SAS_ADDR_SIZE
);
434 void scic_sds_phy_get_protocols(struct scic_sds_phy
*sci_phy
,
435 struct scic_phy_proto
*protocols
)
438 (u16
)(readl(&sci_phy
->
439 link_layer_registers
->transmit_identification
) &
443 enum sci_status
scic_sds_phy_start(struct scic_sds_phy
*sci_phy
)
445 struct scic_sds_controller
*scic
= sci_phy
->owning_port
->owning_controller
;
446 enum scic_sds_phy_states state
= sci_phy
->state_machine
.current_state_id
;
447 struct isci_host
*ihost
= scic_to_ihost(scic
);
449 if (state
!= SCI_BASE_PHY_STATE_STOPPED
) {
450 dev_dbg(sciphy_to_dev(sci_phy
),
451 "%s: in wrong state: %d\n", __func__
, state
);
452 return SCI_FAILURE_INVALID_STATE
;
455 /* Create the SIGNATURE FIS Timeout timer for this phy */
456 sci_phy
->sata_timeout_timer
= isci_timer_create(ihost
, sci_phy
,
457 scic_sds_phy_sata_timeout
);
459 if (sci_phy
->sata_timeout_timer
)
460 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
461 SCI_BASE_PHY_STATE_STARTING
);
466 enum sci_status
scic_sds_phy_stop(struct scic_sds_phy
*sci_phy
)
468 enum scic_sds_phy_states state
= sci_phy
->state_machine
.current_state_id
;
471 case SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
:
472 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
:
473 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
:
474 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
:
475 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
:
476 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
:
477 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
:
478 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
:
479 case SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
:
480 case SCI_BASE_PHY_STATE_READY
:
483 dev_dbg(sciphy_to_dev(sci_phy
),
484 "%s: in wrong state: %d\n", __func__
, state
);
485 return SCI_FAILURE_INVALID_STATE
;
488 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
489 SCI_BASE_PHY_STATE_STOPPED
);
493 enum sci_status
scic_sds_phy_reset(struct scic_sds_phy
*sci_phy
)
495 enum scic_sds_phy_states state
= sci_phy
->state_machine
.current_state_id
;
497 if (state
!= SCI_BASE_PHY_STATE_READY
) {
498 dev_dbg(sciphy_to_dev(sci_phy
),
499 "%s: in wrong state: %d\n", __func__
, state
);
500 return SCI_FAILURE_INVALID_STATE
;
503 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
504 SCI_BASE_PHY_STATE_RESETTING
);
509 * This method will process the event code received.
515 enum sci_status
scic_sds_phy_event_handler(
516 struct scic_sds_phy
*sci_phy
,
519 return sci_phy
->state_handlers
->event_handler(sci_phy
, event_code
);
523 * This method will process the frame index received.
529 enum sci_status
scic_sds_phy_frame_handler(
530 struct scic_sds_phy
*sci_phy
,
533 return sci_phy
->state_handlers
->frame_handler(sci_phy
, frame_index
);
537 * This method will give the phy permission to consume power
542 enum sci_status
scic_sds_phy_consume_power_handler(
543 struct scic_sds_phy
*sci_phy
)
545 return sci_phy
->state_handlers
->consume_power_handler(sci_phy
);
549 * *****************************************************************************
550 * * SCIC SDS PHY HELPER FUNCTIONS
551 * ***************************************************************************** */
556 * @sci_phy: The phy object that received SAS PHY DETECTED.
558 * This method continues the link training for the phy as if it were a SAS PHY
559 * instead of a SATA PHY. This is done because the completion queue had a SAS
560 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
563 static void scic_sds_phy_start_sas_link_training(
564 struct scic_sds_phy
*sci_phy
)
569 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
570 phy_control
|= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
);
572 &sci_phy
->link_layer_registers
->phy_configuration
);
574 sci_base_state_machine_change_state(
575 &sci_phy
->state_machine
,
576 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
579 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SAS
;
584 * @sci_phy: The phy object that received a SATA SPINUP HOLD event
586 * This method continues the link training for the phy as if it were a SATA PHY
587 * instead of a SAS PHY. This is done because the completion queue had a SATA
588 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
590 static void scic_sds_phy_start_sata_link_training(
591 struct scic_sds_phy
*sci_phy
)
593 sci_base_state_machine_change_state(
594 &sci_phy
->state_machine
,
595 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
598 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SATA
;
602 * scic_sds_phy_complete_link_training - perform processing common to
603 * all protocols upon completion of link training.
604 * @sci_phy: This parameter specifies the phy object for which link training
606 * @max_link_rate: This parameter specifies the maximum link rate to be
607 * associated with this phy.
608 * @next_state: This parameter specifies the next state for the phy's starting
612 static void scic_sds_phy_complete_link_training(
613 struct scic_sds_phy
*sci_phy
,
614 enum sas_linkrate max_link_rate
,
617 sci_phy
->max_negotiated_speed
= max_link_rate
;
619 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
623 static void scic_sds_phy_restart_starting_state(
624 struct scic_sds_phy
*sci_phy
)
626 /* Re-enter the base state machine starting state */
627 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
628 SCI_BASE_PHY_STATE_STARTING
);
633 * @phy: This struct scic_sds_phy object which has received an event.
634 * @event_code: This is the event code which the phy object is to decode.
636 * This method is called when an event notification is received for the phy
637 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
638 * decode the event - sas phy detected causes a state transition to the wait
639 * for speed event notification. - any other events log a warning message and
640 * set a failure status enum sci_status SCI_SUCCESS on any valid event notification
641 * SCI_FAILURE on any unexpected event notifation
643 static enum sci_status
scic_sds_phy_starting_substate_await_ossp_event_handler(
644 struct scic_sds_phy
*sci_phy
,
647 u32 result
= SCI_SUCCESS
;
649 switch (scu_get_event_code(event_code
)) {
650 case SCU_EVENT_SAS_PHY_DETECTED
:
651 scic_sds_phy_start_sas_link_training(sci_phy
);
652 sci_phy
->is_in_link_training
= true;
655 case SCU_EVENT_SATA_SPINUP_HOLD
:
656 scic_sds_phy_start_sata_link_training(sci_phy
);
657 sci_phy
->is_in_link_training
= true;
661 dev_dbg(sciphy_to_dev(sci_phy
),
662 "%s: PHY starting substate machine received "
663 "unexpected event_code %x\n",
667 result
= SCI_FAILURE
;
676 * @phy: This struct scic_sds_phy object which has received an event.
677 * @event_code: This is the event code which the phy object is to decode.
679 * This method is called when an event notification is received for the phy
680 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
681 * decode the event - sas phy detected returns us back to this state. - speed
682 * event detected causes a state transition to the wait for iaf. - identify
683 * timeout is an un-expected event and the state machine is restarted. - link
684 * failure events restart the starting state machine - any other events log a
685 * warning message and set a failure status enum sci_status SCI_SUCCESS on any valid
686 * event notification SCI_FAILURE on any unexpected event notifation
688 static enum sci_status
scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler(
689 struct scic_sds_phy
*sci_phy
,
692 u32 result
= SCI_SUCCESS
;
694 switch (scu_get_event_code(event_code
)) {
695 case SCU_EVENT_SAS_PHY_DETECTED
:
697 * Why is this being reported again by the controller?
698 * We would re-enter this state so just stay here */
701 case SCU_EVENT_SAS_15
:
702 case SCU_EVENT_SAS_15_SSC
:
703 scic_sds_phy_complete_link_training(
705 SAS_LINK_RATE_1_5_GBPS
,
706 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
709 case SCU_EVENT_SAS_30
:
710 case SCU_EVENT_SAS_30_SSC
:
711 scic_sds_phy_complete_link_training(
713 SAS_LINK_RATE_3_0_GBPS
,
714 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
717 case SCU_EVENT_SAS_60
:
718 case SCU_EVENT_SAS_60_SSC
:
719 scic_sds_phy_complete_link_training(
721 SAS_LINK_RATE_6_0_GBPS
,
722 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
);
725 case SCU_EVENT_SATA_SPINUP_HOLD
:
727 * We were doing SAS PHY link training and received a SATA PHY event
728 * continue OOB/SN as if this were a SATA PHY */
729 scic_sds_phy_start_sata_link_training(sci_phy
);
732 case SCU_EVENT_LINK_FAILURE
:
733 /* Link failure change state back to the starting state */
734 scic_sds_phy_restart_starting_state(sci_phy
);
738 dev_warn(sciphy_to_dev(sci_phy
),
739 "%s: PHY starting substate machine received "
740 "unexpected event_code %x\n",
744 result
= SCI_FAILURE
;
753 * @phy: This struct scic_sds_phy object which has received an event.
754 * @event_code: This is the event code which the phy object is to decode.
756 * This method is called when an event notification is received for the phy
757 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. -
758 * decode the event - sas phy detected event backs up the state machine to the
759 * await speed notification. - identify timeout is an un-expected event and the
760 * state machine is restarted. - link failure events restart the starting state
761 * machine - any other events log a warning message and set a failure status
762 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
763 * unexpected event notifation
765 static enum sci_status
scic_sds_phy_starting_substate_await_iaf_uf_event_handler(
766 struct scic_sds_phy
*sci_phy
,
769 u32 result
= SCI_SUCCESS
;
771 switch (scu_get_event_code(event_code
)) {
772 case SCU_EVENT_SAS_PHY_DETECTED
:
773 /* Backup the state machine */
774 scic_sds_phy_start_sas_link_training(sci_phy
);
777 case SCU_EVENT_SATA_SPINUP_HOLD
:
779 * We were doing SAS PHY link training and received a SATA PHY event
780 * continue OOB/SN as if this were a SATA PHY */
781 scic_sds_phy_start_sata_link_training(sci_phy
);
784 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT
:
785 case SCU_EVENT_LINK_FAILURE
:
786 case SCU_EVENT_HARD_RESET_RECEIVED
:
787 /* Start the oob/sn state machine over again */
788 scic_sds_phy_restart_starting_state(sci_phy
);
792 dev_warn(sciphy_to_dev(sci_phy
),
793 "%s: PHY starting substate machine received "
794 "unexpected event_code %x\n",
798 result
= SCI_FAILURE
;
807 * @phy: This struct scic_sds_phy object which has received an event.
808 * @event_code: This is the event code which the phy object is to decode.
810 * This method is called when an event notification is received for the phy
811 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. -
812 * decode the event - link failure events restart the starting state machine -
813 * any other events log a warning message and set a failure status enum sci_status
814 * SCI_SUCCESS on a link failure event SCI_FAILURE on any unexpected event
817 static enum sci_status
scic_sds_phy_starting_substate_await_sas_power_event_handler(
818 struct scic_sds_phy
*sci_phy
,
821 u32 result
= SCI_SUCCESS
;
823 switch (scu_get_event_code(event_code
)) {
824 case SCU_EVENT_LINK_FAILURE
:
825 /* Link failure change state back to the starting state */
826 scic_sds_phy_restart_starting_state(sci_phy
);
830 dev_warn(sciphy_to_dev(sci_phy
),
831 "%s: PHY starting substate machine received unexpected "
836 result
= SCI_FAILURE
;
845 * @phy: This struct scic_sds_phy object which has received an event.
846 * @event_code: This is the event code which the phy object is to decode.
848 * This method is called when an event notification is received for the phy
849 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. -
850 * decode the event - link failure events restart the starting state machine -
851 * sata spinup hold events are ignored since they are expected - any other
852 * events log a warning message and set a failure status enum sci_status SCI_SUCCESS
853 * on a link failure event SCI_FAILURE on any unexpected event notifation
855 static enum sci_status
scic_sds_phy_starting_substate_await_sata_power_event_handler(
856 struct scic_sds_phy
*sci_phy
,
859 u32 result
= SCI_SUCCESS
;
861 switch (scu_get_event_code(event_code
)) {
862 case SCU_EVENT_LINK_FAILURE
:
863 /* Link failure change state back to the starting state */
864 scic_sds_phy_restart_starting_state(sci_phy
);
867 case SCU_EVENT_SATA_SPINUP_HOLD
:
868 /* These events are received every 10ms and are expected while in this state */
871 case SCU_EVENT_SAS_PHY_DETECTED
:
873 * There has been a change in the phy type before OOB/SN for the
874 * SATA finished start down the SAS link traning path. */
875 scic_sds_phy_start_sas_link_training(sci_phy
);
879 dev_warn(sciphy_to_dev(sci_phy
),
880 "%s: PHY starting substate machine received "
881 "unexpected event_code %x\n",
885 result
= SCI_FAILURE
;
893 * scic_sds_phy_starting_substate_await_sata_phy_event_handler -
894 * @phy: This struct scic_sds_phy object which has received an event.
895 * @event_code: This is the event code which the phy object is to decode.
897 * This method is called when an event notification is received for the phy
898 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. -
899 * decode the event - link failure events restart the starting state machine -
900 * sata spinup hold events are ignored since they are expected - sata phy
901 * detected event change to the wait speed event - any other events log a
902 * warning message and set a failure status enum sci_status SCI_SUCCESS on a link
903 * failure event SCI_FAILURE on any unexpected event notifation
905 static enum sci_status
scic_sds_phy_starting_substate_await_sata_phy_event_handler(
906 struct scic_sds_phy
*sci_phy
, u32 event_code
)
908 u32 result
= SCI_SUCCESS
;
910 switch (scu_get_event_code(event_code
)) {
911 case SCU_EVENT_LINK_FAILURE
:
912 /* Link failure change state back to the starting state */
913 scic_sds_phy_restart_starting_state(sci_phy
);
916 case SCU_EVENT_SATA_SPINUP_HOLD
:
917 /* These events might be received since we dont know how many may be in
918 * the completion queue while waiting for power
922 case SCU_EVENT_SATA_PHY_DETECTED
:
923 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_SATA
;
925 /* We have received the SATA PHY notification change state */
926 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
927 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
930 case SCU_EVENT_SAS_PHY_DETECTED
:
931 /* There has been a change in the phy type before OOB/SN for the
932 * SATA finished start down the SAS link traning path.
934 scic_sds_phy_start_sas_link_training(sci_phy
);
938 dev_warn(sciphy_to_dev(sci_phy
),
939 "%s: PHY starting substate machine received "
940 "unexpected event_code %x\n",
944 result
= SCI_FAILURE
;
953 * @phy: This struct scic_sds_phy object which has received an event.
954 * @event_code: This is the event code which the phy object is to decode.
956 * This method is called when an event notification is received for the phy
957 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
958 * - decode the event - sata phy detected returns us back to this state. -
959 * speed event detected causes a state transition to the wait for signature. -
960 * link failure events restart the starting state machine - any other events
961 * log a warning message and set a failure status enum sci_status SCI_SUCCESS on any
962 * valid event notification SCI_FAILURE on any unexpected event notifation
964 static enum sci_status
scic_sds_phy_starting_substate_await_sata_speed_event_handler(
965 struct scic_sds_phy
*sci_phy
,
968 u32 result
= SCI_SUCCESS
;
970 switch (scu_get_event_code(event_code
)) {
971 case SCU_EVENT_SATA_PHY_DETECTED
:
973 * The hardware reports multiple SATA PHY detected events
974 * ignore the extras */
977 case SCU_EVENT_SATA_15
:
978 case SCU_EVENT_SATA_15_SSC
:
979 scic_sds_phy_complete_link_training(
981 SAS_LINK_RATE_1_5_GBPS
,
982 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
985 case SCU_EVENT_SATA_30
:
986 case SCU_EVENT_SATA_30_SSC
:
987 scic_sds_phy_complete_link_training(
989 SAS_LINK_RATE_3_0_GBPS
,
990 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
993 case SCU_EVENT_SATA_60
:
994 case SCU_EVENT_SATA_60_SSC
:
995 scic_sds_phy_complete_link_training(
997 SAS_LINK_RATE_6_0_GBPS
,
998 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
1001 case SCU_EVENT_LINK_FAILURE
:
1002 /* Link failure change state back to the starting state */
1003 scic_sds_phy_restart_starting_state(sci_phy
);
1006 case SCU_EVENT_SAS_PHY_DETECTED
:
1008 * There has been a change in the phy type before OOB/SN for the
1009 * SATA finished start down the SAS link traning path. */
1010 scic_sds_phy_start_sas_link_training(sci_phy
);
1014 dev_warn(sciphy_to_dev(sci_phy
),
1015 "%s: PHY starting substate machine received "
1016 "unexpected event_code %x\n",
1020 result
= SCI_FAILURE
;
1028 * scic_sds_phy_starting_substate_await_sig_fis_event_handler -
1029 * @phy: This struct scic_sds_phy object which has received an event.
1030 * @event_code: This is the event code which the phy object is to decode.
1032 * This method is called when an event notification is received for the phy
1033 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. -
1034 * decode the event - sas phy detected event backs up the state machine to the
1035 * await speed notification. - identify timeout is an un-expected event and the
1036 * state machine is restarted. - link failure events restart the starting state
1037 * machine - any other events log a warning message and set a failure status
1038 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
1039 * unexpected event notifation
1041 static enum sci_status
scic_sds_phy_starting_substate_await_sig_fis_event_handler(
1042 struct scic_sds_phy
*sci_phy
, u32 event_code
)
1044 u32 result
= SCI_SUCCESS
;
1046 switch (scu_get_event_code(event_code
)) {
1047 case SCU_EVENT_SATA_PHY_DETECTED
:
1048 /* Backup the state machine */
1049 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1050 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
1053 case SCU_EVENT_LINK_FAILURE
:
1054 /* Link failure change state back to the starting state */
1055 scic_sds_phy_restart_starting_state(sci_phy
);
1059 dev_warn(sciphy_to_dev(sci_phy
),
1060 "%s: PHY starting substate machine received "
1061 "unexpected event_code %x\n",
1065 result
= SCI_FAILURE
;
1074 * *****************************************************************************
1075 * * SCIC SDS PHY FRAME_HANDLERS
1076 * ***************************************************************************** */
1080 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1082 * @frame_index: This is the index of the unsolicited frame which was received
1085 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1086 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Get the UF Header - If the UF
1087 * is an IAF - Copy IAF data to local phy object IAF data buffer. - Change
1088 * starting substate to wait power. - else - log warning message of unexpected
1089 * unsolicted frame - release frame buffer enum sci_status SCI_SUCCESS
1091 static enum sci_status
scic_sds_phy_starting_substate_await_iaf_uf_frame_handler(
1092 struct scic_sds_phy
*sci_phy
, u32 frame_index
)
1094 enum sci_status result
;
1096 struct sas_identify_frame iaf
;
1097 struct isci_phy
*iphy
= sci_phy_to_iphy(sci_phy
);
1099 result
= scic_sds_unsolicited_frame_control_get_header(
1100 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1102 (void **)&frame_words
);
1104 if (result
!= SCI_SUCCESS
)
1107 sci_swab32_cpy(&iaf
, frame_words
, sizeof(iaf
) / sizeof(u32
));
1108 if (iaf
.frame_type
== 0) {
1111 memcpy(&iphy
->frame_rcvd
.iaf
, &iaf
, sizeof(iaf
));
1112 if (iaf
.smp_tport
) {
1113 /* We got the IAF for an expander PHY go to the final
1114 * state since there are no power requirements for
1117 state
= SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
;
1119 /* We got the IAF we can now go to the await spinup
1122 state
= SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
;
1124 sci_base_state_machine_change_state(
1125 &sci_phy
->state_machine
,
1127 result
= SCI_SUCCESS
;
1129 dev_warn(sciphy_to_dev(sci_phy
),
1130 "%s: PHY starting substate machine received "
1131 "unexpected frame id %x\n",
1135 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy
),
1143 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1145 * @frame_index: This is the index of the unsolicited frame which was received
1148 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1149 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Get the UF Header - If
1150 * the UF is an SIGNATURE FIS - Copy IAF data to local phy object SIGNATURE FIS
1151 * data buffer. - else - log warning message of unexpected unsolicted frame -
1152 * release frame buffer enum sci_status SCI_SUCCESS Must decode the SIGNATURE FIS
1155 static enum sci_status
scic_sds_phy_starting_substate_await_sig_fis_frame_handler(
1156 struct scic_sds_phy
*sci_phy
,
1159 enum sci_status result
;
1160 struct dev_to_host_fis
*frame_header
;
1161 u32
*fis_frame_data
;
1162 struct isci_phy
*iphy
= sci_phy_to_iphy(sci_phy
);
1164 result
= scic_sds_unsolicited_frame_control_get_header(
1165 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1167 (void **)&frame_header
);
1169 if (result
!= SCI_SUCCESS
)
1172 if ((frame_header
->fis_type
== FIS_REGD2H
) &&
1173 !(frame_header
->status
& ATA_BUSY
)) {
1174 scic_sds_unsolicited_frame_control_get_buffer(
1175 &(scic_sds_phy_get_controller(sci_phy
)->uf_control
),
1177 (void **)&fis_frame_data
);
1179 scic_sds_controller_copy_sata_response(&iphy
->frame_rcvd
.fis
,
1183 /* got IAF we can now go to the await spinup semaphore state */
1184 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1185 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1187 result
= SCI_SUCCESS
;
1189 dev_warn(sciphy_to_dev(sci_phy
),
1190 "%s: PHY starting substate machine received "
1191 "unexpected frame id %x\n",
1195 /* Regardless of the result we are done with this frame with it */
1196 scic_sds_controller_release_frame(scic_sds_phy_get_controller(sci_phy
),
1203 * *****************************************************************************
1204 * * SCIC SDS PHY POWER_HANDLERS
1205 * ***************************************************************************** */
1208 * This method is called by the struct scic_sds_controller when the phy object is
1209 * granted power. - The notify enable spinups are turned on for this phy object
1210 * - The phy state machine is transitioned to the
1211 * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. enum sci_status SCI_SUCCESS
1213 static enum sci_status
scic_sds_phy_starting_substate_await_sas_power_consume_power_handler(
1214 struct scic_sds_phy
*sci_phy
)
1218 enable_spinup
= readl(&sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1219 enable_spinup
|= SCU_ENSPINUP_GEN_BIT(ENABLE
);
1220 writel(enable_spinup
, &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1222 /* Change state to the final state this substate machine has run to completion */
1223 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1224 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1230 * This method is called by the struct scic_sds_controller when the phy object is
1231 * granted power. - The phy state machine is transitioned to the
1232 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. enum sci_status SCI_SUCCESS
1234 static enum sci_status
scic_sds_phy_starting_substate_await_sata_power_consume_power_handler(
1235 struct scic_sds_phy
*sci_phy
)
1237 u32 scu_sas_pcfg_value
;
1239 /* Release the spinup hold state and reset the OOB state machine */
1240 scu_sas_pcfg_value
=
1241 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
1242 scu_sas_pcfg_value
&=
1243 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
));
1244 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
1245 writel(scu_sas_pcfg_value
,
1246 &sci_phy
->link_layer_registers
->phy_configuration
);
1248 /* Now restart the OOB operation */
1249 scu_sas_pcfg_value
&= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
1250 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
1251 writel(scu_sas_pcfg_value
,
1252 &sci_phy
->link_layer_registers
->phy_configuration
);
1254 /* Change state to the final state this substate machine has run to completion */
1255 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1256 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
);
1261 static enum sci_status
default_phy_handler(struct scic_sds_phy
*sci_phy
,
1264 dev_dbg(sciphy_to_dev(sci_phy
),
1265 "%s: in wrong state: %d\n", func
,
1266 sci_base_state_machine_get_state(&sci_phy
->state_machine
));
1267 return SCI_FAILURE_INVALID_STATE
;
1270 static enum sci_status
1271 scic_sds_phy_default_destroy_handler(struct scic_sds_phy
*sci_phy
)
1273 return default_phy_handler(sci_phy
, __func__
);
1276 static enum sci_status
1277 scic_sds_phy_default_frame_handler(struct scic_sds_phy
*sci_phy
,
1280 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
1282 default_phy_handler(sci_phy
, __func__
);
1283 scic_sds_controller_release_frame(scic
, frame_index
);
1285 return SCI_FAILURE_INVALID_STATE
;
1288 static enum sci_status
1289 scic_sds_phy_default_event_handler(struct scic_sds_phy
*sci_phy
,
1292 return default_phy_handler(sci_phy
, __func__
);
1295 static enum sci_status
1296 scic_sds_phy_default_consume_power_handler(struct scic_sds_phy
*sci_phy
)
1298 return default_phy_handler(sci_phy
, __func__
);
1301 static enum sci_status
1302 scic_sds_phy_stopped_state_destroy_handler(struct scic_sds_phy
*sci_phy
)
1308 * scic_sds_phy_ready_state_event_handler -
1309 * @phy: This is the struct scic_sds_phy object which has received the event.
1311 * This method request the struct scic_sds_phy handle the received event. The only
1312 * event that we are interested in while in the ready state is the link failure
1313 * event. - decoded event is a link failure - transition the struct scic_sds_phy back
1314 * to the SCI_BASE_PHY_STATE_STARTING state. - any other event received will
1315 * report a warning message enum sci_status SCI_SUCCESS if the event received is a
1316 * link failure SCI_FAILURE_INVALID_STATE for any other event received.
1318 static enum sci_status
scic_sds_phy_ready_state_event_handler(struct scic_sds_phy
*sci_phy
,
1321 enum sci_status result
= SCI_FAILURE
;
1323 switch (scu_get_event_code(event_code
)) {
1324 case SCU_EVENT_LINK_FAILURE
:
1325 /* Link failure change state back to the starting state */
1326 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1327 SCI_BASE_PHY_STATE_STARTING
);
1328 result
= SCI_SUCCESS
;
1331 case SCU_EVENT_BROADCAST_CHANGE
:
1332 /* Broadcast change received. Notify the port. */
1333 if (scic_sds_phy_get_port(sci_phy
) != NULL
)
1334 scic_sds_port_broadcast_change_received(sci_phy
->owning_port
, sci_phy
);
1336 sci_phy
->bcn_received_while_port_unassigned
= true;
1340 dev_warn(sciphy_to_dev(sci_phy
),
1341 "%sP SCIC PHY 0x%p ready state machine received "
1342 "unexpected event_code %x\n",
1343 __func__
, sci_phy
, event_code
);
1345 result
= SCI_FAILURE_INVALID_STATE
;
1352 static enum sci_status
scic_sds_phy_resetting_state_event_handler(struct scic_sds_phy
*sci_phy
,
1355 enum sci_status result
= SCI_FAILURE
;
1357 switch (scu_get_event_code(event_code
)) {
1358 case SCU_EVENT_HARD_RESET_TRANSMITTED
:
1359 /* Link failure change state back to the starting state */
1360 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1361 SCI_BASE_PHY_STATE_STARTING
);
1362 result
= SCI_SUCCESS
;
1366 dev_warn(sciphy_to_dev(sci_phy
),
1367 "%s: SCIC PHY 0x%p resetting state machine received "
1368 "unexpected event_code %x\n",
1369 __func__
, sci_phy
, event_code
);
1371 result
= SCI_FAILURE_INVALID_STATE
;
1378 /* --------------------------------------------------------------------------- */
1380 static const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table
[] = {
1381 [SCI_BASE_PHY_STATE_INITIAL
] = {
1382 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1383 .frame_handler
= scic_sds_phy_default_frame_handler
,
1384 .event_handler
= scic_sds_phy_default_event_handler
,
1385 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1387 [SCI_BASE_PHY_STATE_STOPPED
] = {
1388 .destruct_handler
= scic_sds_phy_stopped_state_destroy_handler
,
1389 .frame_handler
= scic_sds_phy_default_frame_handler
,
1390 .event_handler
= scic_sds_phy_default_event_handler
,
1391 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1393 [SCI_BASE_PHY_STATE_STARTING
] = {
1394 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1395 .frame_handler
= scic_sds_phy_default_frame_handler
,
1396 .event_handler
= scic_sds_phy_default_event_handler
,
1397 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1399 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
] = {
1400 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1401 .frame_handler
= scic_sds_phy_default_frame_handler
,
1402 .event_handler
= scic_sds_phy_default_event_handler
,
1403 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1405 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
] = {
1406 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1407 .frame_handler
= scic_sds_phy_default_frame_handler
,
1408 .event_handler
= scic_sds_phy_starting_substate_await_ossp_event_handler
,
1409 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1411 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
] = {
1412 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1413 .frame_handler
= scic_sds_phy_default_frame_handler
,
1414 .event_handler
= scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler
,
1415 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1417 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
] = {
1418 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1419 .frame_handler
= scic_sds_phy_starting_substate_await_iaf_uf_frame_handler
,
1420 .event_handler
= scic_sds_phy_starting_substate_await_iaf_uf_event_handler
,
1421 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1423 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
] = {
1424 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1425 .frame_handler
= scic_sds_phy_default_frame_handler
,
1426 .event_handler
= scic_sds_phy_starting_substate_await_sas_power_event_handler
,
1427 .consume_power_handler
= scic_sds_phy_starting_substate_await_sas_power_consume_power_handler
1429 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
] = {
1430 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1431 .frame_handler
= scic_sds_phy_default_frame_handler
,
1432 .event_handler
= scic_sds_phy_starting_substate_await_sata_power_event_handler
,
1433 .consume_power_handler
= scic_sds_phy_starting_substate_await_sata_power_consume_power_handler
1435 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
] = {
1436 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1437 .frame_handler
= scic_sds_phy_default_frame_handler
,
1438 .event_handler
= scic_sds_phy_starting_substate_await_sata_phy_event_handler
,
1439 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1441 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
] = {
1442 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1443 .frame_handler
= scic_sds_phy_default_frame_handler
,
1444 .event_handler
= scic_sds_phy_starting_substate_await_sata_speed_event_handler
,
1445 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1447 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
] = {
1448 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1449 .frame_handler
= scic_sds_phy_starting_substate_await_sig_fis_frame_handler
,
1450 .event_handler
= scic_sds_phy_starting_substate_await_sig_fis_event_handler
,
1451 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1453 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
] = {
1454 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1455 .frame_handler
= scic_sds_phy_default_frame_handler
,
1456 .event_handler
= scic_sds_phy_default_event_handler
,
1457 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1459 [SCI_BASE_PHY_STATE_READY
] = {
1460 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1461 .frame_handler
= scic_sds_phy_default_frame_handler
,
1462 .event_handler
= scic_sds_phy_ready_state_event_handler
,
1463 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1465 [SCI_BASE_PHY_STATE_RESETTING
] = {
1466 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1467 .frame_handler
= scic_sds_phy_default_frame_handler
,
1468 .event_handler
= scic_sds_phy_resetting_state_event_handler
,
1469 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1471 [SCI_BASE_PHY_STATE_FINAL
] = {
1472 .destruct_handler
= scic_sds_phy_default_destroy_handler
,
1473 .frame_handler
= scic_sds_phy_default_frame_handler
,
1474 .event_handler
= scic_sds_phy_default_event_handler
,
1475 .consume_power_handler
= scic_sds_phy_default_consume_power_handler
1480 * ****************************************************************************
1481 * * PHY STARTING SUBSTATE METHODS
1482 * **************************************************************************** */
1485 * scic_sds_phy_starting_initial_substate_enter -
1486 * @object: This is the object which is cast to a struct scic_sds_phy object.
1488 * This method will perform the actions required by the struct scic_sds_phy on
1489 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL. - The initial state
1490 * handlers are put in place for the struct scic_sds_phy object. - The state is
1491 * changed to the wait phy type event notification. none
1493 static void scic_sds_phy_starting_initial_substate_enter(void *object
)
1495 struct scic_sds_phy
*sci_phy
= object
;
1497 scic_sds_phy_set_base_state_handlers(
1498 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
);
1500 /* This is just an temporary state go off to the starting state */
1501 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1502 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_PHY_TYPE_EN. - Set the
1511 * struct scic_sds_phy object state handlers for this state. none
1513 static void scic_sds_phy_starting_await_ossp_en_substate_enter(void *object
)
1515 struct scic_sds_phy
*sci_phy
= object
;
1517 scic_sds_phy_set_base_state_handlers(
1518 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1524 * @object: This is the object which is cast to a struct scic_sds_phy object.
1526 * This method will perform the actions required by the struct scic_sds_phy on
1527 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - Set the
1528 * struct scic_sds_phy object state handlers for this state. none
1530 static void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
1533 struct scic_sds_phy
*sci_phy
= object
;
1535 scic_sds_phy_set_base_state_handlers(
1536 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
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_IAF_UF. - Set the
1546 * struct scic_sds_phy object state handlers for this state. none
1548 static void scic_sds_phy_starting_await_iaf_uf_substate_enter(void *object
)
1550 struct scic_sds_phy
*sci_phy
= object
;
1552 scic_sds_phy_set_base_state_handlers(
1553 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
1559 * @object: This is the object which is cast to a struct scic_sds_phy object.
1561 * This method will perform the actions required by the struct scic_sds_phy on
1562 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Set the
1563 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1564 * the power control queue none
1566 static void scic_sds_phy_starting_await_sas_power_substate_enter(void *object
)
1568 struct scic_sds_phy
*sci_phy
= object
;
1570 scic_sds_phy_set_base_state_handlers(
1571 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1574 scic_sds_controller_power_control_queue_insert(
1575 scic_sds_phy_get_controller(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 exiting
1585 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Remove the
1586 * struct scic_sds_phy object from the power control queue. none
1588 static void scic_sds_phy_starting_await_sas_power_substate_exit(void *object
)
1590 struct scic_sds_phy
*sci_phy
= object
;
1592 scic_sds_controller_power_control_queue_remove(
1593 scic_sds_phy_get_controller(sci_phy
), sci_phy
1599 * @object: This is the object which is cast to a struct scic_sds_phy object.
1601 * This method will perform the actions required by the struct scic_sds_phy on
1602 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Set the
1603 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1604 * the power control queue none
1606 static void scic_sds_phy_starting_await_sata_power_substate_enter(void *object
)
1608 struct scic_sds_phy
*sci_phy
= object
;
1610 scic_sds_phy_set_base_state_handlers(
1611 sci_phy
, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
1614 scic_sds_controller_power_control_queue_insert(
1615 scic_sds_phy_get_controller(sci_phy
),
1622 * @object: This is the object which is cast to a struct scic_sds_phy object.
1624 * This method will perform the actions required by the struct scic_sds_phy on exiting
1625 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Remove the
1626 * struct scic_sds_phy object from the power control queue. none
1628 static void scic_sds_phy_starting_await_sata_power_substate_exit(void *object
)
1630 struct scic_sds_phy
*sci_phy
= object
;
1632 scic_sds_controller_power_control_queue_remove(
1633 scic_sds_phy_get_controller(sci_phy
),
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 struct scic_sds_phy on
1643 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. - Set the
1644 * struct scic_sds_phy object state handlers for this state. none
1646 static void scic_sds_phy_starting_await_sata_phy_substate_enter(void *object
)
1648 struct scic_sds_phy
*sci_phy
= object
;
1650 scic_sds_phy_set_base_state_handlers(
1652 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
);
1654 isci_timer_start(sci_phy
->sata_timeout_timer
,
1655 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
);
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
1664 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1665 * that was started on entry to await sata phy event notification none
1667 static inline void scic_sds_phy_starting_await_sata_phy_substate_exit(
1670 struct scic_sds_phy
*sci_phy
= object
;
1672 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1677 * @object: This is the object which is cast to a struct scic_sds_phy object.
1679 * This method will perform the actions required by the struct scic_sds_phy on
1680 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - Set the
1681 * struct scic_sds_phy object state handlers for this state. none
1683 static void scic_sds_phy_starting_await_sata_speed_substate_enter(void *object
)
1685 struct scic_sds_phy
*sci_phy
= object
;
1687 scic_sds_phy_set_base_state_handlers(
1689 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
);
1691 isci_timer_start(sci_phy
->sata_timeout_timer
,
1692 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
);
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
1700 * struct scic_sds_phy on exiting
1701 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1702 * that was started on entry to await sata phy event notification none
1704 static inline void scic_sds_phy_starting_await_sata_speed_substate_exit(
1707 struct scic_sds_phy
*sci_phy
= object
;
1709 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1714 * @object: This is the object which is cast to a struct scic_sds_phy object.
1716 * This function will perform the actions required by the struct scic_sds_phy on
1717 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Set the
1718 * struct scic_sds_phy object state handlers for this state.
1719 * - Start the SIGNATURE FIS
1720 * timeout timer none
1722 static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(void *object
)
1724 bool continue_to_ready_state
;
1725 struct scic_sds_phy
*sci_phy
= object
;
1727 scic_sds_phy_set_base_state_handlers(
1729 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
);
1731 continue_to_ready_state
= scic_sds_port_link_detected(
1732 sci_phy
->owning_port
,
1735 if (continue_to_ready_state
) {
1737 * Clear the PE suspend condition so we can actually
1739 * The hardware will not respond to the XRDY until the PE
1740 * suspend condition is cleared.
1742 scic_sds_phy_resume(sci_phy
);
1744 isci_timer_start(sci_phy
->sata_timeout_timer
,
1745 SCIC_SDS_SIGNATURE_FIS_TIMEOUT
);
1747 sci_phy
->is_in_link_training
= false;
1752 * @object: This is the object which is cast to a struct scic_sds_phy object.
1754 * This function will perform the actions required by the
1755 * struct scic_sds_phy on exiting
1756 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Stop the SIGNATURE
1757 * FIS timeout timer. none
1759 static inline void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(
1762 struct scic_sds_phy
*sci_phy
= object
;
1764 isci_timer_stop(sci_phy
->sata_timeout_timer
);
1769 * @object: This is the object which is cast to a struct scic_sds_phy object.
1771 * This method will perform the actions required by the struct scic_sds_phy on
1772 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. - Set the struct scic_sds_phy
1773 * object state handlers for this state. - Change base state machine to the
1776 static void scic_sds_phy_starting_final_substate_enter(void *object
)
1778 struct scic_sds_phy
*sci_phy
= object
;
1780 scic_sds_phy_set_base_state_handlers(sci_phy
,
1781 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
);
1783 /* State machine has run to completion so exit out and change
1784 * the base state machine to the ready state
1786 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1787 SCI_BASE_PHY_STATE_READY
);
1791 * ****************************************************************************
1792 * * PHY STATE PRIVATE METHODS
1793 * **************************************************************************** */
1797 * @sci_phy: This is the struct scic_sds_phy object to stop.
1799 * This method will stop the struct scic_sds_phy object. This does not reset the
1800 * protocol engine it just suspends it and places it in a state where it will
1801 * not cause the end device to power up. none
1803 static void scu_link_layer_stop_protocol_engine(
1804 struct scic_sds_phy
*sci_phy
)
1806 u32 scu_sas_pcfg_value
;
1807 u32 enable_spinup_value
;
1809 /* Suspend the protocol engine and place it in a sata spinup hold state */
1810 scu_sas_pcfg_value
=
1811 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
1812 scu_sas_pcfg_value
|=
1813 (SCU_SAS_PCFG_GEN_BIT(OOB_RESET
) |
1814 SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE
) |
1815 SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD
));
1816 writel(scu_sas_pcfg_value
,
1817 &sci_phy
->link_layer_registers
->phy_configuration
);
1819 /* Disable the notify enable spinup primitives */
1820 enable_spinup_value
= readl(&sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1821 enable_spinup_value
&= ~SCU_ENSPINUP_GEN_BIT(ENABLE
);
1822 writel(enable_spinup_value
, &sci_phy
->link_layer_registers
->notify_enable_spinup_control
);
1828 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
1830 static void scu_link_layer_start_oob(
1831 struct scic_sds_phy
*sci_phy
)
1833 u32 scu_sas_pcfg_value
;
1835 scu_sas_pcfg_value
=
1836 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
1837 scu_sas_pcfg_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
1838 scu_sas_pcfg_value
&=
1839 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET
) |
1840 SCU_SAS_PCFG_GEN_BIT(HARD_RESET
));
1841 writel(scu_sas_pcfg_value
,
1842 &sci_phy
->link_layer_registers
->phy_configuration
);
1848 * This method will transmit a hard reset request on the specified phy. The SCU
1849 * hardware requires that we reset the OOB state machine and set the hard reset
1850 * bit in the phy configuration register. We then must start OOB over with the
1851 * hard reset bit set.
1853 static void scu_link_layer_tx_hard_reset(
1854 struct scic_sds_phy
*sci_phy
)
1856 u32 phy_configuration_value
;
1859 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
1860 * to the starting state. */
1861 phy_configuration_value
=
1862 readl(&sci_phy
->link_layer_registers
->phy_configuration
);
1863 phy_configuration_value
|=
1864 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET
) |
1865 SCU_SAS_PCFG_GEN_BIT(OOB_RESET
));
1866 writel(phy_configuration_value
,
1867 &sci_phy
->link_layer_registers
->phy_configuration
);
1869 /* Now take the OOB state machine out of reset */
1870 phy_configuration_value
|= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE
);
1871 phy_configuration_value
&= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET
);
1872 writel(phy_configuration_value
,
1873 &sci_phy
->link_layer_registers
->phy_configuration
);
1877 * ****************************************************************************
1878 * * PHY BASE STATE METHODS
1879 * **************************************************************************** */
1883 * @object: This is the object which is cast to a struct scic_sds_phy object.
1885 * This method will perform the actions required by the struct scic_sds_phy on
1886 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
1887 * handlers for the phy object base state machine initial state. none
1889 static void scic_sds_phy_initial_state_enter(void *object
)
1891 struct scic_sds_phy
*sci_phy
= object
;
1893 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_INITIAL
);
1898 * @object: This is the object which is cast to a struct scic_sds_phy object.
1900 * This function will perform the actions required by the struct scic_sds_phy on
1901 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
1902 * handlers for the phy object base state machine initial state. - The SCU
1903 * hardware is requested to stop the protocol engine. none
1905 static void scic_sds_phy_stopped_state_enter(void *object
)
1907 struct scic_sds_phy
*sci_phy
= object
;
1908 struct scic_sds_controller
*scic
= scic_sds_phy_get_controller(sci_phy
);
1909 struct isci_host
*ihost
= scic_to_ihost(scic
);
1912 * @todo We need to get to the controller to place this PE in a
1916 scic_sds_phy_set_base_state_handlers(sci_phy
,
1917 SCI_BASE_PHY_STATE_STOPPED
);
1919 if (sci_phy
->sata_timeout_timer
!= NULL
) {
1920 isci_del_timer(ihost
, sci_phy
->sata_timeout_timer
);
1922 sci_phy
->sata_timeout_timer
= NULL
;
1925 scu_link_layer_stop_protocol_engine(sci_phy
);
1927 if (sci_phy
->state_machine
.previous_state_id
!=
1928 SCI_BASE_PHY_STATE_INITIAL
)
1929 scic_sds_controller_link_down(
1930 scic_sds_phy_get_controller(sci_phy
),
1931 scic_sds_phy_get_port(sci_phy
),
1937 * @object: This is the object which is cast to a struct scic_sds_phy object.
1939 * This method will perform the actions required by the struct scic_sds_phy on
1940 * entering the SCI_BASE_PHY_STATE_STARTING. - This function sets the state
1941 * handlers for the phy object base state machine starting state. - The SCU
1942 * hardware is requested to start OOB/SN on this protocl engine. - The phy
1943 * starting substate machine is started. - If the previous state was the ready
1944 * state then the struct scic_sds_controller is informed that the phy has gone link
1947 static void scic_sds_phy_starting_state_enter(void *object
)
1949 struct scic_sds_phy
*sci_phy
= object
;
1951 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_STARTING
);
1953 scu_link_layer_stop_protocol_engine(sci_phy
);
1954 scu_link_layer_start_oob(sci_phy
);
1956 /* We don't know what kind of phy we are going to be just yet */
1957 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_UNKNOWN
;
1958 sci_phy
->bcn_received_while_port_unassigned
= false;
1960 if (sci_phy
->state_machine
.previous_state_id
1961 == SCI_BASE_PHY_STATE_READY
) {
1962 scic_sds_controller_link_down(
1963 scic_sds_phy_get_controller(sci_phy
),
1964 scic_sds_phy_get_port(sci_phy
),
1969 sci_base_state_machine_change_state(&sci_phy
->state_machine
,
1970 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
);
1975 * @object: This is the object which is cast to a struct scic_sds_phy object.
1977 * This method will perform the actions required by the struct scic_sds_phy on
1978 * entering the SCI_BASE_PHY_STATE_READY. - This function sets the state
1979 * handlers for the phy object base state machine ready state. - The SCU
1980 * hardware protocol engine is resumed. - The struct scic_sds_controller is informed
1981 * that the phy object has gone link up. none
1983 static void scic_sds_phy_ready_state_enter(void *object
)
1985 struct scic_sds_phy
*sci_phy
= object
;
1987 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_READY
);
1989 scic_sds_controller_link_up(
1990 scic_sds_phy_get_controller(sci_phy
),
1991 scic_sds_phy_get_port(sci_phy
),
1998 * @object: This is the object which is cast to a struct scic_sds_phy object.
2000 * This method will perform the actions required by the struct scic_sds_phy on exiting
2001 * the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU hardware
2002 * protocol engine represented by this struct scic_sds_phy object. none
2004 static void scic_sds_phy_ready_state_exit(void *object
)
2006 struct scic_sds_phy
*sci_phy
= object
;
2008 scic_sds_phy_suspend(sci_phy
);
2013 * @object: This is the object which is cast to a struct scic_sds_phy object.
2015 * This method will perform the actions required by the struct scic_sds_phy on
2016 * entering the SCI_BASE_PHY_STATE_RESETTING. - This function sets the state
2017 * handlers for the phy object base state machine resetting state. none
2019 static void scic_sds_phy_resetting_state_enter(void *object
)
2021 struct scic_sds_phy
*sci_phy
= object
;
2023 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_RESETTING
);
2026 * The phy is being reset, therefore deactivate it from the port.
2027 * In the resetting state we don't notify the user regarding
2028 * link up and link down notifications. */
2029 scic_sds_port_deactivate_phy(sci_phy
->owning_port
, sci_phy
, false);
2031 if (sci_phy
->protocol
== SCIC_SDS_PHY_PROTOCOL_SAS
) {
2032 scu_link_layer_tx_hard_reset(sci_phy
);
2035 * The SCU does not need to have a discrete reset state so
2036 * just go back to the starting state.
2038 sci_base_state_machine_change_state(
2039 &sci_phy
->state_machine
,
2040 SCI_BASE_PHY_STATE_STARTING
);
2046 * @object: This is the object which is cast to a struct scic_sds_phy object.
2048 * This method will perform the actions required by the struct scic_sds_phy on
2049 * entering the SCI_BASE_PHY_STATE_FINAL. - This function sets the state
2050 * handlers for the phy object base state machine final state. none
2052 static void scic_sds_phy_final_state_enter(void *object
)
2054 struct scic_sds_phy
*sci_phy
= object
;
2056 scic_sds_phy_set_base_state_handlers(sci_phy
, SCI_BASE_PHY_STATE_FINAL
);
2058 /* Nothing to do here */
2061 /* --------------------------------------------------------------------------- */
2063 static const struct sci_base_state scic_sds_phy_state_table
[] = {
2064 [SCI_BASE_PHY_STATE_INITIAL
] = {
2065 .enter_state
= scic_sds_phy_initial_state_enter
,
2067 [SCI_BASE_PHY_STATE_STOPPED
] = {
2068 .enter_state
= scic_sds_phy_stopped_state_enter
,
2070 [SCI_BASE_PHY_STATE_STARTING
] = {
2071 .enter_state
= scic_sds_phy_starting_state_enter
,
2073 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
] = {
2074 .enter_state
= scic_sds_phy_starting_initial_substate_enter
,
2076 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
] = {
2077 .enter_state
= scic_sds_phy_starting_await_ossp_en_substate_enter
,
2079 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
] = {
2080 .enter_state
= scic_sds_phy_starting_await_sas_speed_en_substate_enter
,
2082 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
] = {
2083 .enter_state
= scic_sds_phy_starting_await_iaf_uf_substate_enter
,
2085 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
] = {
2086 .enter_state
= scic_sds_phy_starting_await_sas_power_substate_enter
,
2087 .exit_state
= scic_sds_phy_starting_await_sas_power_substate_exit
,
2089 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
] = {
2090 .enter_state
= scic_sds_phy_starting_await_sata_power_substate_enter
,
2091 .exit_state
= scic_sds_phy_starting_await_sata_power_substate_exit
2093 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
] = {
2094 .enter_state
= scic_sds_phy_starting_await_sata_phy_substate_enter
,
2095 .exit_state
= scic_sds_phy_starting_await_sata_phy_substate_exit
2097 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
] = {
2098 .enter_state
= scic_sds_phy_starting_await_sata_speed_substate_enter
,
2099 .exit_state
= scic_sds_phy_starting_await_sata_speed_substate_exit
2101 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
] = {
2102 .enter_state
= scic_sds_phy_starting_await_sig_fis_uf_substate_enter
,
2103 .exit_state
= scic_sds_phy_starting_await_sig_fis_uf_substate_exit
2105 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
] = {
2106 .enter_state
= scic_sds_phy_starting_final_substate_enter
,
2108 [SCI_BASE_PHY_STATE_READY
] = {
2109 .enter_state
= scic_sds_phy_ready_state_enter
,
2110 .exit_state
= scic_sds_phy_ready_state_exit
,
2112 [SCI_BASE_PHY_STATE_RESETTING
] = {
2113 .enter_state
= scic_sds_phy_resetting_state_enter
,
2115 [SCI_BASE_PHY_STATE_FINAL
] = {
2116 .enter_state
= scic_sds_phy_final_state_enter
,
2120 void scic_sds_phy_construct(struct scic_sds_phy
*sci_phy
,
2121 struct scic_sds_port
*owning_port
, u8 phy_index
)
2123 sci_base_state_machine_construct(&sci_phy
->state_machine
,
2125 scic_sds_phy_state_table
,
2126 SCI_BASE_PHY_STATE_INITIAL
);
2128 sci_base_state_machine_start(&sci_phy
->state_machine
);
2130 /* Copy the rest of the input data to our locals */
2131 sci_phy
->owning_port
= owning_port
;
2132 sci_phy
->phy_index
= phy_index
;
2133 sci_phy
->bcn_received_while_port_unassigned
= false;
2134 sci_phy
->protocol
= SCIC_SDS_PHY_PROTOCOL_UNKNOWN
;
2135 sci_phy
->link_layer_registers
= NULL
;
2136 sci_phy
->max_negotiated_speed
= SAS_LINK_RATE_UNKNOWN
;
2137 sci_phy
->sata_timeout_timer
= NULL
;
2140 void isci_phy_init(struct isci_phy
*iphy
, struct isci_host
*ihost
, int index
)
2142 union scic_oem_parameters oem
;
2146 scic_oem_parameters_get(&ihost
->sci
, &oem
);
2147 sci_sas_addr
= oem
.sds1
.phys
[index
].sas_address
.high
;
2148 sci_sas_addr
<<= 32;
2149 sci_sas_addr
|= oem
.sds1
.phys
[index
].sas_address
.low
;
2150 sas_addr
= cpu_to_be64(sci_sas_addr
);
2151 memcpy(iphy
->sas_addr
, &sas_addr
, sizeof(sas_addr
));
2153 iphy
->isci_port
= NULL
;
2154 iphy
->sas_phy
.enabled
= 0;
2155 iphy
->sas_phy
.id
= index
;
2156 iphy
->sas_phy
.sas_addr
= &iphy
->sas_addr
[0];
2157 iphy
->sas_phy
.frame_rcvd
= (u8
*)&iphy
->frame_rcvd
;
2158 iphy
->sas_phy
.ha
= &ihost
->sas_ha
;
2159 iphy
->sas_phy
.lldd_phy
= iphy
;
2160 iphy
->sas_phy
.enabled
= 1;
2161 iphy
->sas_phy
.class = SAS
;
2162 iphy
->sas_phy
.iproto
= SAS_PROTOCOL_ALL
;
2163 iphy
->sas_phy
.tproto
= 0;
2164 iphy
->sas_phy
.type
= PHY_TYPE_PHYSICAL
;
2165 iphy
->sas_phy
.role
= PHY_ROLE_INITIATOR
;
2166 iphy
->sas_phy
.oob_mode
= OOB_NOT_CONNECTED
;
2167 iphy
->sas_phy
.linkrate
= SAS_LINK_RATE_UNKNOWN
;
2168 memset(&iphy
->frame_rcvd
, 0, sizeof(iphy
->frame_rcvd
));
2173 * isci_phy_control() - This function is one of the SAS Domain Template
2174 * functions. This is a phy management function.
2175 * @phy: This parameter specifies the sphy being controlled.
2176 * @func: This parameter specifies the phy control function being invoked.
2177 * @buf: This parameter is specific to the phy function being invoked.
2179 * status, zero indicates success.
2181 int isci_phy_control(struct asd_sas_phy
*sas_phy
,
2186 struct isci_phy
*iphy
= sas_phy
->lldd_phy
;
2187 struct isci_port
*iport
= iphy
->isci_port
;
2188 struct isci_host
*ihost
= sas_phy
->ha
->lldd_ha
;
2189 unsigned long flags
;
2191 dev_dbg(&ihost
->pdev
->dev
,
2192 "%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
2193 __func__
, sas_phy
, func
, buf
, iphy
, iport
);
2196 case PHY_FUNC_DISABLE
:
2197 spin_lock_irqsave(&ihost
->scic_lock
, flags
);
2198 scic_sds_phy_stop(&iphy
->sci
);
2199 spin_unlock_irqrestore(&ihost
->scic_lock
, flags
);
2202 case PHY_FUNC_LINK_RESET
:
2203 spin_lock_irqsave(&ihost
->scic_lock
, flags
);
2204 scic_sds_phy_stop(&iphy
->sci
);
2205 scic_sds_phy_start(&iphy
->sci
);
2206 spin_unlock_irqrestore(&ihost
->scic_lock
, flags
);
2209 case PHY_FUNC_HARD_RESET
:
2213 /* Perform the port reset. */
2214 ret
= isci_port_perform_hard_reset(ihost
, iport
, iphy
);
2219 dev_dbg(&ihost
->pdev
->dev
,
2220 "%s: phy %p; func %d NOT IMPLEMENTED!\n",
2221 __func__
, sas_phy
, func
);