isci: controller stop/start fixes
[deliverable/linux.git] / drivers / scsi / isci / core / scic_sds_phy.c
CommitLineData
6f231dda
DW
1/*
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.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
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.
12 *
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.
17 *
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.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
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
38 * distribution.
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.
42 *
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.
54 */
55
56#include "intel_ata.h"
57#include "intel_sata.h"
58#include "sci_base_state.h"
59#include "sci_base_state_machine.h"
60#include "scic_phy.h"
61#include "scic_sds_controller.h"
62#include "scic_sds_phy.h"
63#include "scic_sds_phy_registers.h"
64#include "scic_sds_port.h"
24621466 65#include "scic_sds_remote_node_context.h"
6f231dda
DW
66#include "sci_environment.h"
67#include "sci_util.h"
68#include "scu_event_codes.h"
69
70#define SCIC_SDS_PHY_MIN_TIMER_COUNT (SCI_MAX_PHYS)
71#define SCIC_SDS_PHY_MAX_TIMER_COUNT (SCI_MAX_PHYS)
72
73/* Maximum arbitration wait time in micro-seconds */
74#define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
75
83e51430
DW
76enum sas_linkrate sci_phy_linkrate(struct scic_sds_phy *sci_phy)
77{
78 return sci_phy->max_negotiated_speed;
79}
80
6f231dda
DW
81/*
82 * *****************************************************************************
83 * * SCIC SDS PHY Internal Methods
84 * ***************************************************************************** */
85
24621466
HD
86/**
87 * This method will initialize the phy transport layer registers
88 * @this_phy:
89 * @transport_layer_registers
90 *
91 * enum sci_status
92 */
93static enum sci_status scic_sds_phy_transport_layer_initialization(
94 struct scic_sds_phy *this_phy,
95 struct scu_transport_layer_registers __iomem *transport_layer_registers)
96{
97 u32 tl_control;
98
99 this_phy->transport_layer_registers = transport_layer_registers;
100
101 SCU_STPTLDARNI_WRITE(this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
102
103 /* Hardware team recommends that we enable the STP prefetch for all transports */
104 tl_control = SCU_TLCR_READ(this_phy);
105 tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
106 SCU_TLCR_WRITE(this_phy, tl_control);
107
108 return SCI_SUCCESS;
109}
110
6f231dda
DW
111/**
112 * This method will initialize the phy link layer registers
3c06c283 113 * @sci_phy:
6f231dda
DW
114 * @link_layer_registers:
115 *
116 * enum sci_status
117 */
3c06c283
DW
118static enum sci_status
119scic_sds_phy_link_layer_initialization(struct scic_sds_phy *sci_phy,
120 struct scu_link_layer_registers __iomem *link_layer_registers)
6f231dda 121{
3c06c283
DW
122 struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
123 int phy_idx = sci_phy->phy_index;
124 struct sci_phy_user_params *phy_user = &scic->user_parameters.sds1.phys[phy_idx];
125 struct sci_phy_oem_params *phy_oem = &scic->oem_parameters.sds1.phys[phy_idx];
6f231dda
DW
126 u32 phy_configuration;
127 struct sas_capabilities phy_capabilities;
128 u32 parity_check = 0;
129 u32 parity_count = 0;
3c06c283 130 u32 llctl, link_rate;
d9def184 131 u32 clksm_value = 0;
6f231dda 132
3c06c283 133 sci_phy->link_layer_registers = link_layer_registers;
6f231dda
DW
134
135 /* Set our IDENTIFY frame data */
8f31550c 136 #define SCI_END_DEVICE 0x01
6f231dda 137
3c06c283
DW
138 SCU_SAS_TIID_WRITE(sci_phy, (SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) |
139 SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) |
140 SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
141 SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
142 SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE)));
6f231dda
DW
143
144 /* Write the device SAS Address */
3c06c283
DW
145 SCU_SAS_TIDNH_WRITE(sci_phy, 0xFEDCBA98);
146 SCU_SAS_TIDNL_WRITE(sci_phy, phy_idx);
6f231dda
DW
147
148 /* Write the source SAS Address */
3c06c283
DW
149 SCU_SAS_TISSAH_WRITE(sci_phy, phy_oem->sas_address.high);
150 SCU_SAS_TISSAL_WRITE(sci_phy, phy_oem->sas_address.low);
6f231dda
DW
151
152 /* Clear and Set the PHY Identifier */
3c06c283
DW
153 SCU_SAS_TIPID_WRITE(sci_phy, 0x00000000);
154 SCU_SAS_TIPID_WRITE(sci_phy, SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx));
6f231dda
DW
155
156 /* Change the initial state of the phy configuration register */
3c06c283 157 phy_configuration = SCU_SAS_PCFG_READ(sci_phy);
6f231dda
DW
158
159 /* Hold OOB state machine in reset */
160 phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
3c06c283 161 SCU_SAS_PCFG_WRITE(sci_phy, phy_configuration);
6f231dda
DW
162
163 /* Configure the SNW capabilities */
164 phy_capabilities.u.all = 0;
165 phy_capabilities.u.bits.start = 1;
166 phy_capabilities.u.bits.gen3_without_ssc_supported = 1;
167 phy_capabilities.u.bits.gen2_without_ssc_supported = 1;
168 phy_capabilities.u.bits.gen1_without_ssc_supported = 1;
3c06c283 169 if (scic->oem_parameters.sds1.controller.do_enable_ssc == true) {
6f231dda
DW
170 phy_capabilities.u.bits.gen3_with_ssc_supported = 1;
171 phy_capabilities.u.bits.gen2_with_ssc_supported = 1;
172 phy_capabilities.u.bits.gen1_with_ssc_supported = 1;
173 }
174
175 /*
176 * The SAS specification indicates that the phy_capabilities that
177 * are transmitted shall have an even parity. Calculate the parity. */
178 parity_check = phy_capabilities.u.all;
179 while (parity_check != 0) {
180 if (parity_check & 0x1)
181 parity_count++;
182 parity_check >>= 1;
183 }
184
185 /*
186 * If parity indicates there are an odd number of bits set, then
187 * set the parity bit to 1 in the phy capabilities. */
188 if ((parity_count % 2) != 0)
189 phy_capabilities.u.bits.parity = 1;
190
3c06c283 191 SCU_SAS_PHYCAP_WRITE(sci_phy, phy_capabilities.u.all);
6f231dda 192
3c06c283
DW
193 /* Set the enable spinup period but disable the ability to send
194 * notify enable spinup
195 */
196 SCU_SAS_ENSPINUP_WRITE(sci_phy, SCU_ENSPINUP_GEN_VAL(COUNT,
197 phy_user->notify_enable_spin_up_insertion_frequency));
d9def184 198
3c06c283
DW
199 /* Write the ALIGN Insertion Ferequency for connected phy and
200 * inpendent of connected state
201 */
d9def184 202 clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
3c06c283 203 phy_user->in_connection_align_insertion_frequency);
d9def184
JD
204
205 clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
3c06c283
DW
206 phy_user->align_insertion_frequency);
207
208 SCU_SAS_CLKSM_WRITE(sci_phy, clksm_value);
209
210 /* @todo Provide a way to write this register correctly */
211 scu_link_layer_register_write(sci_phy, afe_lookup_table_control, 0x02108421);
212
213 llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
214 (u8)scic->user_parameters.sds1.no_outbound_task_timeout);
215
216 switch(phy_user->max_speed_generation) {
217 case SCIC_SDS_PARM_GEN3_SPEED:
218 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3;
219 break;
220 case SCIC_SDS_PARM_GEN2_SPEED:
221 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
222 break;
223 default:
224 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
225 break;
226 }
227 llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
228
229 scu_link_layer_register_write(sci_phy, link_layer_control, llctl);
230
231 if (is_a0() || is_a2()) {
232 /* Program the max ARB time for the PHY to 700us so we inter-operate with
233 * the PMC expander which shuts down PHYs if the expander PHY generates too
234 * many breaks. This time value will guarantee that the initiator PHY will
235 * generate the break.
236 */
237 scu_link_layer_register_write(sci_phy,
238 maximum_arbitration_wait_timer_timeout,
239 SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME);
6f231dda 240 }
6f231dda
DW
241
242 /*
243 * Set the link layer hang detection to 500ms (0x1F4) from its default
244 * value of 128ms. Max value is 511 ms. */
3c06c283
DW
245 scu_link_layer_register_write(sci_phy, link_layer_hang_detection_timeout,
246 0x1F4);
6f231dda
DW
247
248 /* We can exit the initial state to the stopped state */
3c06c283
DW
249 sci_base_state_machine_change_state(scic_sds_phy_get_base_state_machine(sci_phy),
250 SCI_BASE_PHY_STATE_STOPPED);
6f231dda
DW
251
252 return SCI_SUCCESS;
253}
254
255/**
256 * This function will handle the sata SIGNATURE FIS timeout condition. It will
257 * restart the starting substate machine since we dont know what has actually
258 * happening.
259 */
c658b109 260void scic_sds_phy_sata_timeout(void *phy)
6f231dda
DW
261{
262 struct scic_sds_phy *sci_phy = phy;
263
264 dev_dbg(sciphy_to_dev(sci_phy),
265 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
266 "timeout.\n",
267 __func__,
268 sci_phy);
269
270 sci_base_state_machine_stop(
271 scic_sds_phy_get_starting_substate_machine(sci_phy));
272
273 sci_base_state_machine_change_state(
274 scic_sds_phy_get_base_state_machine(sci_phy),
275 SCI_BASE_PHY_STATE_STARTING
276 );
277}
278
6f231dda
DW
279/**
280 * This method will construct the struct scic_sds_phy object
281 * @this_phy:
282 * @owning_port:
283 * @phy_index:
284 *
285 */
286void scic_sds_phy_construct(
287 struct scic_sds_phy *this_phy,
288 struct scic_sds_port *owning_port,
289 u8 phy_index)
290{
291 /*
292 * Call the base constructor first
293 */
294 sci_base_phy_construct(
295 &this_phy->parent,
296 scic_sds_phy_state_table
297 );
298
299 /* Copy the rest of the input data to our locals */
300 this_phy->owning_port = owning_port;
301 this_phy->phy_index = phy_index;
302 this_phy->bcn_received_while_port_unassigned = false;
303 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
304 this_phy->link_layer_registers = NULL;
305 this_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE;
c658b109 306 this_phy->sata_timeout_timer = NULL;
6f231dda
DW
307
308 /* Clear out the identification buffer data */
309 memset(&this_phy->phy_type, 0, sizeof(this_phy->phy_type));
310
311 /* Initialize the the substate machines */
312 sci_base_state_machine_construct(
313 &this_phy->starting_substate_machine,
314 &this_phy->parent.parent,
315 scic_sds_phy_starting_substates,
316 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
317 );
6f231dda
DW
318}
319
320/**
321 * This method returns the port currently containing this phy. If the phy is
322 * currently contained by the dummy port, then the phy is considered to not
323 * be part of a port.
324 * @this_phy: This parameter specifies the phy for which to retrieve the
325 * containing port.
326 *
327 * This method returns a handle to a port that contains the supplied phy.
a7e536c7
EN
328 * NULL This value is returned if the phy is not part of a real
329 * port (i.e. it's contained in the dummy port). !NULL All other
6f231dda
DW
330 * values indicate a handle/pointer to the port containing the phy.
331 */
332struct scic_sds_port *scic_sds_phy_get_port(
333 struct scic_sds_phy *this_phy)
334{
335 if (scic_sds_port_get_index(this_phy->owning_port) == SCIC_SDS_DUMMY_PORT)
a7e536c7 336 return NULL;
6f231dda
DW
337
338 return this_phy->owning_port;
339}
340
341/**
342 * This method will assign a port to the phy object.
343 * @out]: this_phy This parameter specifies the phy for which to assign a port
344 * object.
345 *
346 *
347 */
348void scic_sds_phy_set_port(
349 struct scic_sds_phy *this_phy,
350 struct scic_sds_port *the_port)
351{
352 this_phy->owning_port = the_port;
353
354 if (this_phy->bcn_received_while_port_unassigned) {
355 this_phy->bcn_received_while_port_unassigned = false;
356 scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy);
357 }
358}
359
360/**
361 * This method will initialize the constructed phy
362 * @sci_phy:
363 * @link_layer_registers:
364 *
365 * enum sci_status
366 */
367enum sci_status scic_sds_phy_initialize(
368 struct scic_sds_phy *sci_phy,
c658b109
PM
369 struct scu_transport_layer_registers __iomem *transport_layer_registers,
370 struct scu_link_layer_registers __iomem *link_layer_registers)
6f231dda
DW
371{
372 /* Create the SIGNATURE FIS Timeout timer for this phy */
a1914059 373 sci_phy->sata_timeout_timer = isci_event_timer_create(
6f231dda
DW
374 scic_sds_phy_get_controller(sci_phy),
375 scic_sds_phy_sata_timeout,
376 sci_phy
377 );
378
24621466
HD
379 /* Perfrom the initialization of the TL hardware */
380 scic_sds_phy_transport_layer_initialization(sci_phy, transport_layer_registers);
381
6f231dda
DW
382 /* Perofrm the initialization of the PE hardware */
383 scic_sds_phy_link_layer_initialization(sci_phy, link_layer_registers);
384
385 /*
386 * There is nothing that needs to be done in this state just
387 * transition to the stopped state. */
388 sci_base_state_machine_change_state(
389 scic_sds_phy_get_base_state_machine(sci_phy),
390 SCI_BASE_PHY_STATE_STOPPED
391 );
392
393 return SCI_SUCCESS;
394}
395
24621466
HD
396/**
397 * This method assigns the direct attached device ID for this phy.
398 *
399 * @this_phy The phy for which the direct attached device id is to
400 * be assigned.
401 * @device_id The direct attached device ID to assign to the phy.
402 * This will either be the RNi for the device or an invalid RNi if there
403 * is no current device assigned to the phy.
404 */
405void scic_sds_phy_setup_transport(
406 struct scic_sds_phy *this_phy,
407 u32 device_id)
408{
409 u32 tl_control;
410
411 SCU_STPTLDARNI_WRITE(this_phy, device_id);
412
413 /*
414 * The read should guarantee that the first write gets posted
415 * before the next write
416 */
417 tl_control = SCU_TLCR_READ(this_phy);
418 tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
419 SCU_TLCR_WRITE(this_phy, tl_control);
420}
6f231dda
DW
421
422/**
423 *
424 * @this_phy: The phy object to be suspended.
425 *
426 * This function will perform the register reads/writes to suspend the SCU
427 * hardware protocol engine. none
428 */
429void scic_sds_phy_suspend(
430 struct scic_sds_phy *this_phy)
431{
432 u32 scu_sas_pcfg_value;
433
434 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
6f231dda 435 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
6f231dda 436 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
24621466 437 scic_sds_phy_setup_transport(this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
6f231dda
DW
438}
439
440/**
441 *
442 * @this_phy: The phy object to resume.
443 *
444 * This function will perform the register reads/writes required to resume the
445 * SCU hardware protocol engine. none
446 */
447void scic_sds_phy_resume(
448 struct scic_sds_phy *this_phy)
449{
450 u32 scu_sas_pcfg_value;
451
452 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
453
454 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
455
456 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
457}
458
459/**
460 * This method returns the local sas address assigned to this phy.
461 * @this_phy: This parameter specifies the phy for which to retrieve the local
462 * SAS address.
463 * @sas_address: This parameter specifies the location into which to copy the
464 * local SAS address.
465 *
466 */
467void scic_sds_phy_get_sas_address(
468 struct scic_sds_phy *this_phy,
469 struct sci_sas_address *sas_address)
470{
471 sas_address->high = SCU_SAS_TISSAH_READ(this_phy);
472 sas_address->low = SCU_SAS_TISSAL_READ(this_phy);
473}
474
475/**
476 * This method returns the remote end-point (i.e. attached) sas address
477 * assigned to this phy.
478 * @this_phy: This parameter specifies the phy for which to retrieve the remote
479 * end-point SAS address.
480 * @sas_address: This parameter specifies the location into which to copy the
481 * remote end-point SAS address.
482 *
483 */
484void scic_sds_phy_get_attached_sas_address(
485 struct scic_sds_phy *this_phy,
486 struct sci_sas_address *sas_address)
487{
488 sas_address->high
489 = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high;
490 sas_address->low
491 = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low;
492}
493
494/**
495 * This method returns the supported protocols assigned to this phy
496 * @this_phy:
497 *
498 *
499 */
500void scic_sds_phy_get_protocols(
501 struct scic_sds_phy *this_phy,
502 struct sci_sas_identify_address_frame_protocols *protocols)
503{
504 protocols->u.all = (u16)(SCU_SAS_TIID_READ(this_phy) & 0x0000FFFF);
505}
506
507/**
508 *
509 * @this_phy: The parameter is the phy object for which the attached phy
510 * protcols are to be returned.
511 *
512 * This method returns the supported protocols for the attached phy. If this
513 * is a SAS phy the protocols are returned from the identify address frame. If
514 * this is a SATA phy then protocols are made up and the target phy is an STP
515 * target phy. The caller will get the entire set of bits for the protocol
516 * value.
517 */
518void scic_sds_phy_get_attached_phy_protocols(
519 struct scic_sds_phy *this_phy,
520 struct sci_sas_identify_address_frame_protocols *protocols)
521{
522 protocols->u.all = 0;
523
524 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
525 protocols->u.all =
526 this_phy->phy_type.sas.identify_address_frame_buffer.protocols.u.all;
527 } else if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
528 protocols->u.bits.stp_target = 1;
529 }
530}
531
532/*
533 * *****************************************************************************
534 * * SCIC SDS PHY Handler Redirects
535 * ***************************************************************************** */
536
537/**
538 * This method will attempt to start the phy object. This request is only valid
539 * when the phy is in the stopped state
540 * @this_phy:
541 *
542 * enum sci_status
543 */
544enum sci_status scic_sds_phy_start(
545 struct scic_sds_phy *this_phy)
546{
547 return this_phy->state_handlers->parent.start_handler(&this_phy->parent);
548}
549
550/**
551 * This method will attempt to stop the phy object.
552 * @this_phy:
553 *
554 * enum sci_status SCI_SUCCESS if the phy is going to stop SCI_INVALID_STATE if the
555 * phy is not in a valid state to stop
556 */
557enum sci_status scic_sds_phy_stop(
558 struct scic_sds_phy *this_phy)
559{
560 return this_phy->state_handlers->parent.stop_handler(&this_phy->parent);
561}
562
563/**
564 * This method will attempt to reset the phy. This request is only valid when
565 * the phy is in an ready state
566 * @this_phy:
567 *
568 * enum sci_status
569 */
570enum sci_status scic_sds_phy_reset(
571 struct scic_sds_phy *this_phy)
572{
573 return this_phy->state_handlers->parent.reset_handler(
574 &this_phy->parent
575 );
576}
577
578/**
579 * This method will process the event code received.
580 * @this_phy:
581 * @event_code:
582 *
583 * enum sci_status
584 */
585enum sci_status scic_sds_phy_event_handler(
586 struct scic_sds_phy *this_phy,
587 u32 event_code)
588{
589 return this_phy->state_handlers->event_handler(this_phy, event_code);
590}
591
592/**
593 * This method will process the frame index received.
594 * @this_phy:
595 * @frame_index:
596 *
597 * enum sci_status
598 */
599enum sci_status scic_sds_phy_frame_handler(
600 struct scic_sds_phy *this_phy,
601 u32 frame_index)
602{
603 return this_phy->state_handlers->frame_handler(this_phy, frame_index);
604}
605
606/**
607 * This method will give the phy permission to consume power
608 * @this_phy:
609 *
610 * enum sci_status
611 */
612enum sci_status scic_sds_phy_consume_power_handler(
613 struct scic_sds_phy *this_phy)
614{
615 return this_phy->state_handlers->consume_power_handler(this_phy);
616}
617
618/*
619 * *****************************************************************************
620 * * SCIC PHY Public Methods
621 * ***************************************************************************** */
622
623
624enum sci_status scic_sas_phy_get_properties(
625 struct scic_sds_phy *sci_phy,
626 struct scic_sas_phy_properties *properties)
627{
628 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
629 memcpy(
630 &properties->received_iaf,
631 &sci_phy->phy_type.sas.identify_address_frame_buffer,
632 sizeof(struct sci_sas_identify_address_frame)
633 );
634
635 properties->received_capabilities.u.all
636 = SCU_SAS_RECPHYCAP_READ(sci_phy);
637
638 return SCI_SUCCESS;
639 }
640
641 return SCI_FAILURE;
642}
643
644
645enum sci_status scic_sata_phy_get_properties(
646 struct scic_sds_phy *sci_phy,
647 struct scic_sata_phy_properties *properties)
648{
649 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
650 memcpy(
651 &properties->signature_fis,
652 &sci_phy->phy_type.sata.signature_fis_buffer,
653 sizeof(struct sata_fis_reg_d2h)
654 );
655
656 /* / @todo add support for port selectors. */
657 properties->is_port_selector_present = false;
658
659 return SCI_SUCCESS;
660 }
661
662 return SCI_FAILURE;
663}
664
665/*
666 * *****************************************************************************
667 * * SCIC SDS PHY HELPER FUNCTIONS
668 * ***************************************************************************** */
669
670
671/**
672 *
673 * @this_phy: The phy object that received SAS PHY DETECTED.
674 *
675 * This method continues the link training for the phy as if it were a SAS PHY
676 * instead of a SATA PHY. This is done because the completion queue had a SAS
677 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
678 * none
679 */
680static void scic_sds_phy_start_sas_link_training(
681 struct scic_sds_phy *this_phy)
682{
683 u32 phy_control;
684
685 phy_control = SCU_SAS_PCFG_READ(this_phy);
686 phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
687 SCU_SAS_PCFG_WRITE(this_phy, phy_control);
688
689 sci_base_state_machine_change_state(
690 &this_phy->starting_substate_machine,
691 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
692 );
693
694 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
695}
696
697/**
698 *
699 * @this_phy: The phy object that received a SATA SPINUP HOLD event
700 *
701 * This method continues the link training for the phy as if it were a SATA PHY
702 * instead of a SAS PHY. This is done because the completion queue had a SATA
703 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
704 */
705static void scic_sds_phy_start_sata_link_training(
706 struct scic_sds_phy *this_phy)
707{
708 sci_base_state_machine_change_state(
709 &this_phy->starting_substate_machine,
710 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
711 );
712
713 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
714}
715
716/**
717 * This method performs processing common to all protocols upon completion of
718 * link training.
719 * @this_phy: This parameter specifies the phy object for which link training
720 * has completed.
721 * @max_link_rate: This parameter specifies the maximum link rate to be
722 * associated with this phy.
723 * @next_state: This parameter specifies the next state for the phy's starting
724 * sub-state machine.
725 *
726 */
727static void scic_sds_phy_complete_link_training(
728 struct scic_sds_phy *this_phy,
729 enum sci_sas_link_rate max_link_rate,
730 u32 next_state)
731{
732 this_phy->max_negotiated_speed = max_link_rate;
733
734 sci_base_state_machine_change_state(
735 scic_sds_phy_get_starting_substate_machine(this_phy), next_state
736 );
737}
738
739/**
740 *
741 * @this_phy: The struct scic_sds_phy object to restart.
742 *
743 * This method restarts the struct scic_sds_phy objects base state machine in the
744 * starting state from any starting substate. none
745 */
746static void scic_sds_phy_restart_starting_state(
747 struct scic_sds_phy *this_phy)
748{
749 /* Stop the current substate machine */
750 sci_base_state_machine_stop(
751 scic_sds_phy_get_starting_substate_machine(this_phy)
752 );
753
754 /* Re-enter the base state machine starting state */
755 sci_base_state_machine_change_state(
756 scic_sds_phy_get_base_state_machine(this_phy),
757 SCI_BASE_PHY_STATE_STARTING
758 );
759}
760
c658b109
PM
761/* ****************************************************************************
762 * SCIC SDS PHY general handlers
763 ************************************************************************** */
764static enum sci_status scic_sds_phy_starting_substate_general_stop_handler(
765 struct sci_base_phy *phy)
766{
767 struct scic_sds_phy *this_phy;
768 this_phy = (struct scic_sds_phy *)phy;
769
770 sci_base_state_machine_stop(&this_phy->starting_substate_machine);
771
772 sci_base_state_machine_change_state(&phy->state_machine,
773 SCI_BASE_PHY_STATE_STOPPED);
774
775 return SCI_SUCCESS;
776}
777
6f231dda
DW
778/*
779 * *****************************************************************************
780 * * SCIC SDS PHY EVENT_HANDLERS
781 * ***************************************************************************** */
782
783/**
784 *
785 * @phy: This struct scic_sds_phy object which has received an event.
786 * @event_code: This is the event code which the phy object is to decode.
787 *
788 * This method is called when an event notification is received for the phy
789 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
790 * decode the event - sas phy detected causes a state transition to the wait
791 * for speed event notification. - any other events log a warning message and
792 * set a failure status enum sci_status SCI_SUCCESS on any valid event notification
793 * SCI_FAILURE on any unexpected event notifation
794 */
795static enum sci_status scic_sds_phy_starting_substate_await_ossp_event_handler(
796 struct scic_sds_phy *this_phy,
797 u32 event_code)
798{
799 u32 result = SCI_SUCCESS;
800
801 switch (scu_get_event_code(event_code)) {
802 case SCU_EVENT_SAS_PHY_DETECTED:
803 scic_sds_phy_start_sas_link_training(this_phy);
804 this_phy->is_in_link_training = true;
805 break;
806
807 case SCU_EVENT_SATA_SPINUP_HOLD:
808 scic_sds_phy_start_sata_link_training(this_phy);
809 this_phy->is_in_link_training = true;
810 break;
811
812 default:
813 dev_warn(sciphy_to_dev(this_phy),
814 "%s: PHY starting substate machine received "
815 "unexpected event_code %x\n",
816 __func__,
817 event_code);
818
819 result = SCI_FAILURE;
820 break;
821 }
822
823 return result;
824}
825
826/**
827 *
828 * @phy: This struct scic_sds_phy object which has received an event.
829 * @event_code: This is the event code which the phy object is to decode.
830 *
831 * This method is called when an event notification is received for the phy
832 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
833 * decode the event - sas phy detected returns us back to this state. - speed
834 * event detected causes a state transition to the wait for iaf. - identify
835 * timeout is an un-expected event and the state machine is restarted. - link
836 * failure events restart the starting state machine - any other events log a
837 * warning message and set a failure status enum sci_status SCI_SUCCESS on any valid
838 * event notification SCI_FAILURE on any unexpected event notifation
839 */
840static enum sci_status scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler(
841 struct scic_sds_phy *this_phy,
842 u32 event_code)
843{
844 u32 result = SCI_SUCCESS;
845
846 switch (scu_get_event_code(event_code)) {
847 case SCU_EVENT_SAS_PHY_DETECTED:
848 /*
849 * Why is this being reported again by the controller?
850 * We would re-enter this state so just stay here */
851 break;
852
853 case SCU_EVENT_SAS_15:
854 case SCU_EVENT_SAS_15_SSC:
855 scic_sds_phy_complete_link_training(
856 this_phy, SCI_SAS_150_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
857 );
858 break;
859
860 case SCU_EVENT_SAS_30:
861 case SCU_EVENT_SAS_30_SSC:
862 scic_sds_phy_complete_link_training(
863 this_phy, SCI_SAS_300_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
864 );
865 break;
866
867 case SCU_EVENT_SAS_60:
868 case SCU_EVENT_SAS_60_SSC:
869 scic_sds_phy_complete_link_training(
870 this_phy, SCI_SAS_600_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
871 );
872 break;
873
874 case SCU_EVENT_SATA_SPINUP_HOLD:
875 /*
876 * We were doing SAS PHY link training and received a SATA PHY event
877 * continue OOB/SN as if this were a SATA PHY */
878 scic_sds_phy_start_sata_link_training(this_phy);
879 break;
880
881 case SCU_EVENT_LINK_FAILURE:
882 /* Link failure change state back to the starting state */
883 scic_sds_phy_restart_starting_state(this_phy);
884 break;
885
886 default:
887 dev_warn(sciphy_to_dev(this_phy),
888 "%s: PHY starting substate machine received "
889 "unexpected event_code %x\n",
890 __func__,
891 event_code);
892
893 result = SCI_FAILURE;
894 break;
895 }
896
897 return result;
898}
899
900/**
901 *
902 * @phy: This struct scic_sds_phy object which has received an event.
903 * @event_code: This is the event code which the phy object is to decode.
904 *
905 * This method is called when an event notification is received for the phy
906 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. -
907 * decode the event - sas phy detected event backs up the state machine to the
908 * await speed notification. - identify timeout is an un-expected event and the
909 * state machine is restarted. - link failure events restart the starting state
910 * machine - any other events log a warning message and set a failure status
911 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
912 * unexpected event notifation
913 */
914static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_event_handler(
915 struct scic_sds_phy *this_phy,
916 u32 event_code)
917{
918 u32 result = SCI_SUCCESS;
919
920 switch (scu_get_event_code(event_code)) {
921 case SCU_EVENT_SAS_PHY_DETECTED:
922 /* Backup the state machine */
923 scic_sds_phy_start_sas_link_training(this_phy);
924 break;
925
926 case SCU_EVENT_SATA_SPINUP_HOLD:
927 /*
928 * We were doing SAS PHY link training and received a SATA PHY event
929 * continue OOB/SN as if this were a SATA PHY */
930 scic_sds_phy_start_sata_link_training(this_phy);
931 break;
932
933 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
934 case SCU_EVENT_LINK_FAILURE:
935 case SCU_EVENT_HARD_RESET_RECEIVED:
936 /* Start the oob/sn state machine over again */
937 scic_sds_phy_restart_starting_state(this_phy);
938 break;
939
940 default:
941 dev_warn(sciphy_to_dev(this_phy),
942 "%s: PHY starting substate machine received "
943 "unexpected event_code %x\n",
944 __func__,
945 event_code);
946
947 result = SCI_FAILURE;
948 break;
949 }
950
951 return result;
952}
953
954/**
955 *
956 * @phy: This struct scic_sds_phy object which has received an event.
957 * @event_code: This is the event code which the phy object is to decode.
958 *
959 * This method is called when an event notification is received for the phy
960 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. -
961 * decode the event - link failure events restart the starting state machine -
962 * any other events log a warning message and set a failure status enum sci_status
963 * SCI_SUCCESS on a link failure event SCI_FAILURE on any unexpected event
964 * notifation
965 */
966static enum sci_status scic_sds_phy_starting_substate_await_sas_power_event_handler(
967 struct scic_sds_phy *this_phy,
968 u32 event_code)
969{
970 u32 result = SCI_SUCCESS;
971
972 switch (scu_get_event_code(event_code)) {
973 case SCU_EVENT_LINK_FAILURE:
974 /* Link failure change state back to the starting state */
975 scic_sds_phy_restart_starting_state(this_phy);
976 break;
977
978 default:
979 dev_warn(sciphy_to_dev(this_phy),
980 "%s: PHY starting substate machine received unexpected "
981 "event_code %x\n",
982 __func__,
983 event_code);
984
985 result = SCI_FAILURE;
986 break;
987 }
988
989 return result;
990}
991
992/**
993 *
994 * @phy: This struct scic_sds_phy object which has received an event.
995 * @event_code: This is the event code which the phy object is to decode.
996 *
997 * This method is called when an event notification is received for the phy
998 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. -
999 * decode the event - link failure events restart the starting state machine -
1000 * sata spinup hold events are ignored since they are expected - any other
1001 * events log a warning message and set a failure status enum sci_status SCI_SUCCESS
1002 * on a link failure event SCI_FAILURE on any unexpected event notifation
1003 */
1004static enum sci_status scic_sds_phy_starting_substate_await_sata_power_event_handler(
1005 struct scic_sds_phy *this_phy,
1006 u32 event_code)
1007{
1008 u32 result = SCI_SUCCESS;
1009
1010 switch (scu_get_event_code(event_code)) {
1011 case SCU_EVENT_LINK_FAILURE:
1012 /* Link failure change state back to the starting state */
1013 scic_sds_phy_restart_starting_state(this_phy);
1014 break;
1015
1016 case SCU_EVENT_SATA_SPINUP_HOLD:
1017 /* These events are received every 10ms and are expected while in this state */
1018 break;
1019
1020 case SCU_EVENT_SAS_PHY_DETECTED:
1021 /*
1022 * There has been a change in the phy type before OOB/SN for the
1023 * SATA finished start down the SAS link traning path. */
1024 scic_sds_phy_start_sas_link_training(this_phy);
1025 break;
1026
1027 default:
1028 dev_warn(sciphy_to_dev(this_phy),
1029 "%s: PHY starting substate machine received "
1030 "unexpected event_code %x\n",
1031 __func__,
1032 event_code);
1033
1034 result = SCI_FAILURE;
1035 break;
1036 }
1037
1038 return result;
1039}
1040
1041/**
1042 *
1043 * @phy: This struct scic_sds_phy object which has received an event.
1044 * @event_code: This is the event code which the phy object is to decode.
1045 *
1046 * This method is called when an event notification is received for the phy
1047 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. -
1048 * decode the event - link failure events restart the starting state machine -
1049 * sata spinup hold events are ignored since they are expected - sata phy
1050 * detected event change to the wait speed event - any other events log a
1051 * warning message and set a failure status enum sci_status SCI_SUCCESS on a link
1052 * failure event SCI_FAILURE on any unexpected event notifation
1053 */
1054static enum sci_status scic_sds_phy_starting_substate_await_sata_phy_event_handler(
1055 struct scic_sds_phy *this_phy,
1056 u32 event_code)
1057{
1058 u32 result = SCI_SUCCESS;
1059
1060 switch (scu_get_event_code(event_code)) {
1061 case SCU_EVENT_LINK_FAILURE:
1062 /* Link failure change state back to the starting state */
1063 scic_sds_phy_restart_starting_state(this_phy);
1064 break;
1065
1066 case SCU_EVENT_SATA_SPINUP_HOLD:
1067 /*
1068 * These events might be received since we dont know how many may be in
1069 * the completion queue while waiting for power */
1070 break;
1071
1072 case SCU_EVENT_SATA_PHY_DETECTED:
1073 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
1074
1075 /* We have received the SATA PHY notification change state */
1076 sci_base_state_machine_change_state(
1077 scic_sds_phy_get_starting_substate_machine(this_phy),
1078 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1079 );
1080 break;
1081
1082 case SCU_EVENT_SAS_PHY_DETECTED:
1083 /*
1084 * There has been a change in the phy type before OOB/SN for the
1085 * SATA finished start down the SAS link traning path. */
1086 scic_sds_phy_start_sas_link_training(this_phy);
1087 break;
1088
1089 default:
1090 dev_warn(sciphy_to_dev(this_phy),
1091 "%s: PHY starting substate machine received "
1092 "unexpected event_code %x\n",
1093 __func__,
1094 event_code);
1095
1096 result = SCI_FAILURE;
1097 break;
1098 }
1099
1100 return result;
1101}
1102
1103/**
1104 *
1105 * @phy: This struct scic_sds_phy object which has received an event.
1106 * @event_code: This is the event code which the phy object is to decode.
1107 *
1108 * This method is called when an event notification is received for the phy
1109 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
1110 * - decode the event - sata phy detected returns us back to this state. -
1111 * speed event detected causes a state transition to the wait for signature. -
1112 * link failure events restart the starting state machine - any other events
1113 * log a warning message and set a failure status enum sci_status SCI_SUCCESS on any
1114 * valid event notification SCI_FAILURE on any unexpected event notifation
1115 */
1116static enum sci_status scic_sds_phy_starting_substate_await_sata_speed_event_handler(
1117 struct scic_sds_phy *this_phy,
1118 u32 event_code)
1119{
1120 u32 result = SCI_SUCCESS;
1121
1122 switch (scu_get_event_code(event_code)) {
1123 case SCU_EVENT_SATA_PHY_DETECTED:
1124 /*
1125 * The hardware reports multiple SATA PHY detected events
1126 * ignore the extras */
1127 break;
1128
1129 case SCU_EVENT_SATA_15:
1130 case SCU_EVENT_SATA_15_SSC:
1131 scic_sds_phy_complete_link_training(
1132 this_phy,
1133 SCI_SAS_150_GB,
1134 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1135 );
1136 break;
1137
1138 case SCU_EVENT_SATA_30:
1139 case SCU_EVENT_SATA_30_SSC:
1140 scic_sds_phy_complete_link_training(
1141 this_phy,
1142 SCI_SAS_300_GB,
1143 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1144 );
1145 break;
1146
1147 case SCU_EVENT_SATA_60:
1148 case SCU_EVENT_SATA_60_SSC:
1149 scic_sds_phy_complete_link_training(
1150 this_phy,
1151 SCI_SAS_600_GB,
1152 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1153 );
1154 break;
1155
1156 case SCU_EVENT_LINK_FAILURE:
1157 /* Link failure change state back to the starting state */
1158 scic_sds_phy_restart_starting_state(this_phy);
1159 break;
1160
1161 case SCU_EVENT_SAS_PHY_DETECTED:
1162 /*
1163 * There has been a change in the phy type before OOB/SN for the
1164 * SATA finished start down the SAS link traning path. */
1165 scic_sds_phy_start_sas_link_training(this_phy);
1166 break;
1167
1168 default:
1169 dev_warn(sciphy_to_dev(this_phy),
1170 "%s: PHY starting substate machine received "
1171 "unexpected event_code %x\n",
1172 __func__,
1173 event_code);
1174
1175 result = SCI_FAILURE;
1176 break;
1177 }
1178
1179 return result;
1180}
1181
1182/**
1183 *
1184 * @phy: This struct scic_sds_phy object which has received an event.
1185 * @event_code: This is the event code which the phy object is to decode.
1186 *
1187 * This method is called when an event notification is received for the phy
1188 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. -
1189 * decode the event - sas phy detected event backs up the state machine to the
1190 * await speed notification. - identify timeout is an un-expected event and the
1191 * state machine is restarted. - link failure events restart the starting state
1192 * machine - any other events log a warning message and set a failure status
1193 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
1194 * unexpected event notifation
1195 */
1196static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_event_handler(
1197 struct scic_sds_phy *this_phy,
1198 u32 event_code)
1199{
1200 u32 result = SCI_SUCCESS;
1201
1202 switch (scu_get_event_code(event_code)) {
1203 case SCU_EVENT_SATA_PHY_DETECTED:
1204 /* Backup the state machine */
1205 sci_base_state_machine_change_state(
1206 scic_sds_phy_get_starting_substate_machine(this_phy),
1207 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1208 );
1209 break;
1210
1211 case SCU_EVENT_LINK_FAILURE:
1212 /* Link failure change state back to the starting state */
1213 scic_sds_phy_restart_starting_state(this_phy);
1214 break;
1215
1216 default:
1217 dev_warn(sciphy_to_dev(this_phy),
1218 "%s: PHY starting substate machine received "
1219 "unexpected event_code %x\n",
1220 __func__,
1221 event_code);
1222
1223 result = SCI_FAILURE;
1224 break;
1225 }
1226
1227 return result;
1228}
1229
1230
1231/*
1232 * *****************************************************************************
1233 * * SCIC SDS PHY FRAME_HANDLERS
1234 * ***************************************************************************** */
1235
1236/**
1237 *
1238 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1239 * frame data.
1240 * @frame_index: This is the index of the unsolicited frame which was received
1241 * for this phy.
1242 *
1243 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1244 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Get the UF Header - If the UF
1245 * is an IAF - Copy IAF data to local phy object IAF data buffer. - Change
1246 * starting substate to wait power. - else - log warning message of unexpected
1247 * unsolicted frame - release frame buffer enum sci_status SCI_SUCCESS
1248 */
1249static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler(
1250 struct scic_sds_phy *this_phy,
1251 u32 frame_index)
1252{
1253 enum sci_status result;
1254 u32 *frame_words;
1255 struct sci_sas_identify_address_frame *identify_frame;
1256
1257 result = scic_sds_unsolicited_frame_control_get_header(
1258 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1259 frame_index,
1260 (void **)&frame_words);
1261
1262 if (result != SCI_SUCCESS) {
1263 return result;
1264 }
1265
1266 frame_words[0] = SCIC_SWAP_DWORD(frame_words[0]);
1267 identify_frame = (struct sci_sas_identify_address_frame *)frame_words;
1268
1269 if (identify_frame->address_frame_type == 0) {
1270 /*
1271 * Byte swap the rest of the frame so we can make
1272 * a copy of the buffer */
1273 frame_words[1] = SCIC_SWAP_DWORD(frame_words[1]);
1274 frame_words[2] = SCIC_SWAP_DWORD(frame_words[2]);
1275 frame_words[3] = SCIC_SWAP_DWORD(frame_words[3]);
1276 frame_words[4] = SCIC_SWAP_DWORD(frame_words[4]);
1277 frame_words[5] = SCIC_SWAP_DWORD(frame_words[5]);
1278
1279 memcpy(
1280 &this_phy->phy_type.sas.identify_address_frame_buffer,
1281 identify_frame,
1282 sizeof(struct sci_sas_identify_address_frame)
1283 );
1284
1285 if (identify_frame->protocols.u.bits.smp_target) {
1286 /*
1287 * We got the IAF for an expander PHY go to the final state since
1288 * there are no power requirements for expander phys. */
1289 sci_base_state_machine_change_state(
1290 scic_sds_phy_get_starting_substate_machine(this_phy),
1291 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1292 );
1293 } else {
1294 /* We got the IAF we can now go to the await spinup semaphore state */
1295 sci_base_state_machine_change_state(
1296 scic_sds_phy_get_starting_substate_machine(this_phy),
1297 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1298 );
1299 }
1300
1301 result = SCI_SUCCESS;
1302 } else
1303 dev_warn(sciphy_to_dev(this_phy),
1304 "%s: PHY starting substate machine received "
1305 "unexpected frame id %x\n",
1306 __func__,
1307 frame_index);
1308
1309 /* Regardless of the result release this frame since we are done with it */
1310 scic_sds_controller_release_frame(
1311 scic_sds_phy_get_controller(this_phy), frame_index
1312 );
1313
1314 return result;
1315}
1316
1317/**
1318 *
1319 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1320 * frame data.
1321 * @frame_index: This is the index of the unsolicited frame which was received
1322 * for this phy.
1323 *
1324 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1325 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Get the UF Header - If
1326 * the UF is an SIGNATURE FIS - Copy IAF data to local phy object SIGNATURE FIS
1327 * data buffer. - else - log warning message of unexpected unsolicted frame -
1328 * release frame buffer enum sci_status SCI_SUCCESS Must decode the SIGNATURE FIS
1329 * data
1330 */
1331static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_frame_handler(
1332 struct scic_sds_phy *this_phy,
1333 u32 frame_index)
1334{
1335 enum sci_status result;
1336 u32 *frame_words;
1337 struct sata_fis_header *fis_frame_header;
1338 u32 *fis_frame_data;
1339
1340 result = scic_sds_unsolicited_frame_control_get_header(
1341 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1342 frame_index,
1343 (void **)&frame_words);
1344
1345 if (result != SCI_SUCCESS) {
1346 return result;
1347 }
1348
1349 fis_frame_header = (struct sata_fis_header *)frame_words;
1350
1351 if (
1352 (fis_frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
1353 && !(fis_frame_header->status & ATA_STATUS_REG_BSY_BIT)
1354 ) {
1355 scic_sds_unsolicited_frame_control_get_buffer(
1356 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1357 frame_index,
1358 (void **)&fis_frame_data
1359 );
1360
1361 scic_sds_controller_copy_sata_response(
1362 &this_phy->phy_type.sata.signature_fis_buffer,
1363 frame_words,
1364 fis_frame_data
1365 );
1366
1367 /* We got the IAF we can now go to the await spinup semaphore state */
1368 sci_base_state_machine_change_state(
1369 scic_sds_phy_get_starting_substate_machine(this_phy),
1370 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1371 );
1372
1373 result = SCI_SUCCESS;
1374 } else
1375 dev_warn(sciphy_to_dev(this_phy),
1376 "%s: PHY starting substate machine received "
1377 "unexpected frame id %x\n",
1378 __func__,
1379 frame_index);
1380
1381 /* Regardless of the result release this frame since we are done with it */
1382 scic_sds_controller_release_frame(
1383 scic_sds_phy_get_controller(this_phy), frame_index
1384 );
1385
1386 return result;
1387}
1388
1389/*
1390 * *****************************************************************************
1391 * * SCIC SDS PHY POWER_HANDLERS
1392 * ***************************************************************************** */
1393
1394/**
1395 *
1396 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
1397 * object.
1398 *
1399 * This method is called by the struct scic_sds_controller when the phy object is
1400 * granted power. - The notify enable spinups are turned on for this phy object
1401 * - The phy state machine is transitioned to the
1402 * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. enum sci_status SCI_SUCCESS
1403 */
1404static enum sci_status scic_sds_phy_starting_substate_await_sas_power_consume_power_handler(
1405 struct scic_sds_phy *this_phy)
1406{
1407 u32 enable_spinup;
1408
1409 enable_spinup = SCU_SAS_ENSPINUP_READ(this_phy);
1410 enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
1411 SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup);
1412
1413 /* Change state to the final state this substate machine has run to completion */
1414 sci_base_state_machine_change_state(
1415 scic_sds_phy_get_starting_substate_machine(this_phy),
1416 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1417 );
1418
1419 return SCI_SUCCESS;
1420}
1421
1422/**
1423 *
1424 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
1425 * object.
1426 *
1427 * This method is called by the struct scic_sds_controller when the phy object is
1428 * granted power. - The phy state machine is transitioned to the
1429 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. enum sci_status SCI_SUCCESS
1430 */
1431static enum sci_status scic_sds_phy_starting_substate_await_sata_power_consume_power_handler(
1432 struct scic_sds_phy *this_phy)
1433{
1434 u32 scu_sas_pcfg_value;
1435
1436 /* Release the spinup hold state and reset the OOB state machine */
1437 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
1438 scu_sas_pcfg_value &=
1439 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
1440 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1441 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
1442
1443 /* Now restart the OOB operation */
1444 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1445 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
1446 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
1447
1448 /* Change state to the final state this substate machine has run to completion */
1449 sci_base_state_machine_change_state(
1450 scic_sds_phy_get_starting_substate_machine(this_phy),
1451 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
1452 );
1453
1454 return SCI_SUCCESS;
1455}
1456
8f31550c
DW
1457const struct scic_sds_phy_state_handler scic_sds_phy_starting_substate_handler_table[] = {
1458 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
1459 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1460 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1461 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1462 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1463 .frame_handler = scic_sds_phy_default_frame_handler,
1464 .event_handler = scic_sds_phy_default_event_handler,
1465 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 1466 },
8f31550c
DW
1467 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
1468 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1469 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1470 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1471 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1472 .frame_handler = scic_sds_phy_default_frame_handler,
1473 .event_handler = scic_sds_phy_starting_substate_await_ossp_event_handler,
1474 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 1475 },
8f31550c
DW
1476 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
1477 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1478 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1479 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1480 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1481 .frame_handler = scic_sds_phy_default_frame_handler,
1482 .event_handler = scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler,
1483 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 1484 },
8f31550c
DW
1485 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = {
1486 .parent.start_handler = scic_sds_phy_default_start_handler,
1487 .parent.stop_handler = scic_sds_phy_default_stop_handler,
1488 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1489 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1490 .frame_handler = scic_sds_phy_starting_substate_await_iaf_uf_frame_handler,
1491 .event_handler = scic_sds_phy_starting_substate_await_iaf_uf_event_handler,
1492 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 1493 },
8f31550c
DW
1494 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
1495 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1496 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1497 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1498 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1499 .frame_handler = scic_sds_phy_default_frame_handler,
1500 .event_handler = scic_sds_phy_starting_substate_await_sas_power_event_handler,
1501 .consume_power_handler = scic_sds_phy_starting_substate_await_sas_power_consume_power_handler
6f231dda 1502 },
8f31550c
DW
1503 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
1504 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1505 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1506 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1507 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1508 .frame_handler = scic_sds_phy_default_frame_handler,
1509 .event_handler = scic_sds_phy_starting_substate_await_sata_power_event_handler,
1510 .consume_power_handler = scic_sds_phy_starting_substate_await_sata_power_consume_power_handler
6f231dda 1511 },
8f31550c
DW
1512 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
1513 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1514 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1515 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1516 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1517 .frame_handler = scic_sds_phy_default_frame_handler,
1518 .event_handler = scic_sds_phy_starting_substate_await_sata_phy_event_handler,
1519 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 1520 },
8f31550c
DW
1521 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
1522 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1523 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1524 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1525 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1526 .frame_handler = scic_sds_phy_default_frame_handler,
1527 .event_handler = scic_sds_phy_starting_substate_await_sata_speed_event_handler,
1528 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 1529 },
8f31550c
DW
1530 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
1531 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1532 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1533 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1534 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1535 .frame_handler = scic_sds_phy_starting_substate_await_sig_fis_frame_handler,
1536 .event_handler = scic_sds_phy_starting_substate_await_sig_fis_event_handler,
1537 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 1538 },
8f31550c
DW
1539 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
1540 .parent.start_handler = scic_sds_phy_default_start_handler,
c658b109 1541 .parent.stop_handler = scic_sds_phy_starting_substate_general_stop_handler,
8f31550c
DW
1542 .parent.reset_handler = scic_sds_phy_default_reset_handler,
1543 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
1544 .frame_handler = scic_sds_phy_default_frame_handler,
1545 .event_handler = scic_sds_phy_default_event_handler,
1546 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda
DW
1547 }
1548};
1549
1550/**
1551 * scic_sds_phy_set_starting_substate_handlers() -
1552 *
1553 * This macro sets the starting substate handlers by state_id
1554 */
1555#define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \
1556 scic_sds_phy_set_state_handlers(\
1557 (phy), \
1558 &scic_sds_phy_starting_substate_handler_table[(state_id)] \
1559 )
1560
1561/*
1562 * ****************************************************************************
1563 * * PHY STARTING SUBSTATE METHODS
1564 * **************************************************************************** */
1565
1566/**
1567 *
1568 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1569 *
1570 * This method will perform the actions required by the struct scic_sds_phy on
1571 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL. - The initial state
1572 * handlers are put in place for the struct scic_sds_phy object. - The state is
1573 * changed to the wait phy type event notification. none
1574 */
1575static void scic_sds_phy_starting_initial_substate_enter(
1576 struct sci_base_object *object)
1577{
1578 struct scic_sds_phy *this_phy;
1579
1580 this_phy = (struct scic_sds_phy *)object;
1581
1582 scic_sds_phy_set_starting_substate_handlers(
1583 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
1584
1585 /* This is just an temporary state go off to the starting state */
1586 sci_base_state_machine_change_state(
1587 scic_sds_phy_get_starting_substate_machine(this_phy),
1588 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1589 );
1590}
1591
1592/**
1593 *
1594 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1595 *
1596 * This method will perform the actions required by the struct scic_sds_phy on
1597 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_PHY_TYPE_EN. - Set the
1598 * struct scic_sds_phy object state handlers for this state. none
1599 */
1600static void scic_sds_phy_starting_await_ossp_en_substate_enter(
1601 struct sci_base_object *object)
1602{
1603 struct scic_sds_phy *this_phy;
1604
1605 this_phy = (struct scic_sds_phy *)object;
1606
1607 scic_sds_phy_set_starting_substate_handlers(
1608 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1609 );
1610}
1611
1612/**
1613 *
1614 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1615 *
1616 * This method will perform the actions required by the struct scic_sds_phy on
1617 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - Set the
1618 * struct scic_sds_phy object state handlers for this state. none
1619 */
1620static void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
1621 struct sci_base_object *object)
1622{
1623 struct scic_sds_phy *this_phy;
1624
1625 this_phy = (struct scic_sds_phy *)object;
1626
1627 scic_sds_phy_set_starting_substate_handlers(
1628 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
1629 );
1630}
1631
1632/**
1633 *
1634 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1635 *
1636 * This method will perform the actions required by the struct scic_sds_phy on
1637 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Set the
1638 * struct scic_sds_phy object state handlers for this state. none
1639 */
1640static void scic_sds_phy_starting_await_iaf_uf_substate_enter(
1641 struct sci_base_object *object)
1642{
1643 struct scic_sds_phy *this_phy;
1644
1645 this_phy = (struct scic_sds_phy *)object;
1646
1647 scic_sds_phy_set_starting_substate_handlers(
1648 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
1649 );
1650}
1651
1652/**
1653 *
1654 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1655 *
1656 * This method will perform the actions required by the struct scic_sds_phy on
1657 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Set the
1658 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1659 * the power control queue none
1660 */
1661static void scic_sds_phy_starting_await_sas_power_substate_enter(
1662 struct sci_base_object *object)
1663{
1664 struct scic_sds_phy *this_phy;
1665
1666 this_phy = (struct scic_sds_phy *)object;
1667
1668 scic_sds_phy_set_starting_substate_handlers(
1669 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1670 );
1671
1672 scic_sds_controller_power_control_queue_insert(
1673 scic_sds_phy_get_controller(this_phy),
1674 this_phy
1675 );
1676}
1677
1678/**
1679 *
1680 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1681 *
1682 * This method will perform the actions required by the struct scic_sds_phy on exiting
1683 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Remove the
1684 * struct scic_sds_phy object from the power control queue. none
1685 */
1686static void scic_sds_phy_starting_await_sas_power_substate_exit(
1687 struct sci_base_object *object)
1688{
1689 struct scic_sds_phy *this_phy;
1690
1691 this_phy = (struct scic_sds_phy *)object;
1692
1693 scic_sds_controller_power_control_queue_remove(
1694 scic_sds_phy_get_controller(this_phy), this_phy
1695 );
1696}
1697
1698/**
1699 *
1700 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1701 *
1702 * This method will perform the actions required by the struct scic_sds_phy on
1703 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Set the
1704 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1705 * the power control queue none
1706 */
1707static void scic_sds_phy_starting_await_sata_power_substate_enter(
1708 struct sci_base_object *object)
1709{
1710 struct scic_sds_phy *this_phy;
1711
1712 this_phy = (struct scic_sds_phy *)object;
1713
1714 scic_sds_phy_set_starting_substate_handlers(
1715 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
1716 );
1717
1718 scic_sds_controller_power_control_queue_insert(
1719 scic_sds_phy_get_controller(this_phy),
1720 this_phy
1721 );
1722}
1723
1724/**
1725 *
1726 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1727 *
1728 * This method will perform the actions required by the struct scic_sds_phy on exiting
1729 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Remove the
1730 * struct scic_sds_phy object from the power control queue. none
1731 */
1732static void scic_sds_phy_starting_await_sata_power_substate_exit(
1733 struct sci_base_object *object)
1734{
1735 struct scic_sds_phy *this_phy;
1736
1737 this_phy = (struct scic_sds_phy *)object;
1738
1739 scic_sds_controller_power_control_queue_remove(
1740 scic_sds_phy_get_controller(this_phy),
1741 this_phy
1742 );
1743}
1744
1745/**
1746 *
1747 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1748 *
1749 * This method will perform the actions required by the struct scic_sds_phy on
1750 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. - Set the
1751 * struct scic_sds_phy object state handlers for this state. none
1752 */
1753static void scic_sds_phy_starting_await_sata_phy_substate_enter(
1754 struct sci_base_object *object)
1755{
1756 struct scic_sds_phy *this_phy;
1757
1758 this_phy = (struct scic_sds_phy *)object;
1759
1760 scic_sds_phy_set_starting_substate_handlers(
1761 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
1762 );
1763
a1914059 1764 isci_event_timer_start(
6f231dda
DW
1765 scic_sds_phy_get_controller(this_phy),
1766 this_phy->sata_timeout_timer,
1767 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
1768 );
1769}
1770
1771/**
1772 *
1773 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1774 *
1775 * This method will perform the actions required by the struct scic_sds_phy on exiting
1776 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1777 * that was started on entry to await sata phy event notification none
1778 */
1779static void scic_sds_phy_starting_await_sata_phy_substate_exit(
1780 struct sci_base_object *object)
1781{
1782 struct scic_sds_phy *this_phy;
1783
1784 this_phy = (struct scic_sds_phy *)object;
1785
a1914059 1786 isci_event_timer_stop(
6f231dda
DW
1787 scic_sds_phy_get_controller(this_phy),
1788 this_phy->sata_timeout_timer
1789 );
1790}
1791
1792/**
1793 *
1794 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1795 *
1796 * This method will perform the actions required by the struct scic_sds_phy on
1797 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - Set the
1798 * struct scic_sds_phy object state handlers for this state. none
1799 */
1800static void scic_sds_phy_starting_await_sata_speed_substate_enter(
1801 struct sci_base_object *object)
1802{
1803 struct scic_sds_phy *this_phy;
1804
1805 this_phy = (struct scic_sds_phy *)object;
1806
1807 scic_sds_phy_set_starting_substate_handlers(
1808 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1809 );
1810
a1914059 1811 isci_event_timer_start(
6f231dda
DW
1812 scic_sds_phy_get_controller(this_phy),
1813 this_phy->sata_timeout_timer,
1814 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
1815 );
1816}
1817
1818/**
1819 *
1820 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1821 *
1822 * This method will perform the actions required by the struct scic_sds_phy on exiting
1823 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1824 * that was started on entry to await sata phy event notification none
1825 */
1826static void scic_sds_phy_starting_await_sata_speed_substate_exit(
1827 struct sci_base_object *object)
1828{
1829 struct scic_sds_phy *this_phy;
1830
1831 this_phy = (struct scic_sds_phy *)object;
1832
a1914059 1833 isci_event_timer_stop(
6f231dda
DW
1834 scic_sds_phy_get_controller(this_phy),
1835 this_phy->sata_timeout_timer
1836 );
1837}
1838
1839/**
1840 *
1841 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1842 *
1843 * This method will perform the actions required by the struct scic_sds_phy on
1844 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Set the
1845 * struct scic_sds_phy object state handlers for this state. - Start the SIGNATURE FIS
1846 * timeout timer none
1847 */
1848static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(
1849 struct sci_base_object *object)
1850{
1851 bool continue_to_ready_state;
1852 struct scic_sds_phy *this_phy;
1853
1854 this_phy = (struct scic_sds_phy *)object;
1855
1856 scic_sds_phy_set_starting_substate_handlers(
1857 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1858 );
1859
1860 continue_to_ready_state = scic_sds_port_link_detected(
1861 this_phy->owning_port,
1862 this_phy
1863 );
1864
1865 if (continue_to_ready_state) {
1866 /*
1867 * Clear the PE suspend condition so we can actually receive SIG FIS
1868 * The hardware will not respond to the XRDY until the PE suspend
1869 * condition is cleared. */
1870 scic_sds_phy_resume(this_phy);
1871
a1914059 1872 isci_event_timer_start(
6f231dda
DW
1873 scic_sds_phy_get_controller(this_phy),
1874 this_phy->sata_timeout_timer,
1875 SCIC_SDS_SIGNATURE_FIS_TIMEOUT
1876 );
1877 } else {
1878 this_phy->is_in_link_training = false;
1879 }
1880}
1881
1882/**
1883 *
1884 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1885 *
1886 * This method will perform the actions required by the struct scic_sds_phy on exiting
1887 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Stop the SIGNATURE
1888 * FIS timeout timer. none
1889 */
1890static void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(
1891 struct sci_base_object *object)
1892{
1893 struct scic_sds_phy *this_phy;
1894
1895 this_phy = (struct scic_sds_phy *)object;
1896
a1914059 1897 isci_event_timer_stop(
6f231dda
DW
1898 scic_sds_phy_get_controller(this_phy),
1899 this_phy->sata_timeout_timer
1900 );
1901}
1902
1903/**
1904 *
1905 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1906 *
1907 * This method will perform the actions required by the struct scic_sds_phy on
1908 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. - Set the struct scic_sds_phy
1909 * object state handlers for this state. - Change base state machine to the
1910 * ready state. none
1911 */
1912static void scic_sds_phy_starting_final_substate_enter(
1913 struct sci_base_object *object)
1914{
1915 struct scic_sds_phy *this_phy;
1916
1917 this_phy = (struct scic_sds_phy *)object;
1918
1919 scic_sds_phy_set_starting_substate_handlers(
1920 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1921 );
1922
1923 /*
1924 * State machine has run to completion so exit out and change
1925 * the base state machine to the ready state */
1926 sci_base_state_machine_change_state(
1927 scic_sds_phy_get_base_state_machine(this_phy),
1928 SCI_BASE_PHY_STATE_READY);
1929}
1930
1931/* --------------------------------------------------------------------------- */
1932
1933const struct sci_base_state scic_sds_phy_starting_substates[] = {
1934 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
1935 .enter_state = scic_sds_phy_starting_initial_substate_enter,
1936 },
1937 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
1938 .enter_state = scic_sds_phy_starting_await_ossp_en_substate_enter,
1939 },
1940 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
1941 .enter_state = scic_sds_phy_starting_await_sas_speed_en_substate_enter,
1942 },
1943 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = {
1944 .enter_state = scic_sds_phy_starting_await_iaf_uf_substate_enter,
1945 },
1946 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
1947 .enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
1948 .exit_state = scic_sds_phy_starting_await_sas_power_substate_exit,
1949 },
1950 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
1951 .enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
1952 .exit_state = scic_sds_phy_starting_await_sata_power_substate_exit
1953 },
1954 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
1955 .enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
1956 .exit_state = scic_sds_phy_starting_await_sata_phy_substate_exit
1957 },
1958 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
1959 .enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
1960 .exit_state = scic_sds_phy_starting_await_sata_speed_substate_exit
1961 },
1962 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
1963 .enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
1964 .exit_state = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
1965 },
1966 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
1967 .enter_state = scic_sds_phy_starting_final_substate_enter,
1968 }
1969};
1970
1971/*
1972 * ***************************************************************************
1973 * * DEFAULT HANDLERS
1974 * *************************************************************************** */
1975
1976/**
1977 *
1978 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
1979 * object.
1980 *
1981 * This is the default method for phy a start request. It will report a
1982 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1983 */
1984enum sci_status scic_sds_phy_default_start_handler(
1985 struct sci_base_phy *phy)
1986{
1987 struct scic_sds_phy *this_phy;
1988
1989 this_phy = (struct scic_sds_phy *)phy;
1990
1991 dev_warn(sciphy_to_dev(this_phy),
1992 "%s: SCIC Phy 0x%p requested to start from invalid "
1993 "state %d\n",
1994 __func__,
1995 this_phy,
1996 sci_base_state_machine_get_state(
1997 &this_phy->parent.state_machine));
1998
1999 return SCI_FAILURE_INVALID_STATE;
2000
2001}
2002
2003/**
2004 *
2005 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2006 * object.
2007 *
2008 * This is the default method for phy a stop request. It will report a warning
2009 * and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2010 */
2011enum sci_status scic_sds_phy_default_stop_handler(
2012 struct sci_base_phy *phy)
2013{
2014 struct scic_sds_phy *this_phy;
2015
2016 this_phy = (struct scic_sds_phy *)phy;
2017
2018 dev_warn(sciphy_to_dev(this_phy),
2019 "%s: SCIC Phy 0x%p requested to stop from invalid "
2020 "state %d\n",
2021 __func__,
2022 this_phy,
2023 sci_base_state_machine_get_state(
2024 &this_phy->parent.state_machine));
2025
2026 return SCI_FAILURE_INVALID_STATE;
2027}
2028
2029/**
2030 *
2031 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2032 * object.
2033 *
2034 * This is the default method for phy a reset request. It will report a
2035 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2036 */
2037enum sci_status scic_sds_phy_default_reset_handler(
2038 struct sci_base_phy *phy)
2039{
2040 struct scic_sds_phy *this_phy;
2041
2042 this_phy = (struct scic_sds_phy *)phy;
2043
2044 dev_warn(sciphy_to_dev(this_phy),
2045 "%s: SCIC Phy 0x%p requested to reset from invalid state "
2046 "%d\n",
2047 __func__,
2048 this_phy,
2049 sci_base_state_machine_get_state(
2050 &this_phy->parent.state_machine));
2051
2052 return SCI_FAILURE_INVALID_STATE;
2053}
2054
2055/**
2056 *
2057 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2058 * object.
2059 *
2060 * This is the default method for phy a destruct request. It will report a
2061 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2062 */
2063enum sci_status scic_sds_phy_default_destroy_handler(
2064 struct sci_base_phy *phy)
2065{
2066 struct scic_sds_phy *this_phy;
2067
2068 this_phy = (struct scic_sds_phy *)phy;
2069
2070 /* / @todo Implement something for the default */
2071 dev_warn(sciphy_to_dev(this_phy),
2072 "%s: SCIC Phy 0x%p requested to destroy from invalid "
2073 "state %d\n",
2074 __func__,
2075 this_phy,
2076 sci_base_state_machine_get_state(
2077 &this_phy->parent.state_machine));
2078
2079 return SCI_FAILURE_INVALID_STATE;
2080}
2081
2082/**
2083 *
2084 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2085 * object.
2086 * @frame_index: This is the frame index that was received from the SCU
2087 * hardware.
2088 *
2089 * This is the default method for a phy frame handling request. It will report
2090 * a warning, release the frame and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2091 */
2092enum sci_status scic_sds_phy_default_frame_handler(
2093 struct scic_sds_phy *this_phy,
2094 u32 frame_index)
2095{
2096 dev_warn(sciphy_to_dev(this_phy),
2097 "%s: SCIC Phy 0x%p received unexpected frame data %d "
2098 "while in state %d\n",
2099 __func__,
2100 this_phy,
2101 frame_index,
2102 sci_base_state_machine_get_state(
2103 &this_phy->parent.state_machine));
2104
2105 scic_sds_controller_release_frame(
2106 scic_sds_phy_get_controller(this_phy), frame_index);
2107
2108 return SCI_FAILURE_INVALID_STATE;
2109}
2110
2111/**
2112 *
2113 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2114 * object.
2115 * @event_code: This is the event code that was received from the SCU hardware.
2116 *
2117 * This is the default method for a phy event handler. It will report a
2118 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2119 */
2120enum sci_status scic_sds_phy_default_event_handler(
2121 struct scic_sds_phy *this_phy,
2122 u32 event_code)
2123{
2124 dev_warn(sciphy_to_dev(this_phy),
2125 "%s: SCIC Phy 0x%p received unexpected event status %x "
2126 "while in state %d\n",
2127 __func__,
2128 this_phy,
2129 event_code,
2130 sci_base_state_machine_get_state(
2131 &this_phy->parent.state_machine));
2132
2133 return SCI_FAILURE_INVALID_STATE;
2134}
2135
2136/**
2137 *
2138 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2139 * object.
2140 *
2141 * This is the default method for a phy consume power handler. It will report
2142 * a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2143 */
2144enum sci_status scic_sds_phy_default_consume_power_handler(
2145 struct scic_sds_phy *this_phy)
2146{
2147 dev_warn(sciphy_to_dev(this_phy),
2148 "%s: SCIC Phy 0x%p given unexpected permission to consume "
2149 "power while in state %d\n",
2150 __func__,
2151 this_phy,
2152 sci_base_state_machine_get_state(
2153 &this_phy->parent.state_machine));
2154
2155 return SCI_FAILURE_INVALID_STATE;
2156}
2157
2158/*
2159 * ******************************************************************************
2160 * * PHY STOPPED STATE HANDLERS
2161 * ****************************************************************************** */
2162
2163/**
2164 *
2165 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2166 * object.
2167 *
2168 * This method takes the struct scic_sds_phy from a stopped state and attempts to
2169 * start it. - The phy state machine is transitioned to the
2170 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
2171 */
c658b109 2172static enum sci_status scic_sds_phy_stopped_state_start_handler(struct sci_base_phy *phy)
6f231dda
DW
2173{
2174 struct scic_sds_phy *this_phy;
2175
2176 this_phy = (struct scic_sds_phy *)phy;
2177
c658b109
PM
2178 /* Create the SIGNATURE FIS Timeout timer for this phy */
2179 this_phy->sata_timeout_timer = isci_event_timer_create(
2180 scic_sds_phy_get_controller(this_phy),
2181 scic_sds_phy_sata_timeout, this_phy);
2182
2183 if (this_phy->sata_timeout_timer != NULL) {
2184 sci_base_state_machine_change_state(
2185 scic_sds_phy_get_base_state_machine(this_phy),
2186 SCI_BASE_PHY_STATE_STARTING);
2187 }
6f231dda
DW
2188
2189 return SCI_SUCCESS;
2190}
2191
2192/**
2193 *
2194 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2195 * object.
2196 *
2197 * This method takes the struct scic_sds_phy from a stopped state and destroys it. -
2198 * This function takes no action. Shouldnt this function transition the
2199 * struct sci_base_phy::state_machine to the SCI_BASE_PHY_STATE_FINAL? enum sci_status
2200 * SCI_SUCCESS
2201 */
2202static enum sci_status scic_sds_phy_stopped_state_destroy_handler(
2203 struct sci_base_phy *phy)
2204{
2205 struct scic_sds_phy *this_phy;
2206
2207 this_phy = (struct scic_sds_phy *)phy;
2208
c658b109 2209 /* @todo what do we actually need to do here? */
6f231dda
DW
2210 return SCI_SUCCESS;
2211}
2212
2213/*
2214 * ******************************************************************************
2215 * * PHY STARTING STATE HANDLERS
2216 * ****************************************************************************** */
2217
2218/* All of these state handlers are mapped to the starting sub-state machine */
2219
2220/*
2221 * ******************************************************************************
2222 * * PHY READY STATE HANDLERS
2223 * ****************************************************************************** */
2224
2225/**
2226 *
2227 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2228 * object.
2229 *
2230 * This method takes the struct scic_sds_phy from a ready state and attempts to stop
2231 * it. - The phy state machine is transitioned to the
2232 * SCI_BASE_PHY_STATE_STOPPED. enum sci_status SCI_SUCCESS
2233 */
2234static enum sci_status scic_sds_phy_ready_state_stop_handler(
2235 struct sci_base_phy *phy)
2236{
2237 struct scic_sds_phy *this_phy;
2238
2239 this_phy = (struct scic_sds_phy *)phy;
2240
2241 sci_base_state_machine_change_state(
2242 scic_sds_phy_get_base_state_machine(this_phy),
2243 SCI_BASE_PHY_STATE_STOPPED
2244 );
2245
2246 return SCI_SUCCESS;
2247}
2248
2249/**
2250 *
2251 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2252 * object.
2253 *
2254 * This method takes the struct scic_sds_phy from a ready state and attempts to reset
2255 * it. - The phy state machine is transitioned to the
2256 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
2257 */
2258static enum sci_status scic_sds_phy_ready_state_reset_handler(
2259 struct sci_base_phy *phy)
2260{
2261 struct scic_sds_phy *this_phy;
2262
2263 this_phy = (struct scic_sds_phy *)phy;
2264
2265 sci_base_state_machine_change_state(
2266 scic_sds_phy_get_base_state_machine(this_phy),
2267 SCI_BASE_PHY_STATE_RESETTING
2268 );
2269
2270 return SCI_SUCCESS;
2271}
2272
2273/**
2274 *
2275 * @phy: This is the struct scic_sds_phy object which has received the event.
2276 *
2277 * This method request the struct scic_sds_phy handle the received event. The only
2278 * event that we are interested in while in the ready state is the link failure
2279 * event. - decoded event is a link failure - transition the struct scic_sds_phy back
2280 * to the SCI_BASE_PHY_STATE_STARTING state. - any other event recived will
2281 * report a warning message enum sci_status SCI_SUCCESS if the event received is a
2282 * link failure SCI_FAILURE_INVALID_STATE for any other event received.
2283 */
2284static enum sci_status scic_sds_phy_ready_state_event_handler(
2285 struct scic_sds_phy *this_phy,
2286 u32 event_code)
2287{
2288 enum sci_status result = SCI_FAILURE;
2289
2290 switch (scu_get_event_code(event_code)) {
2291 case SCU_EVENT_LINK_FAILURE:
2292 /* Link failure change state back to the starting state */
2293 sci_base_state_machine_change_state(
2294 scic_sds_phy_get_base_state_machine(this_phy),
2295 SCI_BASE_PHY_STATE_STARTING
2296 );
2297
2298 result = SCI_SUCCESS;
2299 break;
2300
2301 case SCU_EVENT_BROADCAST_CHANGE:
2302 /* Broadcast change received. Notify the port. */
a7e536c7 2303 if (scic_sds_phy_get_port(this_phy) != NULL)
6f231dda
DW
2304 scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy);
2305 else
2306 this_phy->bcn_received_while_port_unassigned = true;
2307 break;
2308
2309 default:
2310 dev_warn(sciphy_to_dev(this_phy),
2311 "%sP SCIC PHY 0x%p ready state machine received "
2312 "unexpected event_code %x\n",
2313 __func__,
2314 this_phy,
2315 event_code);
2316
2317 result = SCI_FAILURE_INVALID_STATE;
2318 break;
2319 }
2320
2321 return result;
2322}
2323
2324/* --------------------------------------------------------------------------- */
2325
2326/**
2327 *
2328 * @this_phy: This is the struct scic_sds_phy object which is receiving the event.
2329 * @event_code: This is the event code to be processed.
2330 *
2331 * This is the resetting state event handler. enum sci_status
2332 * SCI_FAILURE_INVALID_STATE
2333 */
2334static enum sci_status scic_sds_phy_resetting_state_event_handler(
2335 struct scic_sds_phy *this_phy,
2336 u32 event_code)
2337{
2338 enum sci_status result = SCI_FAILURE;
2339
2340 switch (scu_get_event_code(event_code)) {
2341 case SCU_EVENT_HARD_RESET_TRANSMITTED:
2342 /* Link failure change state back to the starting state */
2343 sci_base_state_machine_change_state(
2344 scic_sds_phy_get_base_state_machine(this_phy),
2345 SCI_BASE_PHY_STATE_STARTING
2346 );
2347
2348 result = SCI_SUCCESS;
2349 break;
2350
2351 default:
2352 dev_warn(sciphy_to_dev(this_phy),
2353 "%s: SCIC PHY 0x%p resetting state machine received "
2354 "unexpected event_code %x\n",
2355 __func__,
2356 this_phy,
2357 event_code);
2358
2359 result = SCI_FAILURE_INVALID_STATE;
2360 break;
2361 }
2362
2363 return result;
2364}
2365
2366/* --------------------------------------------------------------------------- */
2367
8f31550c
DW
2368const struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[] = {
2369 [SCI_BASE_PHY_STATE_INITIAL] = {
2370 .parent.start_handler = scic_sds_phy_default_start_handler,
2371 .parent.stop_handler = scic_sds_phy_default_stop_handler,
2372 .parent.reset_handler = scic_sds_phy_default_reset_handler,
2373 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
2374 .frame_handler = scic_sds_phy_default_frame_handler,
2375 .event_handler = scic_sds_phy_default_event_handler,
2376 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 2377 },
8f31550c
DW
2378 [SCI_BASE_PHY_STATE_STOPPED] = {
2379 .parent.start_handler = scic_sds_phy_stopped_state_start_handler,
2380 .parent.stop_handler = scic_sds_phy_default_stop_handler,
2381 .parent.reset_handler = scic_sds_phy_default_reset_handler,
2382 .parent.destruct_handler = scic_sds_phy_stopped_state_destroy_handler,
2383 .frame_handler = scic_sds_phy_default_frame_handler,
2384 .event_handler = scic_sds_phy_default_event_handler,
2385 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 2386 },
8f31550c
DW
2387 [SCI_BASE_PHY_STATE_STARTING] = {
2388 .parent.start_handler = scic_sds_phy_default_start_handler,
2389 .parent.stop_handler = scic_sds_phy_default_stop_handler,
2390 .parent.reset_handler = scic_sds_phy_default_reset_handler,
2391 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
2392 .frame_handler = scic_sds_phy_default_frame_handler,
2393 .event_handler = scic_sds_phy_default_event_handler,
2394 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 2395 },
8f31550c
DW
2396 [SCI_BASE_PHY_STATE_READY] = {
2397 .parent.start_handler = scic_sds_phy_default_start_handler,
2398 .parent.stop_handler = scic_sds_phy_ready_state_stop_handler,
2399 .parent.reset_handler = scic_sds_phy_ready_state_reset_handler,
2400 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
2401 .frame_handler = scic_sds_phy_default_frame_handler,
2402 .event_handler = scic_sds_phy_ready_state_event_handler,
2403 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 2404 },
8f31550c
DW
2405 [SCI_BASE_PHY_STATE_RESETTING] = {
2406 .parent.start_handler = scic_sds_phy_default_start_handler,
2407 .parent.stop_handler = scic_sds_phy_default_stop_handler,
2408 .parent.reset_handler = scic_sds_phy_default_reset_handler,
2409 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
2410 .frame_handler = scic_sds_phy_default_frame_handler,
2411 .event_handler = scic_sds_phy_resetting_state_event_handler,
2412 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda 2413 },
8f31550c
DW
2414 [SCI_BASE_PHY_STATE_FINAL] = {
2415 .parent.start_handler = scic_sds_phy_default_start_handler,
2416 .parent.stop_handler = scic_sds_phy_default_stop_handler,
2417 .parent.reset_handler = scic_sds_phy_default_reset_handler,
2418 .parent.destruct_handler = scic_sds_phy_default_destroy_handler,
2419 .frame_handler = scic_sds_phy_default_frame_handler,
2420 .event_handler = scic_sds_phy_default_event_handler,
2421 .consume_power_handler = scic_sds_phy_default_consume_power_handler
6f231dda
DW
2422 }
2423};
2424
2425/*
2426 * ****************************************************************************
2427 * * PHY STATE PRIVATE METHODS
2428 * **************************************************************************** */
2429
2430/**
2431 *
2432 * @this_phy: This is the struct scic_sds_phy object to stop.
2433 *
2434 * This method will stop the struct scic_sds_phy object. This does not reset the
2435 * protocol engine it just suspends it and places it in a state where it will
2436 * not cause the end device to power up. none
2437 */
2438static void scu_link_layer_stop_protocol_engine(
2439 struct scic_sds_phy *this_phy)
2440{
2441 u32 scu_sas_pcfg_value;
2442 u32 enable_spinup_value;
2443
2444 /* Suspend the protocol engine and place it in a sata spinup hold state */
2445 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2446 scu_sas_pcfg_value |= (
2447 SCU_SAS_PCFG_GEN_BIT(OOB_RESET)
2448 | SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE)
2449 | SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD)
2450 );
2451 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2452
2453 /* Disable the notify enable spinup primitives */
2454 enable_spinup_value = SCU_SAS_ENSPINUP_READ(this_phy);
2455 enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
2456 SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup_value);
2457}
2458
2459/**
2460 *
2461 *
2462 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
2463 */
2464static void scu_link_layer_start_oob(
2465 struct scic_sds_phy *this_phy)
2466{
2467 u32 scu_sas_pcfg_value;
2468
2469 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2470 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2471 scu_sas_pcfg_value &=
2472 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) | SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
2473
2474 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2475}
2476
2477/**
2478 *
2479 *
2480 * This method will transmit a hard reset request on the specified phy. The SCU
2481 * hardware requires that we reset the OOB state machine and set the hard reset
2482 * bit in the phy configuration register. We then must start OOB over with the
2483 * hard reset bit set.
2484 */
2485static void scu_link_layer_tx_hard_reset(
2486 struct scic_sds_phy *this_phy)
2487{
2488 u32 phy_configuration_value;
2489
2490 /*
2491 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
2492 * to the starting state. */
2493 phy_configuration_value = SCU_SAS_PCFG_READ(this_phy);
2494 phy_configuration_value |=
2495 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) | SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
2496 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value);
2497
2498 /* Now take the OOB state machine out of reset */
2499 phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2500 phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
2501 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value);
2502}
2503
2504/*
2505 * ****************************************************************************
2506 * * PHY BASE STATE METHODS
2507 * **************************************************************************** */
2508
2509/**
2510 *
2511 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2512 *
2513 * This method will perform the actions required by the struct scic_sds_phy on
2514 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2515 * handlers for the phy object base state machine initial state. none
2516 */
2517static void scic_sds_phy_initial_state_enter(
2518 struct sci_base_object *object)
2519{
2520 struct scic_sds_phy *this_phy;
2521
2522 this_phy = (struct scic_sds_phy *)object;
2523
c658b109 2524 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_INITIAL);
6f231dda
DW
2525}
2526
2527/**
2528 *
2529 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2530 *
2531 * This method will perform the actions required by the struct scic_sds_phy on
2532 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2533 * handlers for the phy object base state machine initial state. - The SCU
2534 * hardware is requested to stop the protocol engine. none
2535 */
c658b109 2536static void scic_sds_phy_stopped_state_enter(struct sci_base_object *object)
6f231dda 2537{
c658b109 2538 struct scic_sds_phy *sci_phy;
6f231dda 2539
c658b109 2540 sci_phy = (struct scic_sds_phy *)object;
6f231dda
DW
2541
2542 /* / @todo We need to get to the controller to place this PE in a reset state */
2543
c658b109
PM
2544 scic_sds_phy_set_base_state_handlers(sci_phy, SCI_BASE_PHY_STATE_STOPPED);
2545
2546 if (sci_phy->sata_timeout_timer != NULL) {
2547 isci_event_timer_destroy(scic_sds_phy_get_controller(sci_phy),
2548 sci_phy->sata_timeout_timer);
2549
2550 sci_phy->sata_timeout_timer = NULL;
2551 }
6f231dda 2552
c658b109 2553 scu_link_layer_stop_protocol_engine(sci_phy);
6f231dda
DW
2554}
2555
2556/**
2557 *
2558 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2559 *
2560 * This method will perform the actions required by the struct scic_sds_phy on
2561 * entering the SCI_BASE_PHY_STATE_STARTING. - This function sets the state
2562 * handlers for the phy object base state machine starting state. - The SCU
2563 * hardware is requested to start OOB/SN on this protocl engine. - The phy
2564 * starting substate machine is started. - If the previous state was the ready
2565 * state then the struct scic_sds_controller is informed that the phy has gone link
2566 * down. none
2567 */
2568static void scic_sds_phy_starting_state_enter(
2569 struct sci_base_object *object)
2570{
2571 struct scic_sds_phy *this_phy;
2572
2573 this_phy = (struct scic_sds_phy *)object;
2574
2575 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STARTING);
2576
2577 scu_link_layer_stop_protocol_engine(this_phy);
2578 scu_link_layer_start_oob(this_phy);
2579
2580 /* We don't know what kind of phy we are going to be just yet */
2581 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
2582 this_phy->bcn_received_while_port_unassigned = false;
2583
2584 /* Change over to the starting substate machine to continue */
2585 sci_base_state_machine_start(&this_phy->starting_substate_machine);
2586
2587 if (this_phy->parent.state_machine.previous_state_id
2588 == SCI_BASE_PHY_STATE_READY) {
2589 scic_sds_controller_link_down(
2590 scic_sds_phy_get_controller(this_phy),
2591 scic_sds_phy_get_port(this_phy),
2592 this_phy
2593 );
2594 }
2595}
2596
2597/**
2598 *
2599 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2600 *
2601 * This method will perform the actions required by the struct scic_sds_phy on
2602 * entering the SCI_BASE_PHY_STATE_READY. - This function sets the state
2603 * handlers for the phy object base state machine ready state. - The SCU
2604 * hardware protocol engine is resumed. - The struct scic_sds_controller is informed
2605 * that the phy object has gone link up. none
2606 */
2607static void scic_sds_phy_ready_state_enter(
2608 struct sci_base_object *object)
2609{
2610 struct scic_sds_phy *this_phy;
2611
2612 this_phy = (struct scic_sds_phy *)object;
2613
2614 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_READY);
2615
2616 scic_sds_controller_link_up(
2617 scic_sds_phy_get_controller(this_phy),
2618 scic_sds_phy_get_port(this_phy),
2619 this_phy
2620 );
2621}
2622
2623/**
2624 *
2625 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2626 *
2627 * This method will perform the actions required by the struct scic_sds_phy on exiting
2628 * the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU hardware
2629 * protocol engine represented by this struct scic_sds_phy object. none
2630 */
2631static void scic_sds_phy_ready_state_exit(
2632 struct sci_base_object *object)
2633{
2634 struct scic_sds_phy *this_phy;
2635
2636 this_phy = (struct scic_sds_phy *)object;
2637
2638 scic_sds_phy_suspend(this_phy);
2639}
2640
2641/**
2642 *
2643 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2644 *
2645 * This method will perform the actions required by the struct scic_sds_phy on
2646 * entering the SCI_BASE_PHY_STATE_RESETTING. - This function sets the state
2647 * handlers for the phy object base state machine resetting state. none
2648 */
2649static void scic_sds_phy_resetting_state_enter(
2650 struct sci_base_object *object)
2651{
2652 struct scic_sds_phy *this_phy;
2653
2654 this_phy = (struct scic_sds_phy *)object;
2655
2656 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_RESETTING);
2657
2658 /*
2659 * The phy is being reset, therefore deactivate it from the port.
2660 * In the resetting state we don't notify the user regarding
2661 * link up and link down notifications. */
2662 scic_sds_port_deactivate_phy(this_phy->owning_port, this_phy, false);
2663
2664 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
2665 scu_link_layer_tx_hard_reset(this_phy);
2666 } else {
2667 /*
2668 * The SCU does not need to have a descrete reset state so just go back to
2669 * the starting state. */
2670 sci_base_state_machine_change_state(
2671 &this_phy->parent.state_machine,
2672 SCI_BASE_PHY_STATE_STARTING
2673 );
2674 }
2675}
2676
2677/**
2678 *
2679 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2680 *
2681 * This method will perform the actions required by the struct scic_sds_phy on
2682 * entering the SCI_BASE_PHY_STATE_FINAL. - This function sets the state
2683 * handlers for the phy object base state machine final state. none
2684 */
2685static void scic_sds_phy_final_state_enter(
2686 struct sci_base_object *object)
2687{
2688 struct scic_sds_phy *this_phy;
2689
2690 this_phy = (struct scic_sds_phy *)object;
2691
2692 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_FINAL);
2693
2694 /* Nothing to do here */
2695}
2696
2697/* --------------------------------------------------------------------------- */
2698
2699const struct sci_base_state scic_sds_phy_state_table[] = {
2700 [SCI_BASE_PHY_STATE_INITIAL] = {
2701 .enter_state = scic_sds_phy_initial_state_enter,
2702 },
2703 [SCI_BASE_PHY_STATE_STOPPED] = {
2704 .enter_state = scic_sds_phy_stopped_state_enter,
2705 },
2706 [SCI_BASE_PHY_STATE_STARTING] = {
2707 .enter_state = scic_sds_phy_starting_state_enter,
2708 },
2709 [SCI_BASE_PHY_STATE_READY] = {
2710 .enter_state = scic_sds_phy_ready_state_enter,
2711 .exit_state = scic_sds_phy_ready_state_exit,
2712 },
2713 [SCI_BASE_PHY_STATE_RESETTING] = {
2714 .enter_state = scic_sds_phy_resetting_state_enter,
2715 },
2716 [SCI_BASE_PHY_STATE_FINAL] = {
2717 .enter_state = scic_sds_phy_final_state_enter,
2718 },
2719};
2720
This page took 0.133701 seconds and 5 git commands to generate.