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