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