isci: convert phy sata_timeout_timer to sci_timer
[deliverable/linux.git] / drivers / scsi / isci / phy.c
CommitLineData
6f231dda
DW
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "isci.h"
ce2b3261 57#include "host.h"
6f231dda 58#include "phy.h"
d35bc1bd 59#include "scu_event_codes.h"
d35bc1bd 60#include "timers.h"
e2f8db50 61#include "probe_roms.h"
6f231dda 62
d35bc1bd
DW
63/* Maximum arbitration wait time in micro-seconds */
64#define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
65
66enum sas_linkrate sci_phy_linkrate(struct scic_sds_phy *sci_phy)
67{
68 return sci_phy->max_negotiated_speed;
69}
70
71/*
72 * *****************************************************************************
73 * * SCIC SDS PHY Internal Methods
74 * ***************************************************************************** */
75
76/**
77 * This method will initialize the phy transport layer registers
78 * @sci_phy:
79 * @transport_layer_registers
80 *
81 * enum sci_status
82 */
83static enum sci_status scic_sds_phy_transport_layer_initialization(
84 struct scic_sds_phy *sci_phy,
85 struct scu_transport_layer_registers __iomem *transport_layer_registers)
86{
87 u32 tl_control;
88
89 sci_phy->transport_layer_registers = transport_layer_registers;
90
91 writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX,
92 &sci_phy->transport_layer_registers->stp_rni);
93
94 /*
95 * Hardware team recommends that we enable the STP prefetch for all
96 * transports
97 */
98 tl_control = readl(&sci_phy->transport_layer_registers->control);
99 tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
100 writel(tl_control, &sci_phy->transport_layer_registers->control);
101
102 return SCI_SUCCESS;
103}
104
105/**
106 * This method will initialize the phy link layer registers
107 * @sci_phy:
108 * @link_layer_registers:
109 *
110 * enum sci_status
111 */
112static enum sci_status
113scic_sds_phy_link_layer_initialization(struct scic_sds_phy *sci_phy,
114 struct scu_link_layer_registers __iomem *link_layer_registers)
115{
116 struct scic_sds_controller *scic =
117 sci_phy->owning_port->owning_controller;
118 int phy_idx = sci_phy->phy_index;
119 struct sci_phy_user_params *phy_user =
120 &scic->user_parameters.sds1.phys[phy_idx];
121 struct sci_phy_oem_params *phy_oem =
122 &scic->oem_parameters.sds1.phys[phy_idx];
123 u32 phy_configuration;
124 struct scic_phy_cap phy_cap;
125 u32 parity_check = 0;
126 u32 parity_count = 0;
127 u32 llctl, link_rate;
128 u32 clksm_value = 0;
129
130 sci_phy->link_layer_registers = link_layer_registers;
131
132 /* Set our IDENTIFY frame data */
133 #define SCI_END_DEVICE 0x01
134
135 writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) |
136 SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) |
137 SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
138 SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
139 SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE),
140 &sci_phy->link_layer_registers->transmit_identification);
141
142 /* Write the device SAS Address */
143 writel(0xFEDCBA98,
144 &sci_phy->link_layer_registers->sas_device_name_high);
145 writel(phy_idx, &sci_phy->link_layer_registers->sas_device_name_low);
146
147 /* Write the source SAS Address */
148 writel(phy_oem->sas_address.high,
149 &sci_phy->link_layer_registers->source_sas_address_high);
150 writel(phy_oem->sas_address.low,
151 &sci_phy->link_layer_registers->source_sas_address_low);
152
153 /* Clear and Set the PHY Identifier */
154 writel(0, &sci_phy->link_layer_registers->identify_frame_phy_id);
155 writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx),
156 &sci_phy->link_layer_registers->identify_frame_phy_id);
157
158 /* Change the initial state of the phy configuration register */
159 phy_configuration =
160 readl(&sci_phy->link_layer_registers->phy_configuration);
161
162 /* Hold OOB state machine in reset */
163 phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
164 writel(phy_configuration,
165 &sci_phy->link_layer_registers->phy_configuration);
166
167 /* Configure the SNW capabilities */
168 phy_cap.all = 0;
169 phy_cap.start = 1;
170 phy_cap.gen3_no_ssc = 1;
171 phy_cap.gen2_no_ssc = 1;
172 phy_cap.gen1_no_ssc = 1;
173 if (scic->oem_parameters.sds1.controller.do_enable_ssc == true) {
174 phy_cap.gen3_ssc = 1;
175 phy_cap.gen2_ssc = 1;
176 phy_cap.gen1_ssc = 1;
177 }
178
179 /*
180 * The SAS specification indicates that the phy_capabilities that
181 * are transmitted shall have an even parity. Calculate the parity. */
182 parity_check = phy_cap.all;
183 while (parity_check != 0) {
184 if (parity_check & 0x1)
185 parity_count++;
186 parity_check >>= 1;
187 }
188
189 /*
190 * If parity indicates there are an odd number of bits set, then
191 * set the parity bit to 1 in the phy capabilities. */
192 if ((parity_count % 2) != 0)
193 phy_cap.parity = 1;
194
195 writel(phy_cap.all, &sci_phy->link_layer_registers->phy_capabilities);
196
197 /* Set the enable spinup period but disable the ability to send
198 * notify enable spinup
199 */
200 writel(SCU_ENSPINUP_GEN_VAL(COUNT,
201 phy_user->notify_enable_spin_up_insertion_frequency),
202 &sci_phy->link_layer_registers->notify_enable_spinup_control);
203
204 /* Write the ALIGN Insertion Ferequency for connected phy and
205 * inpendent of connected state
206 */
207 clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
208 phy_user->in_connection_align_insertion_frequency);
209
210 clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
211 phy_user->align_insertion_frequency);
212
213 writel(clksm_value, &sci_phy->link_layer_registers->clock_skew_management);
214
215 /* @todo Provide a way to write this register correctly */
216 writel(0x02108421,
217 &sci_phy->link_layer_registers->afe_lookup_table_control);
218
219 llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
220 (u8)scic->user_parameters.sds1.no_outbound_task_timeout);
221
222 switch(phy_user->max_speed_generation) {
223 case SCIC_SDS_PARM_GEN3_SPEED:
224 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3;
225 break;
226 case SCIC_SDS_PARM_GEN2_SPEED:
227 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
228 break;
229 default:
230 link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
231 break;
232 }
233 llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
234 writel(llctl, &sci_phy->link_layer_registers->link_layer_control);
235
236 if (is_a0() || is_a2()) {
237 /* Program the max ARB time for the PHY to 700us so we inter-operate with
238 * the PMC expander which shuts down PHYs if the expander PHY generates too
239 * many breaks. This time value will guarantee that the initiator PHY will
240 * generate the break.
241 */
242 writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
243 &sci_phy->link_layer_registers->maximum_arbitration_wait_timer_timeout);
244 }
245
246 /*
247 * Set the link layer hang detection to 500ms (0x1F4) from its default
248 * value of 128ms. Max value is 511 ms.
249 */
250 writel(0x1F4, &sci_phy->link_layer_registers->link_layer_hang_detection_timeout);
251
252 /* We can exit the initial state to the stopped state */
253 sci_base_state_machine_change_state(&sci_phy->state_machine,
254 SCI_BASE_PHY_STATE_STOPPED);
255
256 return SCI_SUCCESS;
257}
258
a628d478 259static void phy_sata_timeout(unsigned long data)
d35bc1bd 260{
a628d478
EN
261 struct sci_timer *tmr = (struct sci_timer *)data;
262 struct scic_sds_phy *sci_phy = container_of(tmr, typeof(*sci_phy), sata_timer);
263 struct isci_host *ihost = scic_to_ihost(sci_phy->owning_port->owning_controller);
264 unsigned long flags;
265
266 spin_lock_irqsave(&ihost->scic_lock, flags);
267
268 if (tmr->cancel)
269 goto done;
d35bc1bd
DW
270
271 dev_dbg(sciphy_to_dev(sci_phy),
272 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
273 "timeout.\n",
274 __func__,
275 sci_phy);
276
d35bc1bd
DW
277 sci_base_state_machine_change_state(&sci_phy->state_machine,
278 SCI_BASE_PHY_STATE_STARTING);
a628d478
EN
279done:
280 spin_unlock_irqrestore(&ihost->scic_lock, flags);
d35bc1bd
DW
281}
282
283/**
284 * This method returns the port currently containing this phy. If the phy is
285 * currently contained by the dummy port, then the phy is considered to not
286 * be part of a port.
287 * @sci_phy: This parameter specifies the phy for which to retrieve the
288 * containing port.
289 *
290 * This method returns a handle to a port that contains the supplied phy.
291 * NULL This value is returned if the phy is not part of a real
292 * port (i.e. it's contained in the dummy port). !NULL All other
293 * values indicate a handle/pointer to the port containing the phy.
294 */
4f20ef4f 295struct scic_sds_port *phy_get_non_dummy_port(
d35bc1bd
DW
296 struct scic_sds_phy *sci_phy)
297{
298 if (scic_sds_port_get_index(sci_phy->owning_port) == SCIC_SDS_DUMMY_PORT)
299 return NULL;
300
301 return sci_phy->owning_port;
302}
303
304/**
305 * This method will assign a port to the phy object.
306 * @out]: sci_phy This parameter specifies the phy for which to assign a port
307 * object.
308 *
309 *
310 */
311void scic_sds_phy_set_port(
312 struct scic_sds_phy *sci_phy,
313 struct scic_sds_port *sci_port)
314{
315 sci_phy->owning_port = sci_port;
316
317 if (sci_phy->bcn_received_while_port_unassigned) {
318 sci_phy->bcn_received_while_port_unassigned = false;
319 scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy);
320 }
321}
322
323/**
324 * This method will initialize the constructed phy
325 * @sci_phy:
326 * @link_layer_registers:
327 *
328 * enum sci_status
329 */
330enum sci_status scic_sds_phy_initialize(
331 struct scic_sds_phy *sci_phy,
332 struct scu_transport_layer_registers __iomem *transport_layer_registers,
333 struct scu_link_layer_registers __iomem *link_layer_registers)
334{
d35bc1bd
DW
335 /* Perfrom the initialization of the TL hardware */
336 scic_sds_phy_transport_layer_initialization(
337 sci_phy,
338 transport_layer_registers);
339
340 /* Perofrm the initialization of the PE hardware */
341 scic_sds_phy_link_layer_initialization(sci_phy, link_layer_registers);
342
343 /*
344 * There is nothing that needs to be done in this state just
345 * transition to the stopped state. */
346 sci_base_state_machine_change_state(&sci_phy->state_machine,
347 SCI_BASE_PHY_STATE_STOPPED);
348
349 return SCI_SUCCESS;
350}
351
352/**
353 * This method assigns the direct attached device ID for this phy.
354 *
355 * @sci_phy The phy for which the direct attached device id is to
356 * be assigned.
357 * @device_id The direct attached device ID to assign to the phy.
358 * This will either be the RNi for the device or an invalid RNi if there
359 * is no current device assigned to the phy.
360 */
361void scic_sds_phy_setup_transport(
362 struct scic_sds_phy *sci_phy,
363 u32 device_id)
364{
365 u32 tl_control;
366
367 writel(device_id, &sci_phy->transport_layer_registers->stp_rni);
368
369 /*
370 * The read should guarantee that the first write gets posted
371 * before the next write
372 */
373 tl_control = readl(&sci_phy->transport_layer_registers->control);
374 tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
375 writel(tl_control, &sci_phy->transport_layer_registers->control);
376}
377
378/**
379 *
380 * @sci_phy: The phy object to be suspended.
381 *
382 * This function will perform the register reads/writes to suspend the SCU
383 * hardware protocol engine. none
384 */
385static void scic_sds_phy_suspend(
386 struct scic_sds_phy *sci_phy)
387{
388 u32 scu_sas_pcfg_value;
389
390 scu_sas_pcfg_value =
391 readl(&sci_phy->link_layer_registers->phy_configuration);
392 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
393 writel(scu_sas_pcfg_value,
394 &sci_phy->link_layer_registers->phy_configuration);
395
396 scic_sds_phy_setup_transport(
397 sci_phy,
398 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
399}
400
401void scic_sds_phy_resume(struct scic_sds_phy *sci_phy)
402{
403 u32 scu_sas_pcfg_value;
404
405 scu_sas_pcfg_value =
406 readl(&sci_phy->link_layer_registers->phy_configuration);
407 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
408 writel(scu_sas_pcfg_value,
409 &sci_phy->link_layer_registers->phy_configuration);
410}
411
412void scic_sds_phy_get_sas_address(struct scic_sds_phy *sci_phy,
413 struct sci_sas_address *sas_address)
414{
415 sas_address->high = readl(&sci_phy->link_layer_registers->source_sas_address_high);
416 sas_address->low = readl(&sci_phy->link_layer_registers->source_sas_address_low);
417}
418
419void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy *sci_phy,
420 struct sci_sas_address *sas_address)
421{
422 struct sas_identify_frame *iaf;
423 struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
424
425 iaf = &iphy->frame_rcvd.iaf;
426 memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE);
427}
428
429void scic_sds_phy_get_protocols(struct scic_sds_phy *sci_phy,
430 struct scic_phy_proto *protocols)
431{
432 protocols->all =
433 (u16)(readl(&sci_phy->
434 link_layer_registers->transmit_identification) &
435 0x0000FFFF);
436}
437
d35bc1bd
DW
438enum sci_status scic_sds_phy_start(struct scic_sds_phy *sci_phy)
439{
966699b5 440 enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id;
966699b5
DW
441
442 if (state != SCI_BASE_PHY_STATE_STOPPED) {
443 dev_dbg(sciphy_to_dev(sci_phy),
444 "%s: in wrong state: %d\n", __func__, state);
445 return SCI_FAILURE_INVALID_STATE;
446 }
447
a628d478
EN
448 sci_base_state_machine_change_state(&sci_phy->state_machine,
449 SCI_BASE_PHY_STATE_STARTING);
966699b5 450 return SCI_SUCCESS;
d35bc1bd
DW
451}
452
d35bc1bd
DW
453enum sci_status scic_sds_phy_stop(struct scic_sds_phy *sci_phy)
454{
93153236
DW
455 enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id;
456
457 switch (state) {
458 case SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL:
459 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN:
460 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN:
461 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER:
462 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER:
463 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN:
464 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN:
465 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF:
466 case SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL:
467 case SCI_BASE_PHY_STATE_READY:
468 break;
469 default:
470 dev_dbg(sciphy_to_dev(sci_phy),
471 "%s: in wrong state: %d\n", __func__, state);
472 return SCI_FAILURE_INVALID_STATE;
473 }
474
475 sci_base_state_machine_change_state(&sci_phy->state_machine,
476 SCI_BASE_PHY_STATE_STOPPED);
477 return SCI_SUCCESS;
d35bc1bd
DW
478}
479
0cf36fa9 480enum sci_status scic_sds_phy_reset(struct scic_sds_phy *sci_phy)
d35bc1bd 481{
0cf36fa9
DW
482 enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id;
483
484 if (state != SCI_BASE_PHY_STATE_READY) {
485 dev_dbg(sciphy_to_dev(sci_phy),
486 "%s: in wrong state: %d\n", __func__, state);
487 return SCI_FAILURE_INVALID_STATE;
488 }
489
490 sci_base_state_machine_change_state(&sci_phy->state_machine,
491 SCI_BASE_PHY_STATE_RESETTING);
492 return SCI_SUCCESS;
d35bc1bd
DW
493}
494
5b1d4af2 495enum sci_status scic_sds_phy_consume_power_handler(struct scic_sds_phy *sci_phy)
d35bc1bd 496{
5b1d4af2
DW
497 enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id;
498
499 switch (state) {
500 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER: {
501 u32 enable_spinup;
502
503 enable_spinup = readl(&sci_phy->link_layer_registers->notify_enable_spinup_control);
504 enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
505 writel(enable_spinup, &sci_phy->link_layer_registers->notify_enable_spinup_control);
506
507 /* Change state to the final state this substate machine has run to completion */
508 sci_base_state_machine_change_state(&sci_phy->state_machine,
509 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL);
510
511 return SCI_SUCCESS;
512 }
513 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER: {
514 u32 scu_sas_pcfg_value;
515
516 /* Release the spinup hold state and reset the OOB state machine */
517 scu_sas_pcfg_value =
518 readl(&sci_phy->link_layer_registers->phy_configuration);
519 scu_sas_pcfg_value &=
520 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
521 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
522 writel(scu_sas_pcfg_value,
523 &sci_phy->link_layer_registers->phy_configuration);
524
525 /* Now restart the OOB operation */
526 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
527 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
528 writel(scu_sas_pcfg_value,
529 &sci_phy->link_layer_registers->phy_configuration);
530
531 /* Change state to the final state this substate machine has run to completion */
532 sci_base_state_machine_change_state(&sci_phy->state_machine,
533 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN);
534
535 return SCI_SUCCESS;
536 }
537 default:
538 dev_dbg(sciphy_to_dev(sci_phy),
539 "%s: in wrong state: %d\n", __func__, state);
540 return SCI_FAILURE_INVALID_STATE;
541 }
d35bc1bd
DW
542}
543
544/*
545 * *****************************************************************************
546 * * SCIC SDS PHY HELPER FUNCTIONS
547 * ***************************************************************************** */
548
549
550/**
551 *
552 * @sci_phy: The phy object that received SAS PHY DETECTED.
553 *
554 * This method continues the link training for the phy as if it were a SAS PHY
555 * instead of a SATA PHY. This is done because the completion queue had a SAS
556 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
557 * none
558 */
559static void scic_sds_phy_start_sas_link_training(
560 struct scic_sds_phy *sci_phy)
561{
562 u32 phy_control;
563
564 phy_control =
565 readl(&sci_phy->link_layer_registers->phy_configuration);
566 phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
567 writel(phy_control,
568 &sci_phy->link_layer_registers->phy_configuration);
569
570 sci_base_state_machine_change_state(
4a33c525 571 &sci_phy->state_machine,
d35bc1bd
DW
572 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
573 );
574
575 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
576}
577
578/**
579 *
580 * @sci_phy: The phy object that received a SATA SPINUP HOLD event
581 *
582 * This method continues the link training for the phy as if it were a SATA PHY
583 * instead of a SAS PHY. This is done because the completion queue had a SATA
584 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
585 */
586static void scic_sds_phy_start_sata_link_training(
587 struct scic_sds_phy *sci_phy)
588{
589 sci_base_state_machine_change_state(
4a33c525 590 &sci_phy->state_machine,
d35bc1bd
DW
591 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
592 );
593
594 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
595}
596
597/**
598 * scic_sds_phy_complete_link_training - perform processing common to
599 * all protocols upon completion of link training.
600 * @sci_phy: This parameter specifies the phy object for which link training
601 * has completed.
602 * @max_link_rate: This parameter specifies the maximum link rate to be
603 * associated with this phy.
604 * @next_state: This parameter specifies the next state for the phy's starting
605 * sub-state machine.
606 *
607 */
608static void scic_sds_phy_complete_link_training(
609 struct scic_sds_phy *sci_phy,
610 enum sas_linkrate max_link_rate,
611 u32 next_state)
612{
613 sci_phy->max_negotiated_speed = max_link_rate;
614
4a33c525 615 sci_base_state_machine_change_state(&sci_phy->state_machine,
d35bc1bd
DW
616 next_state);
617}
618
23506a69
DW
619enum sci_status scic_sds_phy_event_handler(struct scic_sds_phy *sci_phy,
620 u32 event_code)
4a33c525 621{
23506a69 622 enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id;
4a33c525 623
23506a69
DW
624 switch (state) {
625 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN:
626 switch (scu_get_event_code(event_code)) {
627 case SCU_EVENT_SAS_PHY_DETECTED:
628 scic_sds_phy_start_sas_link_training(sci_phy);
629 sci_phy->is_in_link_training = true;
630 break;
631 case SCU_EVENT_SATA_SPINUP_HOLD:
632 scic_sds_phy_start_sata_link_training(sci_phy);
633 sci_phy->is_in_link_training = true;
634 break;
635 default:
636 dev_dbg(sciphy_to_dev(sci_phy),
637 "%s: PHY starting substate machine received "
638 "unexpected event_code %x\n",
639 __func__,
640 event_code);
641 return SCI_FAILURE;
642 }
643 return SCI_SUCCESS;
644 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN:
645 switch (scu_get_event_code(event_code)) {
646 case SCU_EVENT_SAS_PHY_DETECTED:
647 /*
648 * Why is this being reported again by the controller?
649 * We would re-enter this state so just stay here */
650 break;
651 case SCU_EVENT_SAS_15:
652 case SCU_EVENT_SAS_15_SSC:
653 scic_sds_phy_complete_link_training(
654 sci_phy,
655 SAS_LINK_RATE_1_5_GBPS,
656 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF);
657 break;
658 case SCU_EVENT_SAS_30:
659 case SCU_EVENT_SAS_30_SSC:
660 scic_sds_phy_complete_link_training(
661 sci_phy,
662 SAS_LINK_RATE_3_0_GBPS,
663 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF);
664 break;
665 case SCU_EVENT_SAS_60:
666 case SCU_EVENT_SAS_60_SSC:
667 scic_sds_phy_complete_link_training(
668 sci_phy,
669 SAS_LINK_RATE_6_0_GBPS,
670 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF);
671 break;
672 case SCU_EVENT_SATA_SPINUP_HOLD:
673 /*
674 * We were doing SAS PHY link training and received a SATA PHY event
675 * continue OOB/SN as if this were a SATA PHY */
676 scic_sds_phy_start_sata_link_training(sci_phy);
677 break;
678 case SCU_EVENT_LINK_FAILURE:
679 /* Link failure change state back to the starting state */
680 sci_base_state_machine_change_state(&sci_phy->state_machine,
681 SCI_BASE_PHY_STATE_STARTING);
682 break;
683 default:
684 dev_warn(sciphy_to_dev(sci_phy),
685 "%s: PHY starting substate machine received "
686 "unexpected event_code %x\n",
687 __func__, event_code);
688
689 return SCI_FAILURE;
690 break;
691 }
692 return SCI_SUCCESS;
693 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF:
694 switch (scu_get_event_code(event_code)) {
695 case SCU_EVENT_SAS_PHY_DETECTED:
696 /* Backup the state machine */
697 scic_sds_phy_start_sas_link_training(sci_phy);
698 break;
699 case SCU_EVENT_SATA_SPINUP_HOLD:
700 /* We were doing SAS PHY link training and received a
701 * SATA PHY event continue OOB/SN as if this were a
702 * SATA PHY
703 */
704 scic_sds_phy_start_sata_link_training(sci_phy);
705 break;
706 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
707 case SCU_EVENT_LINK_FAILURE:
708 case SCU_EVENT_HARD_RESET_RECEIVED:
709 /* Start the oob/sn state machine over again */
710 sci_base_state_machine_change_state(&sci_phy->state_machine,
711 SCI_BASE_PHY_STATE_STARTING);
712 break;
713 default:
714 dev_warn(sciphy_to_dev(sci_phy),
715 "%s: PHY starting substate machine received "
716 "unexpected event_code %x\n",
717 __func__, event_code);
718 return SCI_FAILURE;
719 }
720 return SCI_SUCCESS;
721 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER:
722 switch (scu_get_event_code(event_code)) {
723 case SCU_EVENT_LINK_FAILURE:
724 /* Link failure change state back to the starting state */
725 sci_base_state_machine_change_state(&sci_phy->state_machine,
726 SCI_BASE_PHY_STATE_STARTING);
727 break;
728 default:
729 dev_warn(sciphy_to_dev(sci_phy),
730 "%s: PHY starting substate machine received unexpected "
731 "event_code %x\n",
732 __func__,
733 event_code);
734 return SCI_FAILURE;
735 }
736 return SCI_SUCCESS;
737 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER:
738 switch (scu_get_event_code(event_code)) {
739 case SCU_EVENT_LINK_FAILURE:
740 /* Link failure change state back to the starting state */
741 sci_base_state_machine_change_state(&sci_phy->state_machine,
742 SCI_BASE_PHY_STATE_STARTING);
743 break;
744 case SCU_EVENT_SATA_SPINUP_HOLD:
745 /* These events are received every 10ms and are
746 * expected while in this state
747 */
748 break;
749
750 case SCU_EVENT_SAS_PHY_DETECTED:
751 /* There has been a change in the phy type before OOB/SN for the
752 * SATA finished start down the SAS link traning path.
753 */
754 scic_sds_phy_start_sas_link_training(sci_phy);
755 break;
756
757 default:
758 dev_warn(sciphy_to_dev(sci_phy),
759 "%s: PHY starting substate machine received "
760 "unexpected event_code %x\n",
761 __func__, event_code);
4a33c525 762
23506a69
DW
763 return SCI_FAILURE;
764 }
765 return SCI_SUCCESS;
766 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN:
767 switch (scu_get_event_code(event_code)) {
768 case SCU_EVENT_LINK_FAILURE:
769 /* Link failure change state back to the starting state */
770 sci_base_state_machine_change_state(&sci_phy->state_machine,
771 SCI_BASE_PHY_STATE_STARTING);
772 break;
773 case SCU_EVENT_SATA_SPINUP_HOLD:
774 /* These events might be received since we dont know how many may be in
775 * the completion queue while waiting for power
776 */
777 break;
778 case SCU_EVENT_SATA_PHY_DETECTED:
779 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
780
781 /* We have received the SATA PHY notification change state */
782 sci_base_state_machine_change_state(&sci_phy->state_machine,
783 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN);
784 break;
785 case SCU_EVENT_SAS_PHY_DETECTED:
786 /* There has been a change in the phy type before OOB/SN for the
787 * SATA finished start down the SAS link traning path.
788 */
789 scic_sds_phy_start_sas_link_training(sci_phy);
790 break;
791 default:
792 dev_warn(sciphy_to_dev(sci_phy),
793 "%s: PHY starting substate machine received "
794 "unexpected event_code %x\n",
795 __func__,
796 event_code);
4a33c525 797
23506a69
DW
798 return SCI_FAILURE;;
799 }
800 return SCI_SUCCESS;
801 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN:
802 switch (scu_get_event_code(event_code)) {
803 case SCU_EVENT_SATA_PHY_DETECTED:
804 /*
805 * The hardware reports multiple SATA PHY detected events
806 * ignore the extras */
807 break;
808 case SCU_EVENT_SATA_15:
809 case SCU_EVENT_SATA_15_SSC:
810 scic_sds_phy_complete_link_training(
811 sci_phy,
812 SAS_LINK_RATE_1_5_GBPS,
813 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF);
814 break;
815 case SCU_EVENT_SATA_30:
816 case SCU_EVENT_SATA_30_SSC:
817 scic_sds_phy_complete_link_training(
818 sci_phy,
819 SAS_LINK_RATE_3_0_GBPS,
820 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF);
821 break;
822 case SCU_EVENT_SATA_60:
823 case SCU_EVENT_SATA_60_SSC:
824 scic_sds_phy_complete_link_training(
825 sci_phy,
826 SAS_LINK_RATE_6_0_GBPS,
827 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF);
828 break;
829 case SCU_EVENT_LINK_FAILURE:
830 /* Link failure change state back to the starting state */
831 sci_base_state_machine_change_state(&sci_phy->state_machine,
832 SCI_BASE_PHY_STATE_STARTING);
833 break;
834 case SCU_EVENT_SAS_PHY_DETECTED:
835 /*
836 * There has been a change in the phy type before OOB/SN for the
837 * SATA finished start down the SAS link traning path. */
838 scic_sds_phy_start_sas_link_training(sci_phy);
839 break;
840 default:
841 dev_warn(sciphy_to_dev(sci_phy),
842 "%s: PHY starting substate machine received "
843 "unexpected event_code %x\n",
844 __func__, event_code);
4a33c525 845
23506a69
DW
846 return SCI_FAILURE;
847 }
848
849 return SCI_SUCCESS;
850 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF:
851 switch (scu_get_event_code(event_code)) {
852 case SCU_EVENT_SATA_PHY_DETECTED:
853 /* Backup the state machine */
854 sci_base_state_machine_change_state(&sci_phy->state_machine,
855 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN);
856 break;
4a33c525 857
23506a69
DW
858 case SCU_EVENT_LINK_FAILURE:
859 /* Link failure change state back to the starting state */
860 sci_base_state_machine_change_state(&sci_phy->state_machine,
861 SCI_BASE_PHY_STATE_STARTING);
862 break;
863
864 default:
865 dev_warn(sciphy_to_dev(sci_phy),
866 "%s: PHY starting substate machine received "
867 "unexpected event_code %x\n",
868 __func__,
869 event_code);
870
871 return SCI_FAILURE;
872 }
873 return SCI_SUCCESS;
874 case SCI_BASE_PHY_STATE_READY:
875 switch (scu_get_event_code(event_code)) {
876 case SCU_EVENT_LINK_FAILURE:
877 /* Link failure change state back to the starting state */
878 sci_base_state_machine_change_state(&sci_phy->state_machine,
879 SCI_BASE_PHY_STATE_STARTING);
880 break;
881 case SCU_EVENT_BROADCAST_CHANGE:
882 /* Broadcast change received. Notify the port. */
4f20ef4f 883 if (phy_get_non_dummy_port(sci_phy) != NULL)
23506a69
DW
884 scic_sds_port_broadcast_change_received(sci_phy->owning_port, sci_phy);
885 else
886 sci_phy->bcn_received_while_port_unassigned = true;
887 break;
888 default:
889 dev_warn(sciphy_to_dev(sci_phy),
890 "%sP SCIC PHY 0x%p ready state machine received "
891 "unexpected event_code %x\n",
892 __func__, sci_phy, event_code);
893 return SCI_FAILURE_INVALID_STATE;
894 }
895 return SCI_SUCCESS;
896 case SCI_BASE_PHY_STATE_RESETTING:
897 switch (scu_get_event_code(event_code)) {
898 case SCU_EVENT_HARD_RESET_TRANSMITTED:
899 /* Link failure change state back to the starting state */
900 sci_base_state_machine_change_state(&sci_phy->state_machine,
901 SCI_BASE_PHY_STATE_STARTING);
902 break;
903 default:
904 dev_warn(sciphy_to_dev(sci_phy),
905 "%s: SCIC PHY 0x%p resetting state machine received "
906 "unexpected event_code %x\n",
907 __func__, sci_phy, event_code);
908
909 return SCI_FAILURE_INVALID_STATE;
910 break;
911 }
912 return SCI_SUCCESS;
913 default:
914 dev_dbg(sciphy_to_dev(sci_phy),
915 "%s: in wrong state: %d\n", __func__, state);
916 return SCI_FAILURE_INVALID_STATE;
917 }
4a33c525
AG
918}
919
23506a69
DW
920enum sci_status scic_sds_phy_frame_handler(struct scic_sds_phy *sci_phy,
921 u32 frame_index)
4a33c525 922{
23506a69
DW
923 enum scic_sds_phy_states state = sci_phy->state_machine.current_state_id;
924 struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
925 enum sci_status result;
4a33c525 926
23506a69
DW
927 switch (state) {
928 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF: {
929 u32 *frame_words;
930 struct sas_identify_frame iaf;
931 struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
4a33c525 932
23506a69
DW
933 result = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control,
934 frame_index,
935 (void **)&frame_words);
4a33c525 936
23506a69
DW
937 if (result != SCI_SUCCESS)
938 return result;
939
940 sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
941 if (iaf.frame_type == 0) {
942 u32 state;
943
944 memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
945 if (iaf.smp_tport) {
946 /* We got the IAF for an expander PHY go to the final
947 * state since there are no power requirements for
948 * expander phys.
949 */
950 state = SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL;
951 } else {
952 /* We got the IAF we can now go to the await spinup
953 * semaphore state
954 */
955 state = SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER;
956 }
957 sci_base_state_machine_change_state(&sci_phy->state_machine,
958 state);
959 result = SCI_SUCCESS;
960 } else
961 dev_warn(sciphy_to_dev(sci_phy),
962 "%s: PHY starting substate machine received "
963 "unexpected frame id %x\n",
964 __func__, frame_index);
965
966 scic_sds_controller_release_frame(scic, frame_index);
967 return result;
4a33c525 968 }
23506a69
DW
969 case SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF: {
970 struct dev_to_host_fis *frame_header;
971 u32 *fis_frame_data;
972 struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
973
974 result = scic_sds_unsolicited_frame_control_get_header(
975 &(scic_sds_phy_get_controller(sci_phy)->uf_control),
976 frame_index,
977 (void **)&frame_header);
978
979 if (result != SCI_SUCCESS)
980 return result;
4a33c525 981
23506a69
DW
982 if ((frame_header->fis_type == FIS_REGD2H) &&
983 !(frame_header->status & ATA_BUSY)) {
984 scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control,
985 frame_index,
986 (void **)&fis_frame_data);
987
988 scic_sds_controller_copy_sata_response(&iphy->frame_rcvd.fis,
989 frame_header,
990 fis_frame_data);
991
992 /* got IAF we can now go to the await spinup semaphore state */
993 sci_base_state_machine_change_state(&sci_phy->state_machine,
994 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL);
995
996 result = SCI_SUCCESS;
997 } else
998 dev_warn(sciphy_to_dev(sci_phy),
999 "%s: PHY starting substate machine received "
1000 "unexpected frame id %x\n",
1001 __func__, frame_index);
1002
1003 /* Regardless of the result we are done with this frame with it */
1004 scic_sds_controller_release_frame(scic, frame_index);
1005
1006 return result;
1007 }
1008 default:
1009 dev_dbg(sciphy_to_dev(sci_phy),
1010 "%s: in wrong state: %d\n", __func__, state);
1011 return SCI_FAILURE_INVALID_STATE;
1012 }
1013
4a33c525
AG
1014}
1015
9269e0e8 1016static void scic_sds_phy_starting_initial_substate_enter(struct sci_base_state_machine *sm)
d35bc1bd 1017{
9269e0e8 1018 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1019
d35bc1bd 1020 /* This is just an temporary state go off to the starting state */
4a33c525 1021 sci_base_state_machine_change_state(&sci_phy->state_machine,
d35bc1bd
DW
1022 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN);
1023}
1024
9269e0e8 1025static void scic_sds_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
d35bc1bd 1026{
9269e0e8 1027 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
5b1d4af2 1028 struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
d35bc1bd 1029
5b1d4af2 1030 scic_sds_controller_power_control_queue_insert(scic, sci_phy);
d35bc1bd
DW
1031}
1032
9269e0e8 1033static void scic_sds_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
d35bc1bd 1034{
9269e0e8 1035 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
5b1d4af2 1036 struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
d35bc1bd 1037
5b1d4af2 1038 scic_sds_controller_power_control_queue_remove(scic, sci_phy);
d35bc1bd
DW
1039}
1040
9269e0e8 1041static void scic_sds_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
d35bc1bd 1042{
9269e0e8 1043 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
5b1d4af2 1044 struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
d35bc1bd 1045
5b1d4af2 1046 scic_sds_controller_power_control_queue_insert(scic, sci_phy);
d35bc1bd
DW
1047}
1048
9269e0e8 1049static void scic_sds_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
d35bc1bd 1050{
9269e0e8 1051 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
5b1d4af2 1052 struct scic_sds_controller *scic = sci_phy->owning_port->owning_controller;
d35bc1bd 1053
5b1d4af2 1054 scic_sds_controller_power_control_queue_remove(scic, sci_phy);
d35bc1bd
DW
1055}
1056
9269e0e8 1057static void scic_sds_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
d35bc1bd 1058{
9269e0e8 1059 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1060
a628d478 1061 sci_mod_timer(&sci_phy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
d35bc1bd
DW
1062}
1063
9269e0e8 1064static void scic_sds_phy_starting_await_sata_phy_substate_exit(struct sci_base_state_machine *sm)
d35bc1bd 1065{
9269e0e8 1066 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1067
a628d478 1068 sci_del_timer(&sci_phy->sata_timer);
d35bc1bd
DW
1069}
1070
9269e0e8 1071static void scic_sds_phy_starting_await_sata_speed_substate_enter(struct sci_base_state_machine *sm)
d35bc1bd 1072{
9269e0e8 1073 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1074
a628d478 1075 sci_mod_timer(&sci_phy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
d35bc1bd
DW
1076}
1077
9269e0e8 1078static void scic_sds_phy_starting_await_sata_speed_substate_exit(struct sci_base_state_machine *sm)
d35bc1bd 1079{
9269e0e8 1080 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1081
a628d478 1082 sci_del_timer(&sci_phy->sata_timer);
d35bc1bd
DW
1083}
1084
9269e0e8 1085static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(struct sci_base_state_machine *sm)
d35bc1bd 1086{
9269e0e8 1087 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1088
5b1d4af2 1089 if (scic_sds_port_link_detected(sci_phy->owning_port, sci_phy)) {
d35bc1bd 1090
d35bc1bd
DW
1091 /*
1092 * Clear the PE suspend condition so we can actually
1093 * receive SIG FIS
1094 * The hardware will not respond to the XRDY until the PE
1095 * suspend condition is cleared.
1096 */
1097 scic_sds_phy_resume(sci_phy);
1098
a628d478
EN
1099 sci_mod_timer(&sci_phy->sata_timer,
1100 SCIC_SDS_SIGNATURE_FIS_TIMEOUT);
d35bc1bd
DW
1101 } else
1102 sci_phy->is_in_link_training = false;
1103}
1104
9269e0e8 1105static void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(struct sci_base_state_machine *sm)
d35bc1bd 1106{
9269e0e8 1107 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1108
a628d478 1109 sci_del_timer(&sci_phy->sata_timer);
d35bc1bd
DW
1110}
1111
9269e0e8 1112static void scic_sds_phy_starting_final_substate_enter(struct sci_base_state_machine *sm)
d35bc1bd 1113{
9269e0e8 1114 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1115
d35bc1bd
DW
1116 /* State machine has run to completion so exit out and change
1117 * the base state machine to the ready state
1118 */
1119 sci_base_state_machine_change_state(&sci_phy->state_machine,
1120 SCI_BASE_PHY_STATE_READY);
1121}
1122
d35bc1bd
DW
1123/**
1124 *
1125 * @sci_phy: This is the struct scic_sds_phy object to stop.
1126 *
1127 * This method will stop the struct scic_sds_phy object. This does not reset the
1128 * protocol engine it just suspends it and places it in a state where it will
1129 * not cause the end device to power up. none
1130 */
1131static void scu_link_layer_stop_protocol_engine(
1132 struct scic_sds_phy *sci_phy)
1133{
1134 u32 scu_sas_pcfg_value;
1135 u32 enable_spinup_value;
1136
1137 /* Suspend the protocol engine and place it in a sata spinup hold state */
1138 scu_sas_pcfg_value =
1139 readl(&sci_phy->link_layer_registers->phy_configuration);
1140 scu_sas_pcfg_value |=
1141 (SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
1142 SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE) |
1143 SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD));
1144 writel(scu_sas_pcfg_value,
1145 &sci_phy->link_layer_registers->phy_configuration);
1146
1147 /* Disable the notify enable spinup primitives */
1148 enable_spinup_value = readl(&sci_phy->link_layer_registers->notify_enable_spinup_control);
1149 enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
1150 writel(enable_spinup_value, &sci_phy->link_layer_registers->notify_enable_spinup_control);
1151}
1152
1153/**
1154 *
1155 *
1156 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
1157 */
1158static void scu_link_layer_start_oob(
1159 struct scic_sds_phy *sci_phy)
1160{
1161 u32 scu_sas_pcfg_value;
1162
1163 scu_sas_pcfg_value =
1164 readl(&sci_phy->link_layer_registers->phy_configuration);
1165 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
1166 scu_sas_pcfg_value &=
1167 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
1168 SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
1169 writel(scu_sas_pcfg_value,
1170 &sci_phy->link_layer_registers->phy_configuration);
1171}
1172
1173/**
1174 *
1175 *
1176 * This method will transmit a hard reset request on the specified phy. The SCU
1177 * hardware requires that we reset the OOB state machine and set the hard reset
1178 * bit in the phy configuration register. We then must start OOB over with the
1179 * hard reset bit set.
1180 */
1181static void scu_link_layer_tx_hard_reset(
1182 struct scic_sds_phy *sci_phy)
1183{
1184 u32 phy_configuration_value;
1185
1186 /*
1187 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
1188 * to the starting state. */
1189 phy_configuration_value =
1190 readl(&sci_phy->link_layer_registers->phy_configuration);
1191 phy_configuration_value |=
1192 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) |
1193 SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
1194 writel(phy_configuration_value,
1195 &sci_phy->link_layer_registers->phy_configuration);
1196
1197 /* Now take the OOB state machine out of reset */
1198 phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
1199 phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1200 writel(phy_configuration_value,
1201 &sci_phy->link_layer_registers->phy_configuration);
1202}
1203
9269e0e8 1204static void scic_sds_phy_stopped_state_enter(struct sci_base_state_machine *sm)
d35bc1bd 1205{
9269e0e8 1206 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd
DW
1207
1208 /*
1209 * @todo We need to get to the controller to place this PE in a
1210 * reset state
1211 */
a628d478 1212 sci_del_timer(&sci_phy->sata_timer);
d35bc1bd
DW
1213
1214 scu_link_layer_stop_protocol_engine(sci_phy);
1215
5b1d4af2
DW
1216 if (sci_phy->state_machine.previous_state_id != SCI_BASE_PHY_STATE_INITIAL)
1217 scic_sds_controller_link_down(scic_sds_phy_get_controller(sci_phy),
4f20ef4f 1218 phy_get_non_dummy_port(sci_phy),
5b1d4af2 1219 sci_phy);
d35bc1bd
DW
1220}
1221
9269e0e8 1222static void scic_sds_phy_starting_state_enter(struct sci_base_state_machine *sm)
d35bc1bd 1223{
9269e0e8 1224 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1225
d35bc1bd
DW
1226 scu_link_layer_stop_protocol_engine(sci_phy);
1227 scu_link_layer_start_oob(sci_phy);
1228
1229 /* We don't know what kind of phy we are going to be just yet */
1230 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
1231 sci_phy->bcn_received_while_port_unassigned = false;
1232
5b1d4af2
DW
1233 if (sci_phy->state_machine.previous_state_id == SCI_BASE_PHY_STATE_READY)
1234 scic_sds_controller_link_down(scic_sds_phy_get_controller(sci_phy),
4f20ef4f 1235 phy_get_non_dummy_port(sci_phy),
5b1d4af2 1236 sci_phy);
4a33c525
AG
1237
1238 sci_base_state_machine_change_state(&sci_phy->state_machine,
1239 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
d35bc1bd
DW
1240}
1241
9269e0e8 1242static void scic_sds_phy_ready_state_enter(struct sci_base_state_machine *sm)
d35bc1bd 1243{
9269e0e8 1244 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1245
5b1d4af2 1246 scic_sds_controller_link_up(scic_sds_phy_get_controller(sci_phy),
4f20ef4f 1247 phy_get_non_dummy_port(sci_phy),
5b1d4af2 1248 sci_phy);
d35bc1bd 1249
d35bc1bd
DW
1250}
1251
9269e0e8 1252static void scic_sds_phy_ready_state_exit(struct sci_base_state_machine *sm)
d35bc1bd 1253{
9269e0e8 1254 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd
DW
1255
1256 scic_sds_phy_suspend(sci_phy);
1257}
1258
9269e0e8 1259static void scic_sds_phy_resetting_state_enter(struct sci_base_state_machine *sm)
d35bc1bd 1260{
9269e0e8 1261 struct scic_sds_phy *sci_phy = container_of(sm, typeof(*sci_phy), state_machine);
d35bc1bd 1262
5b1d4af2
DW
1263 /* The phy is being reset, therefore deactivate it from the port. In
1264 * the resetting state we don't notify the user regarding link up and
1265 * link down notifications
1266 */
d35bc1bd
DW
1267 scic_sds_port_deactivate_phy(sci_phy->owning_port, sci_phy, false);
1268
1269 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
1270 scu_link_layer_tx_hard_reset(sci_phy);
1271 } else {
5b1d4af2 1272 /* The SCU does not need to have a discrete reset state so
d35bc1bd
DW
1273 * just go back to the starting state.
1274 */
5b1d4af2
DW
1275 sci_base_state_machine_change_state(&sci_phy->state_machine,
1276 SCI_BASE_PHY_STATE_STARTING);
d35bc1bd
DW
1277 }
1278}
1279
d35bc1bd 1280static const struct sci_base_state scic_sds_phy_state_table[] = {
5b1d4af2 1281 [SCI_BASE_PHY_STATE_INITIAL] = { },
d35bc1bd
DW
1282 [SCI_BASE_PHY_STATE_STOPPED] = {
1283 .enter_state = scic_sds_phy_stopped_state_enter,
1284 },
1285 [SCI_BASE_PHY_STATE_STARTING] = {
1286 .enter_state = scic_sds_phy_starting_state_enter,
1287 },
4a33c525
AG
1288 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
1289 .enter_state = scic_sds_phy_starting_initial_substate_enter,
1290 },
5b1d4af2
DW
1291 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = { },
1292 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = { },
1293 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = { },
4a33c525
AG
1294 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
1295 .enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
1296 .exit_state = scic_sds_phy_starting_await_sas_power_substate_exit,
1297 },
1298 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
1299 .enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
1300 .exit_state = scic_sds_phy_starting_await_sata_power_substate_exit
1301 },
1302 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
1303 .enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
1304 .exit_state = scic_sds_phy_starting_await_sata_phy_substate_exit
1305 },
1306 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
1307 .enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
1308 .exit_state = scic_sds_phy_starting_await_sata_speed_substate_exit
1309 },
1310 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
1311 .enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
1312 .exit_state = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
1313 },
1314 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
1315 .enter_state = scic_sds_phy_starting_final_substate_enter,
1316 },
d35bc1bd
DW
1317 [SCI_BASE_PHY_STATE_READY] = {
1318 .enter_state = scic_sds_phy_ready_state_enter,
1319 .exit_state = scic_sds_phy_ready_state_exit,
1320 },
1321 [SCI_BASE_PHY_STATE_RESETTING] = {
1322 .enter_state = scic_sds_phy_resetting_state_enter,
1323 },
5b1d4af2 1324 [SCI_BASE_PHY_STATE_FINAL] = { },
d35bc1bd
DW
1325};
1326
1327void scic_sds_phy_construct(struct scic_sds_phy *sci_phy,
1328 struct scic_sds_port *owning_port, u8 phy_index)
1329{
1330 sci_base_state_machine_construct(&sci_phy->state_machine,
d35bc1bd
DW
1331 scic_sds_phy_state_table,
1332 SCI_BASE_PHY_STATE_INITIAL);
1333
1334 sci_base_state_machine_start(&sci_phy->state_machine);
1335
1336 /* Copy the rest of the input data to our locals */
1337 sci_phy->owning_port = owning_port;
1338 sci_phy->phy_index = phy_index;
1339 sci_phy->bcn_received_while_port_unassigned = false;
1340 sci_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
1341 sci_phy->link_layer_registers = NULL;
1342 sci_phy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
a628d478
EN
1343
1344 /* Create the SIGNATURE FIS Timeout timer for this phy */
1345 sci_init_timer(&sci_phy->sata_timer, phy_sata_timeout);
d35bc1bd 1346}
6f231dda 1347
4b33981a 1348void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
6f231dda 1349{
150fc6fc 1350 union scic_oem_parameters oem;
4b33981a
DW
1351 u64 sci_sas_addr;
1352 __be64 sas_addr;
1353
1354 scic_oem_parameters_get(&ihost->sci, &oem);
1355 sci_sas_addr = oem.sds1.phys[index].sas_address.high;
1356 sci_sas_addr <<= 32;
1357 sci_sas_addr |= oem.sds1.phys[index].sas_address.low;
1358 sas_addr = cpu_to_be64(sci_sas_addr);
1359 memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));
1360
1361 iphy->isci_port = NULL;
1362 iphy->sas_phy.enabled = 0;
1363 iphy->sas_phy.id = index;
1364 iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
1365 iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd;
1366 iphy->sas_phy.ha = &ihost->sas_ha;
1367 iphy->sas_phy.lldd_phy = iphy;
1368 iphy->sas_phy.enabled = 1;
1369 iphy->sas_phy.class = SAS;
1370 iphy->sas_phy.iproto = SAS_PROTOCOL_ALL;
1371 iphy->sas_phy.tproto = 0;
1372 iphy->sas_phy.type = PHY_TYPE_PHYSICAL;
1373 iphy->sas_phy.role = PHY_ROLE_INITIATOR;
1374 iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
1375 iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
1376 memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd));
6f231dda
DW
1377}
1378
1379
1380/**
1381 * isci_phy_control() - This function is one of the SAS Domain Template
1382 * functions. This is a phy management function.
1383 * @phy: This parameter specifies the sphy being controlled.
1384 * @func: This parameter specifies the phy control function being invoked.
1385 * @buf: This parameter is specific to the phy function being invoked.
1386 *
1387 * status, zero indicates success.
1388 */
4d07f7f3
DJ
1389int isci_phy_control(struct asd_sas_phy *sas_phy,
1390 enum phy_func func,
1391 void *buf)
6f231dda 1392{
4d07f7f3
DJ
1393 int ret = 0;
1394 struct isci_phy *iphy = sas_phy->lldd_phy;
1395 struct isci_port *iport = iphy->isci_port;
1396 struct isci_host *ihost = sas_phy->ha->lldd_ha;
1397 unsigned long flags;
6f231dda 1398
4d07f7f3
DJ
1399 dev_dbg(&ihost->pdev->dev,
1400 "%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
1401 __func__, sas_phy, func, buf, iphy, iport);
6f231dda
DW
1402
1403 switch (func) {
4d07f7f3
DJ
1404 case PHY_FUNC_DISABLE:
1405 spin_lock_irqsave(&ihost->scic_lock, flags);
4b33981a 1406 scic_sds_phy_stop(&iphy->sci);
4d07f7f3
DJ
1407 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1408 break;
1409
6f231dda 1410 case PHY_FUNC_LINK_RESET:
4d07f7f3 1411 spin_lock_irqsave(&ihost->scic_lock, flags);
4b33981a
DW
1412 scic_sds_phy_stop(&iphy->sci);
1413 scic_sds_phy_start(&iphy->sci);
4d07f7f3
DJ
1414 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1415 break;
1416
1417 case PHY_FUNC_HARD_RESET:
1418 if (!iport)
1419 return -ENODEV;
6f231dda
DW
1420
1421 /* Perform the port reset. */
4393aa4e 1422 ret = isci_port_perform_hard_reset(ihost, iport, iphy);
6f231dda
DW
1423
1424 break;
1425
6f231dda 1426 default:
4d07f7f3
DJ
1427 dev_dbg(&ihost->pdev->dev,
1428 "%s: phy %p; func %d NOT IMPLEMENTED!\n",
1429 __func__, sas_phy, func);
1430 ret = -ENOSYS;
6f231dda
DW
1431 break;
1432 }
1433 return ret;
1434}
This page took 0.098702 seconds and 5 git commands to generate.