2
* This file is provided under a dual BSD/GPLv2 license. When using or
3
* redistributing this file, you may do so under either license.
7
* Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of version 2 of the GNU General Public License as
11
* published by the Free Software Foundation.
13
* This program is distributed in the hope that it will be useful, but
14
* WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21
* The full GNU General Public License is included in this distribution
22
* in the file called LICENSE.GPL.
26
* Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27
* All rights reserved.
29
* Redistribution and use in source and binary forms, with or without
30
* modification, are permitted provided that the following conditions
33
* * Redistributions of source code must retain the above copyright
34
* notice, this list of conditions and the following disclaimer.
35
* * Redistributions in binary form must reproduce the above copyright
36
* notice, this list of conditions and the following disclaimer in
37
* the documentation and/or other materials provided with the
39
* * Neither the name of Intel Corporation nor the names of its
40
* contributors may be used to endorse or promote products derived
41
* from this software without specific prior written permission.
43
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59
#include "scu_event_codes.h"
60
#include "probe_roms.h"
62
/* Maximum arbitration wait time in micro-seconds */
63
#define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
65
enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy)
67
return iphy->max_negotiated_speed;
70
static enum sci_status
71
sci_phy_transport_layer_initialization(struct isci_phy *iphy,
72
struct scu_transport_layer_registers __iomem *reg)
76
iphy->transport_layer_registers = reg;
78
writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX,
79
&iphy->transport_layer_registers->stp_rni);
82
* Hardware team recommends that we enable the STP prefetch for all
85
tl_control = readl(&iphy->transport_layer_registers->control);
86
tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
87
writel(tl_control, &iphy->transport_layer_registers->control);
92
static enum sci_status
93
sci_phy_link_layer_initialization(struct isci_phy *iphy,
94
struct scu_link_layer_registers __iomem *reg)
96
struct isci_host *ihost = iphy->owning_port->owning_controller;
97
int phy_idx = iphy->phy_index;
98
struct sci_phy_user_params *phy_user = &ihost->user_parameters.phys[phy_idx];
99
struct sci_phy_oem_params *phy_oem =
100
&ihost->oem_parameters.phys[phy_idx];
101
u32 phy_configuration;
102
struct sci_phy_cap phy_cap;
103
u32 parity_check = 0;
104
u32 parity_count = 0;
105
u32 llctl, link_rate;
109
iphy->link_layer_registers = reg;
111
/* Set our IDENTIFY frame data */
112
#define SCI_END_DEVICE 0x01
114
writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) |
115
SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) |
116
SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
117
SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
118
SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE),
119
&iphy->link_layer_registers->transmit_identification);
121
/* Write the device SAS Address */
123
&iphy->link_layer_registers->sas_device_name_high);
124
writel(phy_idx, &iphy->link_layer_registers->sas_device_name_low);
126
/* Write the source SAS Address */
127
writel(phy_oem->sas_address.high,
128
&iphy->link_layer_registers->source_sas_address_high);
129
writel(phy_oem->sas_address.low,
130
&iphy->link_layer_registers->source_sas_address_low);
132
/* Clear and Set the PHY Identifier */
133
writel(0, &iphy->link_layer_registers->identify_frame_phy_id);
134
writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx),
135
&iphy->link_layer_registers->identify_frame_phy_id);
137
/* Change the initial state of the phy configuration register */
139
readl(&iphy->link_layer_registers->phy_configuration);
141
/* Hold OOB state machine in reset */
142
phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
143
writel(phy_configuration,
144
&iphy->link_layer_registers->phy_configuration);
146
/* Configure the SNW capabilities */
149
phy_cap.gen3_no_ssc = 1;
150
phy_cap.gen2_no_ssc = 1;
151
phy_cap.gen1_no_ssc = 1;
152
if (ihost->oem_parameters.controller.do_enable_ssc == true) {
153
phy_cap.gen3_ssc = 1;
154
phy_cap.gen2_ssc = 1;
155
phy_cap.gen1_ssc = 1;
159
* The SAS specification indicates that the phy_capabilities that
160
* are transmitted shall have an even parity. Calculate the parity. */
161
parity_check = phy_cap.all;
162
while (parity_check != 0) {
163
if (parity_check & 0x1)
169
* If parity indicates there are an odd number of bits set, then
170
* set the parity bit to 1 in the phy capabilities. */
171
if ((parity_count % 2) != 0)
174
writel(phy_cap.all, &iphy->link_layer_registers->phy_capabilities);
176
/* Set the enable spinup period but disable the ability to send
177
* notify enable spinup
179
writel(SCU_ENSPINUP_GEN_VAL(COUNT,
180
phy_user->notify_enable_spin_up_insertion_frequency),
181
&iphy->link_layer_registers->notify_enable_spinup_control);
183
/* Write the ALIGN Insertion Ferequency for connected phy and
184
* inpendent of connected state
186
clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
187
phy_user->in_connection_align_insertion_frequency);
189
clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
190
phy_user->align_insertion_frequency);
192
writel(clksm_value, &iphy->link_layer_registers->clock_skew_management);
194
/* @todo Provide a way to write this register correctly */
196
&iphy->link_layer_registers->afe_lookup_table_control);
198
llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
199
(u8)ihost->user_parameters.no_outbound_task_timeout);
201
switch (phy_user->max_speed_generation) {
202
case SCIC_SDS_PARM_GEN3_SPEED:
203
link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3;
205
case SCIC_SDS_PARM_GEN2_SPEED:
206
link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
209
link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
212
llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
213
writel(llctl, &iphy->link_layer_registers->link_layer_control);
215
sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts);
217
/* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */
218
sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
220
/* Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can
221
* lock with 3Gb drive when SCU max rate is set to 1.5Gb.
223
sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
225
writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts);
227
if (is_a2(ihost->pdev)) {
228
/* Program the max ARB time for the PHY to 700us so we inter-operate with
229
* the PMC expander which shuts down PHYs if the expander PHY generates too
230
* many breaks. This time value will guarantee that the initiator PHY will
231
* generate the break.
233
writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
234
&iphy->link_layer_registers->maximum_arbitration_wait_timer_timeout);
237
/* Disable link layer hang detection, rely on the OS timeout for I/O timeouts. */
238
writel(0, &iphy->link_layer_registers->link_layer_hang_detection_timeout);
240
/* We can exit the initial state to the stopped state */
241
sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
246
static void phy_sata_timeout(unsigned long data)
248
struct sci_timer *tmr = (struct sci_timer *)data;
249
struct isci_phy *iphy = container_of(tmr, typeof(*iphy), sata_timer);
250
struct isci_host *ihost = iphy->owning_port->owning_controller;
253
spin_lock_irqsave(&ihost->scic_lock, flags);
258
dev_dbg(sciphy_to_dev(iphy),
259
"%s: SCIC SDS Phy 0x%p did not receive signature fis before "
264
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
266
spin_unlock_irqrestore(&ihost->scic_lock, flags);
270
* This method returns the port currently containing this phy. If the phy is
271
* currently contained by the dummy port, then the phy is considered to not
273
* @sci_phy: This parameter specifies the phy for which to retrieve the
276
* This method returns a handle to a port that contains the supplied phy.
277
* NULL This value is returned if the phy is not part of a real
278
* port (i.e. it's contained in the dummy port). !NULL All other
279
* values indicate a handle/pointer to the port containing the phy.
281
struct isci_port *phy_get_non_dummy_port(struct isci_phy *iphy)
283
struct isci_port *iport = iphy->owning_port;
285
if (iport->physical_port_index == SCIC_SDS_DUMMY_PORT)
288
return iphy->owning_port;
292
* This method will assign a port to the phy object.
293
* @out]: iphy This parameter specifies the phy for which to assign a port
298
void sci_phy_set_port(
299
struct isci_phy *iphy,
300
struct isci_port *iport)
302
iphy->owning_port = iport;
304
if (iphy->bcn_received_while_port_unassigned) {
305
iphy->bcn_received_while_port_unassigned = false;
306
sci_port_broadcast_change_received(iphy->owning_port, iphy);
310
enum sci_status sci_phy_initialize(struct isci_phy *iphy,
311
struct scu_transport_layer_registers __iomem *tl,
312
struct scu_link_layer_registers __iomem *ll)
314
/* Perfrom the initialization of the TL hardware */
315
sci_phy_transport_layer_initialization(iphy, tl);
317
/* Perofrm the initialization of the PE hardware */
318
sci_phy_link_layer_initialization(iphy, ll);
320
/* There is nothing that needs to be done in this state just
321
* transition to the stopped state
323
sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
329
* This method assigns the direct attached device ID for this phy.
331
* @iphy The phy for which the direct attached device id is to
333
* @device_id The direct attached device ID to assign to the phy.
334
* This will either be the RNi for the device or an invalid RNi if there
335
* is no current device assigned to the phy.
337
void sci_phy_setup_transport(struct isci_phy *iphy, u32 device_id)
341
writel(device_id, &iphy->transport_layer_registers->stp_rni);
344
* The read should guarantee that the first write gets posted
345
* before the next write
347
tl_control = readl(&iphy->transport_layer_registers->control);
348
tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
349
writel(tl_control, &iphy->transport_layer_registers->control);
352
static void sci_phy_suspend(struct isci_phy *iphy)
354
u32 scu_sas_pcfg_value;
357
readl(&iphy->link_layer_registers->phy_configuration);
358
scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
359
writel(scu_sas_pcfg_value,
360
&iphy->link_layer_registers->phy_configuration);
362
sci_phy_setup_transport(iphy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
365
void sci_phy_resume(struct isci_phy *iphy)
367
u32 scu_sas_pcfg_value;
370
readl(&iphy->link_layer_registers->phy_configuration);
371
scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
372
writel(scu_sas_pcfg_value,
373
&iphy->link_layer_registers->phy_configuration);
376
void sci_phy_get_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas)
378
sas->high = readl(&iphy->link_layer_registers->source_sas_address_high);
379
sas->low = readl(&iphy->link_layer_registers->source_sas_address_low);
382
void sci_phy_get_attached_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas)
384
struct sas_identify_frame *iaf;
386
iaf = &iphy->frame_rcvd.iaf;
387
memcpy(sas, iaf->sas_addr, SAS_ADDR_SIZE);
390
void sci_phy_get_protocols(struct isci_phy *iphy, struct sci_phy_proto *proto)
392
proto->all = readl(&iphy->link_layer_registers->transmit_identification);
395
enum sci_status sci_phy_start(struct isci_phy *iphy)
397
enum sci_phy_states state = iphy->sm.current_state_id;
399
if (state != SCI_PHY_STOPPED) {
400
dev_dbg(sciphy_to_dev(iphy),
401
"%s: in wrong state: %d\n", __func__, state);
402
return SCI_FAILURE_INVALID_STATE;
405
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
409
enum sci_status sci_phy_stop(struct isci_phy *iphy)
411
enum sci_phy_states state = iphy->sm.current_state_id;
414
case SCI_PHY_SUB_INITIAL:
415
case SCI_PHY_SUB_AWAIT_OSSP_EN:
416
case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
417
case SCI_PHY_SUB_AWAIT_SAS_POWER:
418
case SCI_PHY_SUB_AWAIT_SATA_POWER:
419
case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
420
case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
421
case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
422
case SCI_PHY_SUB_FINAL:
426
dev_dbg(sciphy_to_dev(iphy),
427
"%s: in wrong state: %d\n", __func__, state);
428
return SCI_FAILURE_INVALID_STATE;
431
sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
435
enum sci_status sci_phy_reset(struct isci_phy *iphy)
437
enum sci_phy_states state = iphy->sm.current_state_id;
439
if (state != SCI_PHY_READY) {
440
dev_dbg(sciphy_to_dev(iphy),
441
"%s: in wrong state: %d\n", __func__, state);
442
return SCI_FAILURE_INVALID_STATE;
445
sci_change_state(&iphy->sm, SCI_PHY_RESETTING);
449
enum sci_status sci_phy_consume_power_handler(struct isci_phy *iphy)
451
enum sci_phy_states state = iphy->sm.current_state_id;
454
case SCI_PHY_SUB_AWAIT_SAS_POWER: {
457
enable_spinup = readl(&iphy->link_layer_registers->notify_enable_spinup_control);
458
enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
459
writel(enable_spinup, &iphy->link_layer_registers->notify_enable_spinup_control);
461
/* Change state to the final state this substate machine has run to completion */
462
sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
466
case SCI_PHY_SUB_AWAIT_SATA_POWER: {
467
u32 scu_sas_pcfg_value;
469
/* Release the spinup hold state and reset the OOB state machine */
471
readl(&iphy->link_layer_registers->phy_configuration);
472
scu_sas_pcfg_value &=
473
~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
474
scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
475
writel(scu_sas_pcfg_value,
476
&iphy->link_layer_registers->phy_configuration);
478
/* Now restart the OOB operation */
479
scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
480
scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
481
writel(scu_sas_pcfg_value,
482
&iphy->link_layer_registers->phy_configuration);
484
/* Change state to the final state this substate machine has run to completion */
485
sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_PHY_EN);
490
dev_dbg(sciphy_to_dev(iphy),
491
"%s: in wrong state: %d\n", __func__, state);
492
return SCI_FAILURE_INVALID_STATE;
496
static void sci_phy_start_sas_link_training(struct isci_phy *iphy)
498
/* continue the link training for the phy as if it were a SAS PHY
499
* instead of a SATA PHY. This is done because the completion queue had a SAS
500
* PHY DETECTED event when the state machine was expecting a SATA PHY event.
504
phy_control = readl(&iphy->link_layer_registers->phy_configuration);
505
phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
507
&iphy->link_layer_registers->phy_configuration);
509
sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SAS_SPEED_EN);
511
iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
514
static void sci_phy_start_sata_link_training(struct isci_phy *iphy)
516
/* This method continues the link training for the phy as if it were a SATA PHY
517
* instead of a SAS PHY. This is done because the completion queue had a SATA
518
* SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
520
sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_POWER);
522
iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
526
* sci_phy_complete_link_training - perform processing common to
527
* all protocols upon completion of link training.
528
* @sci_phy: This parameter specifies the phy object for which link training
530
* @max_link_rate: This parameter specifies the maximum link rate to be
531
* associated with this phy.
532
* @next_state: This parameter specifies the next state for the phy's starting
536
static void sci_phy_complete_link_training(struct isci_phy *iphy,
537
enum sas_linkrate max_link_rate,
540
iphy->max_negotiated_speed = max_link_rate;
542
sci_change_state(&iphy->sm, next_state);
545
enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
547
enum sci_phy_states state = iphy->sm.current_state_id;
550
case SCI_PHY_SUB_AWAIT_OSSP_EN:
551
switch (scu_get_event_code(event_code)) {
552
case SCU_EVENT_SAS_PHY_DETECTED:
553
sci_phy_start_sas_link_training(iphy);
554
iphy->is_in_link_training = true;
556
case SCU_EVENT_SATA_SPINUP_HOLD:
557
sci_phy_start_sata_link_training(iphy);
558
iphy->is_in_link_training = true;
561
dev_dbg(sciphy_to_dev(iphy),
562
"%s: PHY starting substate machine received "
563
"unexpected event_code %x\n",
569
case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
570
switch (scu_get_event_code(event_code)) {
571
case SCU_EVENT_SAS_PHY_DETECTED:
573
* Why is this being reported again by the controller?
574
* We would re-enter this state so just stay here */
576
case SCU_EVENT_SAS_15:
577
case SCU_EVENT_SAS_15_SSC:
578
sci_phy_complete_link_training(iphy, SAS_LINK_RATE_1_5_GBPS,
579
SCI_PHY_SUB_AWAIT_IAF_UF);
581
case SCU_EVENT_SAS_30:
582
case SCU_EVENT_SAS_30_SSC:
583
sci_phy_complete_link_training(iphy, SAS_LINK_RATE_3_0_GBPS,
584
SCI_PHY_SUB_AWAIT_IAF_UF);
586
case SCU_EVENT_SAS_60:
587
case SCU_EVENT_SAS_60_SSC:
588
sci_phy_complete_link_training(iphy, SAS_LINK_RATE_6_0_GBPS,
589
SCI_PHY_SUB_AWAIT_IAF_UF);
591
case SCU_EVENT_SATA_SPINUP_HOLD:
593
* We were doing SAS PHY link training and received a SATA PHY event
594
* continue OOB/SN as if this were a SATA PHY */
595
sci_phy_start_sata_link_training(iphy);
597
case SCU_EVENT_LINK_FAILURE:
598
/* Link failure change state back to the starting state */
599
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
602
dev_warn(sciphy_to_dev(iphy),
603
"%s: PHY starting substate machine received "
604
"unexpected event_code %x\n",
605
__func__, event_code);
611
case SCI_PHY_SUB_AWAIT_IAF_UF:
612
switch (scu_get_event_code(event_code)) {
613
case SCU_EVENT_SAS_PHY_DETECTED:
614
/* Backup the state machine */
615
sci_phy_start_sas_link_training(iphy);
617
case SCU_EVENT_SATA_SPINUP_HOLD:
618
/* We were doing SAS PHY link training and received a
619
* SATA PHY event continue OOB/SN as if this were a
622
sci_phy_start_sata_link_training(iphy);
624
case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
625
case SCU_EVENT_LINK_FAILURE:
626
case SCU_EVENT_HARD_RESET_RECEIVED:
627
/* Start the oob/sn state machine over again */
628
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
631
dev_warn(sciphy_to_dev(iphy),
632
"%s: PHY starting substate machine received "
633
"unexpected event_code %x\n",
634
__func__, event_code);
638
case SCI_PHY_SUB_AWAIT_SAS_POWER:
639
switch (scu_get_event_code(event_code)) {
640
case SCU_EVENT_LINK_FAILURE:
641
/* Link failure change state back to the starting state */
642
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
645
dev_warn(sciphy_to_dev(iphy),
646
"%s: PHY starting substate machine received unexpected "
653
case SCI_PHY_SUB_AWAIT_SATA_POWER:
654
switch (scu_get_event_code(event_code)) {
655
case SCU_EVENT_LINK_FAILURE:
656
/* Link failure change state back to the starting state */
657
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
659
case SCU_EVENT_SATA_SPINUP_HOLD:
660
/* These events are received every 10ms and are
661
* expected while in this state
665
case SCU_EVENT_SAS_PHY_DETECTED:
666
/* There has been a change in the phy type before OOB/SN for the
667
* SATA finished start down the SAS link traning path.
669
sci_phy_start_sas_link_training(iphy);
673
dev_warn(sciphy_to_dev(iphy),
674
"%s: PHY starting substate machine received "
675
"unexpected event_code %x\n",
676
__func__, event_code);
681
case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
682
switch (scu_get_event_code(event_code)) {
683
case SCU_EVENT_LINK_FAILURE:
684
/* Link failure change state back to the starting state */
685
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
687
case SCU_EVENT_SATA_SPINUP_HOLD:
688
/* These events might be received since we dont know how many may be in
689
* the completion queue while waiting for power
692
case SCU_EVENT_SATA_PHY_DETECTED:
693
iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
695
/* We have received the SATA PHY notification change state */
696
sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
698
case SCU_EVENT_SAS_PHY_DETECTED:
699
/* There has been a change in the phy type before OOB/SN for the
700
* SATA finished start down the SAS link traning path.
702
sci_phy_start_sas_link_training(iphy);
705
dev_warn(sciphy_to_dev(iphy),
706
"%s: PHY starting substate machine received "
707
"unexpected event_code %x\n",
714
case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
715
switch (scu_get_event_code(event_code)) {
716
case SCU_EVENT_SATA_PHY_DETECTED:
718
* The hardware reports multiple SATA PHY detected events
719
* ignore the extras */
721
case SCU_EVENT_SATA_15:
722
case SCU_EVENT_SATA_15_SSC:
723
sci_phy_complete_link_training(iphy, SAS_LINK_RATE_1_5_GBPS,
724
SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
726
case SCU_EVENT_SATA_30:
727
case SCU_EVENT_SATA_30_SSC:
728
sci_phy_complete_link_training(iphy, SAS_LINK_RATE_3_0_GBPS,
729
SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
731
case SCU_EVENT_SATA_60:
732
case SCU_EVENT_SATA_60_SSC:
733
sci_phy_complete_link_training(iphy, SAS_LINK_RATE_6_0_GBPS,
734
SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
736
case SCU_EVENT_LINK_FAILURE:
737
/* Link failure change state back to the starting state */
738
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
740
case SCU_EVENT_SAS_PHY_DETECTED:
742
* There has been a change in the phy type before OOB/SN for the
743
* SATA finished start down the SAS link traning path. */
744
sci_phy_start_sas_link_training(iphy);
747
dev_warn(sciphy_to_dev(iphy),
748
"%s: PHY starting substate machine received "
749
"unexpected event_code %x\n",
750
__func__, event_code);
756
case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
757
switch (scu_get_event_code(event_code)) {
758
case SCU_EVENT_SATA_PHY_DETECTED:
759
/* Backup the state machine */
760
sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
763
case SCU_EVENT_LINK_FAILURE:
764
/* Link failure change state back to the starting state */
765
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
769
dev_warn(sciphy_to_dev(iphy),
770
"%s: PHY starting substate machine received "
771
"unexpected event_code %x\n",
779
switch (scu_get_event_code(event_code)) {
780
case SCU_EVENT_LINK_FAILURE:
781
/* Link failure change state back to the starting state */
782
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
784
case SCU_EVENT_BROADCAST_CHANGE:
785
/* Broadcast change received. Notify the port. */
786
if (phy_get_non_dummy_port(iphy) != NULL)
787
sci_port_broadcast_change_received(iphy->owning_port, iphy);
789
iphy->bcn_received_while_port_unassigned = true;
792
dev_warn(sciphy_to_dev(iphy),
793
"%sP SCIC PHY 0x%p ready state machine received "
794
"unexpected event_code %x\n",
795
__func__, iphy, event_code);
796
return SCI_FAILURE_INVALID_STATE;
799
case SCI_PHY_RESETTING:
800
switch (scu_get_event_code(event_code)) {
801
case SCU_EVENT_HARD_RESET_TRANSMITTED:
802
/* Link failure change state back to the starting state */
803
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
806
dev_warn(sciphy_to_dev(iphy),
807
"%s: SCIC PHY 0x%p resetting state machine received "
808
"unexpected event_code %x\n",
809
__func__, iphy, event_code);
811
return SCI_FAILURE_INVALID_STATE;
816
dev_dbg(sciphy_to_dev(iphy),
817
"%s: in wrong state: %d\n", __func__, state);
818
return SCI_FAILURE_INVALID_STATE;
822
enum sci_status sci_phy_frame_handler(struct isci_phy *iphy, u32 frame_index)
824
enum sci_phy_states state = iphy->sm.current_state_id;
825
struct isci_host *ihost = iphy->owning_port->owning_controller;
826
enum sci_status result;
830
case SCI_PHY_SUB_AWAIT_IAF_UF: {
832
struct sas_identify_frame iaf;
834
result = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
836
(void **)&frame_words);
838
if (result != SCI_SUCCESS)
841
sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
842
if (iaf.frame_type == 0) {
845
spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
846
memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
847
spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
849
/* We got the IAF for an expander PHY go to the final
850
* state since there are no power requirements for
853
state = SCI_PHY_SUB_FINAL;
855
/* We got the IAF we can now go to the await spinup
858
state = SCI_PHY_SUB_AWAIT_SAS_POWER;
860
sci_change_state(&iphy->sm, state);
861
result = SCI_SUCCESS;
863
dev_warn(sciphy_to_dev(iphy),
864
"%s: PHY starting substate machine received "
865
"unexpected frame id %x\n",
866
__func__, frame_index);
868
sci_controller_release_frame(ihost, frame_index);
871
case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: {
872
struct dev_to_host_fis *frame_header;
875
result = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
877
(void **)&frame_header);
879
if (result != SCI_SUCCESS)
882
if ((frame_header->fis_type == FIS_REGD2H) &&
883
!(frame_header->status & ATA_BUSY)) {
884
sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
886
(void **)&fis_frame_data);
888
spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
889
sci_controller_copy_sata_response(&iphy->frame_rcvd.fis,
892
spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
894
/* got IAF we can now go to the await spinup semaphore state */
895
sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
897
result = SCI_SUCCESS;
899
dev_warn(sciphy_to_dev(iphy),
900
"%s: PHY starting substate machine received "
901
"unexpected frame id %x\n",
902
__func__, frame_index);
904
/* Regardless of the result we are done with this frame with it */
905
sci_controller_release_frame(ihost, frame_index);
910
dev_dbg(sciphy_to_dev(iphy),
911
"%s: in wrong state: %d\n", __func__, state);
912
return SCI_FAILURE_INVALID_STATE;
917
static void sci_phy_starting_initial_substate_enter(struct sci_base_state_machine *sm)
919
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
921
/* This is just an temporary state go off to the starting state */
922
sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_OSSP_EN);
925
static void sci_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
927
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
928
struct isci_host *ihost = iphy->owning_port->owning_controller;
930
sci_controller_power_control_queue_insert(ihost, iphy);
933
static void sci_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
935
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
936
struct isci_host *ihost = iphy->owning_port->owning_controller;
938
sci_controller_power_control_queue_remove(ihost, iphy);
941
static void sci_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
943
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
944
struct isci_host *ihost = iphy->owning_port->owning_controller;
946
sci_controller_power_control_queue_insert(ihost, iphy);
949
static void sci_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
951
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
952
struct isci_host *ihost = iphy->owning_port->owning_controller;
954
sci_controller_power_control_queue_remove(ihost, iphy);
957
static void sci_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
959
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
961
sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
964
static void sci_phy_starting_await_sata_phy_substate_exit(struct sci_base_state_machine *sm)
966
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
968
sci_del_timer(&iphy->sata_timer);
971
static void sci_phy_starting_await_sata_speed_substate_enter(struct sci_base_state_machine *sm)
973
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
975
sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
978
static void sci_phy_starting_await_sata_speed_substate_exit(struct sci_base_state_machine *sm)
980
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
982
sci_del_timer(&iphy->sata_timer);
985
static void sci_phy_starting_await_sig_fis_uf_substate_enter(struct sci_base_state_machine *sm)
987
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
989
if (sci_port_link_detected(iphy->owning_port, iphy)) {
992
* Clear the PE suspend condition so we can actually
994
* The hardware will not respond to the XRDY until the PE
995
* suspend condition is cleared.
997
sci_phy_resume(iphy);
999
sci_mod_timer(&iphy->sata_timer,
1000
SCIC_SDS_SIGNATURE_FIS_TIMEOUT);
1002
iphy->is_in_link_training = false;
1005
static void sci_phy_starting_await_sig_fis_uf_substate_exit(struct sci_base_state_machine *sm)
1007
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
1009
sci_del_timer(&iphy->sata_timer);
1012
static void sci_phy_starting_final_substate_enter(struct sci_base_state_machine *sm)
1014
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
1016
/* State machine has run to completion so exit out and change
1017
* the base state machine to the ready state
1019
sci_change_state(&iphy->sm, SCI_PHY_READY);
1024
* @sci_phy: This is the struct isci_phy object to stop.
1026
* This method will stop the struct isci_phy object. This does not reset the
1027
* protocol engine it just suspends it and places it in a state where it will
1028
* not cause the end device to power up. none
1030
static void scu_link_layer_stop_protocol_engine(
1031
struct isci_phy *iphy)
1033
u32 scu_sas_pcfg_value;
1034
u32 enable_spinup_value;
1036
/* Suspend the protocol engine and place it in a sata spinup hold state */
1037
scu_sas_pcfg_value =
1038
readl(&iphy->link_layer_registers->phy_configuration);
1039
scu_sas_pcfg_value |=
1040
(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
1041
SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE) |
1042
SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD));
1043
writel(scu_sas_pcfg_value,
1044
&iphy->link_layer_registers->phy_configuration);
1046
/* Disable the notify enable spinup primitives */
1047
enable_spinup_value = readl(&iphy->link_layer_registers->notify_enable_spinup_control);
1048
enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
1049
writel(enable_spinup_value, &iphy->link_layer_registers->notify_enable_spinup_control);
1055
* This method will start the OOB/SN state machine for this struct isci_phy object.
1057
static void scu_link_layer_start_oob(
1058
struct isci_phy *iphy)
1060
u32 scu_sas_pcfg_value;
1062
scu_sas_pcfg_value =
1063
readl(&iphy->link_layer_registers->phy_configuration);
1064
scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
1065
scu_sas_pcfg_value &=
1066
~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
1067
SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
1068
writel(scu_sas_pcfg_value,
1069
&iphy->link_layer_registers->phy_configuration);
1075
* This method will transmit a hard reset request on the specified phy. The SCU
1076
* hardware requires that we reset the OOB state machine and set the hard reset
1077
* bit in the phy configuration register. We then must start OOB over with the
1078
* hard reset bit set.
1080
static void scu_link_layer_tx_hard_reset(
1081
struct isci_phy *iphy)
1083
u32 phy_configuration_value;
1086
* SAS Phys must wait for the HARD_RESET_TX event notification to transition
1087
* to the starting state. */
1088
phy_configuration_value =
1089
readl(&iphy->link_layer_registers->phy_configuration);
1090
phy_configuration_value |=
1091
(SCU_SAS_PCFG_GEN_BIT(HARD_RESET) |
1092
SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
1093
writel(phy_configuration_value,
1094
&iphy->link_layer_registers->phy_configuration);
1096
/* Now take the OOB state machine out of reset */
1097
phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
1098
phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1099
writel(phy_configuration_value,
1100
&iphy->link_layer_registers->phy_configuration);
1103
static void sci_phy_stopped_state_enter(struct sci_base_state_machine *sm)
1105
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
1106
struct isci_port *iport = iphy->owning_port;
1107
struct isci_host *ihost = iport->owning_controller;
1110
* @todo We need to get to the controller to place this PE in a
1113
sci_del_timer(&iphy->sata_timer);
1115
scu_link_layer_stop_protocol_engine(iphy);
1117
if (iphy->sm.previous_state_id != SCI_PHY_INITIAL)
1118
sci_controller_link_down(ihost, phy_get_non_dummy_port(iphy), iphy);
1121
static void sci_phy_starting_state_enter(struct sci_base_state_machine *sm)
1123
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
1124
struct isci_port *iport = iphy->owning_port;
1125
struct isci_host *ihost = iport->owning_controller;
1127
scu_link_layer_stop_protocol_engine(iphy);
1128
scu_link_layer_start_oob(iphy);
1130
/* We don't know what kind of phy we are going to be just yet */
1131
iphy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
1132
iphy->bcn_received_while_port_unassigned = false;
1134
if (iphy->sm.previous_state_id == SCI_PHY_READY)
1135
sci_controller_link_down(ihost, phy_get_non_dummy_port(iphy), iphy);
1137
sci_change_state(&iphy->sm, SCI_PHY_SUB_INITIAL);
1140
static void sci_phy_ready_state_enter(struct sci_base_state_machine *sm)
1142
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
1143
struct isci_port *iport = iphy->owning_port;
1144
struct isci_host *ihost = iport->owning_controller;
1146
sci_controller_link_up(ihost, phy_get_non_dummy_port(iphy), iphy);
1149
static void sci_phy_ready_state_exit(struct sci_base_state_machine *sm)
1151
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
1153
sci_phy_suspend(iphy);
1156
static void sci_phy_resetting_state_enter(struct sci_base_state_machine *sm)
1158
struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
1160
/* The phy is being reset, therefore deactivate it from the port. In
1161
* the resetting state we don't notify the user regarding link up and
1162
* link down notifications
1164
sci_port_deactivate_phy(iphy->owning_port, iphy, false);
1166
if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
1167
scu_link_layer_tx_hard_reset(iphy);
1169
/* The SCU does not need to have a discrete reset state so
1170
* just go back to the starting state.
1172
sci_change_state(&iphy->sm, SCI_PHY_STARTING);
1176
static const struct sci_base_state sci_phy_state_table[] = {
1177
[SCI_PHY_INITIAL] = { },
1178
[SCI_PHY_STOPPED] = {
1179
.enter_state = sci_phy_stopped_state_enter,
1181
[SCI_PHY_STARTING] = {
1182
.enter_state = sci_phy_starting_state_enter,
1184
[SCI_PHY_SUB_INITIAL] = {
1185
.enter_state = sci_phy_starting_initial_substate_enter,
1187
[SCI_PHY_SUB_AWAIT_OSSP_EN] = { },
1188
[SCI_PHY_SUB_AWAIT_SAS_SPEED_EN] = { },
1189
[SCI_PHY_SUB_AWAIT_IAF_UF] = { },
1190
[SCI_PHY_SUB_AWAIT_SAS_POWER] = {
1191
.enter_state = sci_phy_starting_await_sas_power_substate_enter,
1192
.exit_state = sci_phy_starting_await_sas_power_substate_exit,
1194
[SCI_PHY_SUB_AWAIT_SATA_POWER] = {
1195
.enter_state = sci_phy_starting_await_sata_power_substate_enter,
1196
.exit_state = sci_phy_starting_await_sata_power_substate_exit
1198
[SCI_PHY_SUB_AWAIT_SATA_PHY_EN] = {
1199
.enter_state = sci_phy_starting_await_sata_phy_substate_enter,
1200
.exit_state = sci_phy_starting_await_sata_phy_substate_exit
1202
[SCI_PHY_SUB_AWAIT_SATA_SPEED_EN] = {
1203
.enter_state = sci_phy_starting_await_sata_speed_substate_enter,
1204
.exit_state = sci_phy_starting_await_sata_speed_substate_exit
1206
[SCI_PHY_SUB_AWAIT_SIG_FIS_UF] = {
1207
.enter_state = sci_phy_starting_await_sig_fis_uf_substate_enter,
1208
.exit_state = sci_phy_starting_await_sig_fis_uf_substate_exit
1210
[SCI_PHY_SUB_FINAL] = {
1211
.enter_state = sci_phy_starting_final_substate_enter,
1214
.enter_state = sci_phy_ready_state_enter,
1215
.exit_state = sci_phy_ready_state_exit,
1217
[SCI_PHY_RESETTING] = {
1218
.enter_state = sci_phy_resetting_state_enter,
1220
[SCI_PHY_FINAL] = { },
1223
void sci_phy_construct(struct isci_phy *iphy,
1224
struct isci_port *iport, u8 phy_index)
1226
sci_init_sm(&iphy->sm, sci_phy_state_table, SCI_PHY_INITIAL);
1228
/* Copy the rest of the input data to our locals */
1229
iphy->owning_port = iport;
1230
iphy->phy_index = phy_index;
1231
iphy->bcn_received_while_port_unassigned = false;
1232
iphy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
1233
iphy->link_layer_registers = NULL;
1234
iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
1236
/* Create the SIGNATURE FIS Timeout timer for this phy */
1237
sci_init_timer(&iphy->sata_timer, phy_sata_timeout);
1240
void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
1242
struct sci_oem_params *oem = &ihost->oem_parameters;
1246
sci_sas_addr = oem->phys[index].sas_address.high;
1247
sci_sas_addr <<= 32;
1248
sci_sas_addr |= oem->phys[index].sas_address.low;
1249
sas_addr = cpu_to_be64(sci_sas_addr);
1250
memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));
1252
iphy->isci_port = NULL;
1253
iphy->sas_phy.enabled = 0;
1254
iphy->sas_phy.id = index;
1255
iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
1256
iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd;
1257
iphy->sas_phy.ha = &ihost->sas_ha;
1258
iphy->sas_phy.lldd_phy = iphy;
1259
iphy->sas_phy.enabled = 1;
1260
iphy->sas_phy.class = SAS;
1261
iphy->sas_phy.iproto = SAS_PROTOCOL_ALL;
1262
iphy->sas_phy.tproto = 0;
1263
iphy->sas_phy.type = PHY_TYPE_PHYSICAL;
1264
iphy->sas_phy.role = PHY_ROLE_INITIATOR;
1265
iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
1266
iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
1267
memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd));
1272
* isci_phy_control() - This function is one of the SAS Domain Template
1273
* functions. This is a phy management function.
1274
* @phy: This parameter specifies the sphy being controlled.
1275
* @func: This parameter specifies the phy control function being invoked.
1276
* @buf: This parameter is specific to the phy function being invoked.
1278
* status, zero indicates success.
1280
int isci_phy_control(struct asd_sas_phy *sas_phy,
1285
struct isci_phy *iphy = sas_phy->lldd_phy;
1286
struct isci_port *iport = iphy->isci_port;
1287
struct isci_host *ihost = sas_phy->ha->lldd_ha;
1288
unsigned long flags;
1290
dev_dbg(&ihost->pdev->dev,
1291
"%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
1292
__func__, sas_phy, func, buf, iphy, iport);
1295
case PHY_FUNC_DISABLE:
1296
spin_lock_irqsave(&ihost->scic_lock, flags);
1298
spin_unlock_irqrestore(&ihost->scic_lock, flags);
1301
case PHY_FUNC_LINK_RESET:
1302
spin_lock_irqsave(&ihost->scic_lock, flags);
1304
sci_phy_start(iphy);
1305
spin_unlock_irqrestore(&ihost->scic_lock, flags);
1308
case PHY_FUNC_HARD_RESET:
1312
/* Perform the port reset. */
1313
ret = isci_port_perform_hard_reset(ihost, iport, iphy);
1316
case PHY_FUNC_GET_EVENTS: {
1317
struct scu_link_layer_registers __iomem *r;
1318
struct sas_phy *phy = sas_phy->phy;
1320
r = iphy->link_layer_registers;
1321
phy->running_disparity_error_count = readl(&r->running_disparity_error_count);
1322
phy->loss_of_dword_sync_count = readl(&r->loss_of_sync_error_count);
1323
phy->phy_reset_problem_count = readl(&r->phy_reset_problem_count);
1324
phy->invalid_dword_count = readl(&r->invalid_dword_counter);
1329
dev_dbg(&ihost->pdev->dev,
1330
"%s: phy %p; func %d NOT IMPLEMENTED!\n",
1331
__func__, sas_phy, func);