~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/scsi/isci/phy.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 isci_phy *iphy)
 
66
{
 
67
        return iphy->max_negotiated_speed;
 
68
}
 
69
 
 
70
static enum sci_status
 
71
sci_phy_transport_layer_initialization(struct isci_phy *iphy,
 
72
                                       struct scu_transport_layer_registers __iomem *reg)
 
73
{
 
74
        u32 tl_control;
 
75
 
 
76
        iphy->transport_layer_registers = reg;
 
77
 
 
78
        writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX,
 
79
                &iphy->transport_layer_registers->stp_rni);
 
80
 
 
81
        /*
 
82
         * Hardware team recommends that we enable the STP prefetch for all
 
83
         * transports
 
84
         */
 
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);
 
88
 
 
89
        return SCI_SUCCESS;
 
90
}
 
91
 
 
92
static enum sci_status
 
93
sci_phy_link_layer_initialization(struct isci_phy *iphy,
 
94
                                  struct scu_link_layer_registers __iomem *reg)
 
95
{
 
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;
 
106
        u32 clksm_value = 0;
 
107
        u32 sp_timeouts = 0;
 
108
 
 
109
        iphy->link_layer_registers = reg;
 
110
 
 
111
        /* Set our IDENTIFY frame data */
 
112
        #define SCI_END_DEVICE 0x01
 
113
 
 
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);
 
120
 
 
121
        /* Write the device SAS Address */
 
122
        writel(0xFEDCBA98,
 
123
               &iphy->link_layer_registers->sas_device_name_high);
 
124
        writel(phy_idx, &iphy->link_layer_registers->sas_device_name_low);
 
125
 
 
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);
 
131
 
 
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);
 
136
 
 
137
        /* Change the initial state of the phy configuration register */
 
138
        phy_configuration =
 
139
                readl(&iphy->link_layer_registers->phy_configuration);
 
140
 
 
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);
 
145
 
 
146
        /* Configure the SNW capabilities */
 
147
        phy_cap.all = 0;
 
148
        phy_cap.start = 1;
 
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;
 
156
        }
 
157
 
 
158
        /*
 
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)
 
164
                        parity_count++;
 
165
                parity_check >>= 1;
 
166
        }
 
167
 
 
168
        /*
 
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)
 
172
                phy_cap.parity = 1;
 
173
 
 
174
        writel(phy_cap.all, &iphy->link_layer_registers->phy_capabilities);
 
175
 
 
176
        /* Set the enable spinup period but disable the ability to send
 
177
         * notify enable spinup
 
178
         */
 
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);
 
182
 
 
183
        /* Write the ALIGN Insertion Ferequency for connected phy and
 
184
         * inpendent of connected state
 
185
         */
 
186
        clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
 
187
                        phy_user->in_connection_align_insertion_frequency);
 
188
 
 
189
        clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
 
190
                        phy_user->align_insertion_frequency);
 
191
 
 
192
        writel(clksm_value, &iphy->link_layer_registers->clock_skew_management);
 
193
 
 
194
        /* @todo Provide a way to write this register correctly */
 
195
        writel(0x02108421,
 
196
                &iphy->link_layer_registers->afe_lookup_table_control);
 
197
 
 
198
        llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
 
199
                (u8)ihost->user_parameters.no_outbound_task_timeout);
 
200
 
 
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;
 
204
                break;
 
205
        case SCIC_SDS_PARM_GEN2_SPEED:
 
206
                link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
 
207
                break;
 
208
        default:
 
209
                link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
 
210
                break;
 
211
        }
 
212
        llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
 
213
        writel(llctl, &iphy->link_layer_registers->link_layer_control);
 
214
 
 
215
        sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts);
 
216
 
 
217
        /* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */
 
218
        sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
 
219
 
 
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.
 
222
         */
 
223
        sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
 
224
 
 
225
        writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts);
 
226
 
 
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.
 
232
                 */
 
233
                writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
 
234
                        &iphy->link_layer_registers->maximum_arbitration_wait_timer_timeout);
 
235
        }
 
236
 
 
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);
 
239
 
 
240
        /* We can exit the initial state to the stopped state */
 
241
        sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
 
242
 
 
243
        return SCI_SUCCESS;
 
244
}
 
245
 
 
246
static void phy_sata_timeout(unsigned long data)
 
247
{
 
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;
 
251
        unsigned long flags;
 
252
 
 
253
        spin_lock_irqsave(&ihost->scic_lock, flags);
 
254
 
 
255
        if (tmr->cancel)
 
256
                goto done;
 
257
 
 
258
        dev_dbg(sciphy_to_dev(iphy),
 
259
                 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
 
260
                 "timeout.\n",
 
261
                 __func__,
 
262
                 iphy);
 
263
 
 
264
        sci_change_state(&iphy->sm, SCI_PHY_STARTING);
 
265
done:
 
266
        spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
267
}
 
268
 
 
269
/**
 
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
 
272
 *    be part of a port.
 
273
 * @sci_phy: This parameter specifies the phy for which to retrieve the
 
274
 *    containing port.
 
275
 *
 
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.
 
280
 */
 
281
struct isci_port *phy_get_non_dummy_port(struct isci_phy *iphy)
 
282
{
 
283
        struct isci_port *iport = iphy->owning_port;
 
284
 
 
285
        if (iport->physical_port_index == SCIC_SDS_DUMMY_PORT)
 
286
                return NULL;
 
287
 
 
288
        return iphy->owning_port;
 
289
}
 
290
 
 
291
/**
 
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
 
294
 *    object.
 
295
 *
 
296
 *
 
297
 */
 
298
void sci_phy_set_port(
 
299
        struct isci_phy *iphy,
 
300
        struct isci_port *iport)
 
301
{
 
302
        iphy->owning_port = iport;
 
303
 
 
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);
 
307
        }
 
308
}
 
309
 
 
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)
 
313
{
 
314
        /* Perfrom the initialization of the TL hardware */
 
315
        sci_phy_transport_layer_initialization(iphy, tl);
 
316
 
 
317
        /* Perofrm the initialization of the PE hardware */
 
318
        sci_phy_link_layer_initialization(iphy, ll);
 
319
 
 
320
        /* There is nothing that needs to be done in this state just
 
321
         * transition to the stopped state
 
322
         */
 
323
        sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
 
324
 
 
325
        return SCI_SUCCESS;
 
326
}
 
327
 
 
328
/**
 
329
 * This method assigns the direct attached device ID for this phy.
 
330
 *
 
331
 * @iphy The phy for which the direct attached device id is to
 
332
 *       be assigned.
 
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.
 
336
 */
 
337
void sci_phy_setup_transport(struct isci_phy *iphy, u32 device_id)
 
338
{
 
339
        u32 tl_control;
 
340
 
 
341
        writel(device_id, &iphy->transport_layer_registers->stp_rni);
 
342
 
 
343
        /*
 
344
         * The read should guarantee that the first write gets posted
 
345
         * before the next write
 
346
         */
 
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);
 
350
}
 
351
 
 
352
static void sci_phy_suspend(struct isci_phy *iphy)
 
353
{
 
354
        u32 scu_sas_pcfg_value;
 
355
 
 
356
        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);
 
361
 
 
362
        sci_phy_setup_transport(iphy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
 
363
}
 
364
 
 
365
void sci_phy_resume(struct isci_phy *iphy)
 
366
{
 
367
        u32 scu_sas_pcfg_value;
 
368
 
 
369
        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);
 
374
}
 
375
 
 
376
void sci_phy_get_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas)
 
377
{
 
378
        sas->high = readl(&iphy->link_layer_registers->source_sas_address_high);
 
379
        sas->low = readl(&iphy->link_layer_registers->source_sas_address_low);
 
380
}
 
381
 
 
382
void sci_phy_get_attached_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas)
 
383
{
 
384
        struct sas_identify_frame *iaf;
 
385
 
 
386
        iaf = &iphy->frame_rcvd.iaf;
 
387
        memcpy(sas, iaf->sas_addr, SAS_ADDR_SIZE);
 
388
}
 
389
 
 
390
void sci_phy_get_protocols(struct isci_phy *iphy, struct sci_phy_proto *proto)
 
391
{
 
392
        proto->all = readl(&iphy->link_layer_registers->transmit_identification);
 
393
}
 
394
 
 
395
enum sci_status sci_phy_start(struct isci_phy *iphy)
 
396
{
 
397
        enum sci_phy_states state = iphy->sm.current_state_id;
 
398
 
 
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;
 
403
        }
 
404
 
 
405
        sci_change_state(&iphy->sm, SCI_PHY_STARTING);
 
406
        return SCI_SUCCESS;
 
407
}
 
408
 
 
409
enum sci_status sci_phy_stop(struct isci_phy *iphy)
 
410
{
 
411
        enum sci_phy_states state = iphy->sm.current_state_id;
 
412
 
 
413
        switch (state) {
 
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:
 
423
        case SCI_PHY_READY:
 
424
                break;
 
425
        default:
 
426
                dev_dbg(sciphy_to_dev(iphy),
 
427
                        "%s: in wrong state: %d\n", __func__, state);
 
428
                return SCI_FAILURE_INVALID_STATE;
 
429
        }
 
430
 
 
431
        sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
 
432
        return SCI_SUCCESS;
 
433
}
 
434
 
 
435
enum sci_status sci_phy_reset(struct isci_phy *iphy)
 
436
{
 
437
        enum sci_phy_states state = iphy->sm.current_state_id;
 
438
 
 
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;
 
443
        }
 
444
 
 
445
        sci_change_state(&iphy->sm, SCI_PHY_RESETTING);
 
446
        return SCI_SUCCESS;
 
447
}
 
448
 
 
449
enum sci_status sci_phy_consume_power_handler(struct isci_phy *iphy)
 
450
{
 
451
        enum sci_phy_states state = iphy->sm.current_state_id;
 
452
 
 
453
        switch (state) {
 
454
        case SCI_PHY_SUB_AWAIT_SAS_POWER: {
 
455
                u32 enable_spinup;
 
456
 
 
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);
 
460
 
 
461
                /* Change state to the final state this substate machine has run to completion */
 
462
                sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
 
463
 
 
464
                return SCI_SUCCESS;
 
465
        }
 
466
        case SCI_PHY_SUB_AWAIT_SATA_POWER: {
 
467
                u32 scu_sas_pcfg_value;
 
468
 
 
469
                /* Release the spinup hold state and reset the OOB state machine */
 
470
                scu_sas_pcfg_value =
 
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);
 
477
 
 
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);
 
483
 
 
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);
 
486
 
 
487
                return SCI_SUCCESS;
 
488
        }
 
489
        default:
 
490
                dev_dbg(sciphy_to_dev(iphy),
 
491
                        "%s: in wrong state: %d\n", __func__, state);
 
492
                return SCI_FAILURE_INVALID_STATE;
 
493
        }
 
494
}
 
495
 
 
496
static void sci_phy_start_sas_link_training(struct isci_phy *iphy)
 
497
{
 
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.
 
501
         */
 
502
        u32 phy_control;
 
503
 
 
504
        phy_control = readl(&iphy->link_layer_registers->phy_configuration);
 
505
        phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
 
506
        writel(phy_control,
 
507
               &iphy->link_layer_registers->phy_configuration);
 
508
 
 
509
        sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SAS_SPEED_EN);
 
510
 
 
511
        iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
 
512
}
 
513
 
 
514
static void sci_phy_start_sata_link_training(struct isci_phy *iphy)
 
515
{
 
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
 
519
         */
 
520
        sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_POWER);
 
521
 
 
522
        iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
 
523
}
 
524
 
 
525
/**
 
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
 
529
 *    has completed.
 
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
 
533
 *    sub-state machine.
 
534
 *
 
535
 */
 
536
static void sci_phy_complete_link_training(struct isci_phy *iphy,
 
537
                                           enum sas_linkrate max_link_rate,
 
538
                                           u32 next_state)
 
539
{
 
540
        iphy->max_negotiated_speed = max_link_rate;
 
541
 
 
542
        sci_change_state(&iphy->sm, next_state);
 
543
}
 
544
 
 
545
enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 
546
{
 
547
        enum sci_phy_states state = iphy->sm.current_state_id;
 
548
 
 
549
        switch (state) {
 
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;
 
555
                        break;
 
556
                case SCU_EVENT_SATA_SPINUP_HOLD:
 
557
                        sci_phy_start_sata_link_training(iphy);
 
558
                        iphy->is_in_link_training = true;
 
559
                        break;
 
560
                default:
 
561
                        dev_dbg(sciphy_to_dev(iphy),
 
562
                                "%s: PHY starting substate machine received "
 
563
                                "unexpected event_code %x\n",
 
564
                                __func__,
 
565
                                event_code);
 
566
                        return SCI_FAILURE;
 
567
                }
 
568
                return SCI_SUCCESS;
 
569
        case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
 
570
                switch (scu_get_event_code(event_code)) {
 
571
                case SCU_EVENT_SAS_PHY_DETECTED:
 
572
                        /*
 
573
                         * Why is this being reported again by the controller?
 
574
                         * We would re-enter this state so just stay here */
 
575
                        break;
 
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);
 
580
                        break;
 
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);
 
585
                        break;
 
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);
 
590
                        break;
 
591
                case SCU_EVENT_SATA_SPINUP_HOLD:
 
592
                        /*
 
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);
 
596
                        break;
 
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);
 
600
                        break;
 
601
                default:
 
602
                        dev_warn(sciphy_to_dev(iphy),
 
603
                                 "%s: PHY starting substate machine received "
 
604
                                 "unexpected event_code %x\n",
 
605
                                 __func__, event_code);
 
606
 
 
607
                        return SCI_FAILURE;
 
608
                        break;
 
609
                }
 
610
                return SCI_SUCCESS;
 
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);
 
616
                        break;
 
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
 
620
                         * SATA PHY
 
621
                         */
 
622
                        sci_phy_start_sata_link_training(iphy);
 
623
                        break;
 
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);
 
629
                        break;
 
630
                default:
 
631
                        dev_warn(sciphy_to_dev(iphy),
 
632
                                 "%s: PHY starting substate machine received "
 
633
                                 "unexpected event_code %x\n",
 
634
                                 __func__, event_code);
 
635
                        return SCI_FAILURE;
 
636
                }
 
637
                return SCI_SUCCESS;
 
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);
 
643
                        break;
 
644
                default:
 
645
                        dev_warn(sciphy_to_dev(iphy),
 
646
                                "%s: PHY starting substate machine received unexpected "
 
647
                                "event_code %x\n",
 
648
                                __func__,
 
649
                                event_code);
 
650
                        return SCI_FAILURE;
 
651
                }
 
652
                return SCI_SUCCESS;
 
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);
 
658
                        break;
 
659
                case SCU_EVENT_SATA_SPINUP_HOLD:
 
660
                        /* These events are received every 10ms and are
 
661
                         * expected while in this state
 
662
                         */
 
663
                        break;
 
664
 
 
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.
 
668
                         */
 
669
                        sci_phy_start_sas_link_training(iphy);
 
670
                        break;
 
671
 
 
672
                default:
 
673
                        dev_warn(sciphy_to_dev(iphy),
 
674
                                 "%s: PHY starting substate machine received "
 
675
                                 "unexpected event_code %x\n",
 
676
                                 __func__, event_code);
 
677
 
 
678
                        return SCI_FAILURE;
 
679
                }
 
680
                return SCI_SUCCESS;
 
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);
 
686
                        break;
 
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
 
690
                         */
 
691
                        break;
 
692
                case SCU_EVENT_SATA_PHY_DETECTED:
 
693
                        iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
 
694
 
 
695
                        /* We have received the SATA PHY notification change state */
 
696
                        sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
 
697
                        break;
 
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.
 
701
                         */
 
702
                        sci_phy_start_sas_link_training(iphy);
 
703
                        break;
 
704
                default:
 
705
                        dev_warn(sciphy_to_dev(iphy),
 
706
                                 "%s: PHY starting substate machine received "
 
707
                                 "unexpected event_code %x\n",
 
708
                                 __func__,
 
709
                                 event_code);
 
710
 
 
711
                        return SCI_FAILURE;
 
712
                }
 
713
                return SCI_SUCCESS;
 
714
        case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
 
715
                switch (scu_get_event_code(event_code)) {
 
716
                case SCU_EVENT_SATA_PHY_DETECTED:
 
717
                        /*
 
718
                         * The hardware reports multiple SATA PHY detected events
 
719
                         * ignore the extras */
 
720
                        break;
 
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);
 
725
                        break;
 
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);
 
730
                        break;
 
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);
 
735
                        break;
 
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);
 
739
                        break;
 
740
                case SCU_EVENT_SAS_PHY_DETECTED:
 
741
                        /*
 
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);
 
745
                        break;
 
746
                default:
 
747
                        dev_warn(sciphy_to_dev(iphy),
 
748
                                 "%s: PHY starting substate machine received "
 
749
                                 "unexpected event_code %x\n",
 
750
                                 __func__, event_code);
 
751
 
 
752
                        return SCI_FAILURE;
 
753
                }
 
754
 
 
755
                return SCI_SUCCESS;
 
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);
 
761
                        break;
 
762
 
 
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);
 
766
                        break;
 
767
 
 
768
                default:
 
769
                        dev_warn(sciphy_to_dev(iphy),
 
770
                                 "%s: PHY starting substate machine received "
 
771
                                 "unexpected event_code %x\n",
 
772
                                 __func__,
 
773
                                 event_code);
 
774
 
 
775
                        return SCI_FAILURE;
 
776
                }
 
777
                return SCI_SUCCESS;
 
778
        case SCI_PHY_READY:
 
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);
 
783
                        break;
 
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);
 
788
                        else
 
789
                                iphy->bcn_received_while_port_unassigned = true;
 
790
                        break;
 
791
                default:
 
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;
 
797
                }
 
798
                return SCI_SUCCESS;
 
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);
 
804
                        break;
 
805
                default:
 
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);
 
810
 
 
811
                        return SCI_FAILURE_INVALID_STATE;
 
812
                        break;
 
813
                }
 
814
                return SCI_SUCCESS;
 
815
        default:
 
816
                dev_dbg(sciphy_to_dev(iphy),
 
817
                        "%s: in wrong state: %d\n", __func__, state);
 
818
                return SCI_FAILURE_INVALID_STATE;
 
819
        }
 
820
}
 
821
 
 
822
enum sci_status sci_phy_frame_handler(struct isci_phy *iphy, u32 frame_index)
 
823
{
 
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;
 
827
        unsigned long flags;
 
828
 
 
829
        switch (state) {
 
830
        case SCI_PHY_SUB_AWAIT_IAF_UF: {
 
831
                u32 *frame_words;
 
832
                struct sas_identify_frame iaf;
 
833
 
 
834
                result = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
 
835
                                                                  frame_index,
 
836
                                                                  (void **)&frame_words);
 
837
 
 
838
                if (result != SCI_SUCCESS)
 
839
                        return result;
 
840
 
 
841
                sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
 
842
                if (iaf.frame_type == 0) {
 
843
                        u32 state;
 
844
 
 
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);
 
848
                        if (iaf.smp_tport) {
 
849
                                /* We got the IAF for an expander PHY go to the final
 
850
                                 * state since there are no power requirements for
 
851
                                 * expander phys.
 
852
                                 */
 
853
                                state = SCI_PHY_SUB_FINAL;
 
854
                        } else {
 
855
                                /* We got the IAF we can now go to the await spinup
 
856
                                 * semaphore state
 
857
                                 */
 
858
                                state = SCI_PHY_SUB_AWAIT_SAS_POWER;
 
859
                        }
 
860
                        sci_change_state(&iphy->sm, state);
 
861
                        result = SCI_SUCCESS;
 
862
                } else
 
863
                        dev_warn(sciphy_to_dev(iphy),
 
864
                                "%s: PHY starting substate machine received "
 
865
                                "unexpected frame id %x\n",
 
866
                                __func__, frame_index);
 
867
 
 
868
                sci_controller_release_frame(ihost, frame_index);
 
869
                return result;
 
870
        }
 
871
        case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: {
 
872
                struct dev_to_host_fis *frame_header;
 
873
                u32 *fis_frame_data;
 
874
 
 
875
                result = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
 
876
                                                                  frame_index,
 
877
                                                                  (void **)&frame_header);
 
878
 
 
879
                if (result != SCI_SUCCESS)
 
880
                        return result;
 
881
 
 
882
                if ((frame_header->fis_type == FIS_REGD2H) &&
 
883
                    !(frame_header->status & ATA_BUSY)) {
 
884
                        sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
 
885
                                                                 frame_index,
 
886
                                                                 (void **)&fis_frame_data);
 
887
 
 
888
                        spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
 
889
                        sci_controller_copy_sata_response(&iphy->frame_rcvd.fis,
 
890
                                                          frame_header,
 
891
                                                          fis_frame_data);
 
892
                        spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
 
893
 
 
894
                        /* got IAF we can now go to the await spinup semaphore state */
 
895
                        sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
 
896
 
 
897
                        result = SCI_SUCCESS;
 
898
                } else
 
899
                        dev_warn(sciphy_to_dev(iphy),
 
900
                                 "%s: PHY starting substate machine received "
 
901
                                 "unexpected frame id %x\n",
 
902
                                 __func__, frame_index);
 
903
 
 
904
                /* Regardless of the result we are done with this frame with it */
 
905
                sci_controller_release_frame(ihost, frame_index);
 
906
 
 
907
                return result;
 
908
        }
 
909
        default:
 
910
                dev_dbg(sciphy_to_dev(iphy),
 
911
                        "%s: in wrong state: %d\n", __func__, state);
 
912
                return SCI_FAILURE_INVALID_STATE;
 
913
        }
 
914
 
 
915
}
 
916
 
 
917
static void sci_phy_starting_initial_substate_enter(struct sci_base_state_machine *sm)
 
918
{
 
919
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
920
 
 
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);
 
923
}
 
924
 
 
925
static void sci_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
 
926
{
 
927
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
928
        struct isci_host *ihost = iphy->owning_port->owning_controller;
 
929
 
 
930
        sci_controller_power_control_queue_insert(ihost, iphy);
 
931
}
 
932
 
 
933
static void sci_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
 
934
{
 
935
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
936
        struct isci_host *ihost = iphy->owning_port->owning_controller;
 
937
 
 
938
        sci_controller_power_control_queue_remove(ihost, iphy);
 
939
}
 
940
 
 
941
static void sci_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
 
942
{
 
943
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
944
        struct isci_host *ihost = iphy->owning_port->owning_controller;
 
945
 
 
946
        sci_controller_power_control_queue_insert(ihost, iphy);
 
947
}
 
948
 
 
949
static void sci_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
 
950
{
 
951
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
952
        struct isci_host *ihost = iphy->owning_port->owning_controller;
 
953
 
 
954
        sci_controller_power_control_queue_remove(ihost, iphy);
 
955
}
 
956
 
 
957
static void sci_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
 
958
{
 
959
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
960
 
 
961
        sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
 
962
}
 
963
 
 
964
static void sci_phy_starting_await_sata_phy_substate_exit(struct sci_base_state_machine *sm)
 
965
{
 
966
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
967
 
 
968
        sci_del_timer(&iphy->sata_timer);
 
969
}
 
970
 
 
971
static void sci_phy_starting_await_sata_speed_substate_enter(struct sci_base_state_machine *sm)
 
972
{
 
973
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
974
 
 
975
        sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
 
976
}
 
977
 
 
978
static void sci_phy_starting_await_sata_speed_substate_exit(struct sci_base_state_machine *sm)
 
979
{
 
980
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
981
 
 
982
        sci_del_timer(&iphy->sata_timer);
 
983
}
 
984
 
 
985
static void sci_phy_starting_await_sig_fis_uf_substate_enter(struct sci_base_state_machine *sm)
 
986
{
 
987
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
988
 
 
989
        if (sci_port_link_detected(iphy->owning_port, iphy)) {
 
990
 
 
991
                /*
 
992
                 * Clear the PE suspend condition so we can actually
 
993
                 * receive SIG FIS
 
994
                 * The hardware will not respond to the XRDY until the PE
 
995
                 * suspend condition is cleared.
 
996
                 */
 
997
                sci_phy_resume(iphy);
 
998
 
 
999
                sci_mod_timer(&iphy->sata_timer,
 
1000
                              SCIC_SDS_SIGNATURE_FIS_TIMEOUT);
 
1001
        } else
 
1002
                iphy->is_in_link_training = false;
 
1003
}
 
1004
 
 
1005
static void sci_phy_starting_await_sig_fis_uf_substate_exit(struct sci_base_state_machine *sm)
 
1006
{
 
1007
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
1008
 
 
1009
        sci_del_timer(&iphy->sata_timer);
 
1010
}
 
1011
 
 
1012
static void sci_phy_starting_final_substate_enter(struct sci_base_state_machine *sm)
 
1013
{
 
1014
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
1015
 
 
1016
        /* State machine has run to completion so exit out and change
 
1017
         * the base state machine to the ready state
 
1018
         */
 
1019
        sci_change_state(&iphy->sm, SCI_PHY_READY);
 
1020
}
 
1021
 
 
1022
/**
 
1023
 *
 
1024
 * @sci_phy: This is the struct isci_phy object to stop.
 
1025
 *
 
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
 
1029
 */
 
1030
static void scu_link_layer_stop_protocol_engine(
 
1031
        struct isci_phy *iphy)
 
1032
{
 
1033
        u32 scu_sas_pcfg_value;
 
1034
        u32 enable_spinup_value;
 
1035
 
 
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);
 
1045
 
 
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);
 
1050
}
 
1051
 
 
1052
/**
 
1053
 *
 
1054
 *
 
1055
 * This method will start the OOB/SN state machine for this struct isci_phy object.
 
1056
 */
 
1057
static void scu_link_layer_start_oob(
 
1058
        struct isci_phy *iphy)
 
1059
{
 
1060
        u32 scu_sas_pcfg_value;
 
1061
 
 
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);
 
1070
}
 
1071
 
 
1072
/**
 
1073
 *
 
1074
 *
 
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.
 
1079
 */
 
1080
static void scu_link_layer_tx_hard_reset(
 
1081
        struct isci_phy *iphy)
 
1082
{
 
1083
        u32 phy_configuration_value;
 
1084
 
 
1085
        /*
 
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);
 
1095
 
 
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);
 
1101
}
 
1102
 
 
1103
static void sci_phy_stopped_state_enter(struct sci_base_state_machine *sm)
 
1104
{
 
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;
 
1108
 
 
1109
        /*
 
1110
         * @todo We need to get to the controller to place this PE in a
 
1111
         * reset state
 
1112
         */
 
1113
        sci_del_timer(&iphy->sata_timer);
 
1114
 
 
1115
        scu_link_layer_stop_protocol_engine(iphy);
 
1116
 
 
1117
        if (iphy->sm.previous_state_id != SCI_PHY_INITIAL)
 
1118
                sci_controller_link_down(ihost, phy_get_non_dummy_port(iphy), iphy);
 
1119
}
 
1120
 
 
1121
static void sci_phy_starting_state_enter(struct sci_base_state_machine *sm)
 
1122
{
 
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;
 
1126
 
 
1127
        scu_link_layer_stop_protocol_engine(iphy);
 
1128
        scu_link_layer_start_oob(iphy);
 
1129
 
 
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;
 
1133
 
 
1134
        if (iphy->sm.previous_state_id == SCI_PHY_READY)
 
1135
                sci_controller_link_down(ihost, phy_get_non_dummy_port(iphy), iphy);
 
1136
 
 
1137
        sci_change_state(&iphy->sm, SCI_PHY_SUB_INITIAL);
 
1138
}
 
1139
 
 
1140
static void sci_phy_ready_state_enter(struct sci_base_state_machine *sm)
 
1141
{
 
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;
 
1145
 
 
1146
        sci_controller_link_up(ihost, phy_get_non_dummy_port(iphy), iphy);
 
1147
}
 
1148
 
 
1149
static void sci_phy_ready_state_exit(struct sci_base_state_machine *sm)
 
1150
{
 
1151
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
1152
 
 
1153
        sci_phy_suspend(iphy);
 
1154
}
 
1155
 
 
1156
static void sci_phy_resetting_state_enter(struct sci_base_state_machine *sm)
 
1157
{
 
1158
        struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
 
1159
 
 
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
 
1163
         */
 
1164
        sci_port_deactivate_phy(iphy->owning_port, iphy, false);
 
1165
 
 
1166
        if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
 
1167
                scu_link_layer_tx_hard_reset(iphy);
 
1168
        } else {
 
1169
                /* The SCU does not need to have a discrete reset state so
 
1170
                 * just go back to the starting state.
 
1171
                 */
 
1172
                sci_change_state(&iphy->sm, SCI_PHY_STARTING);
 
1173
        }
 
1174
}
 
1175
 
 
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,
 
1180
        },
 
1181
        [SCI_PHY_STARTING] = {
 
1182
                .enter_state = sci_phy_starting_state_enter,
 
1183
        },
 
1184
        [SCI_PHY_SUB_INITIAL] = {
 
1185
                .enter_state = sci_phy_starting_initial_substate_enter,
 
1186
        },
 
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,
 
1193
        },
 
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
 
1197
        },
 
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
 
1201
        },
 
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
 
1205
        },
 
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
 
1209
        },
 
1210
        [SCI_PHY_SUB_FINAL] = {
 
1211
                .enter_state = sci_phy_starting_final_substate_enter,
 
1212
        },
 
1213
        [SCI_PHY_READY] = {
 
1214
                .enter_state = sci_phy_ready_state_enter,
 
1215
                .exit_state = sci_phy_ready_state_exit,
 
1216
        },
 
1217
        [SCI_PHY_RESETTING] = {
 
1218
                .enter_state = sci_phy_resetting_state_enter,
 
1219
        },
 
1220
        [SCI_PHY_FINAL] = { },
 
1221
};
 
1222
 
 
1223
void sci_phy_construct(struct isci_phy *iphy,
 
1224
                            struct isci_port *iport, u8 phy_index)
 
1225
{
 
1226
        sci_init_sm(&iphy->sm, sci_phy_state_table, SCI_PHY_INITIAL);
 
1227
 
 
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;
 
1235
 
 
1236
        /* Create the SIGNATURE FIS Timeout timer for this phy */
 
1237
        sci_init_timer(&iphy->sata_timer, phy_sata_timeout);
 
1238
}
 
1239
 
 
1240
void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
 
1241
{
 
1242
        struct sci_oem_params *oem = &ihost->oem_parameters;
 
1243
        u64 sci_sas_addr;
 
1244
        __be64 sas_addr;
 
1245
 
 
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));
 
1251
 
 
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));
 
1268
}
 
1269
 
 
1270
 
 
1271
/**
 
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.
 
1277
 *
 
1278
 * status, zero indicates success.
 
1279
 */
 
1280
int isci_phy_control(struct asd_sas_phy *sas_phy,
 
1281
                     enum phy_func func,
 
1282
                     void *buf)
 
1283
{
 
1284
        int ret = 0;
 
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;
 
1289
 
 
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);
 
1293
 
 
1294
        switch (func) {
 
1295
        case PHY_FUNC_DISABLE:
 
1296
                spin_lock_irqsave(&ihost->scic_lock, flags);
 
1297
                sci_phy_stop(iphy);
 
1298
                spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
1299
                break;
 
1300
 
 
1301
        case PHY_FUNC_LINK_RESET:
 
1302
                spin_lock_irqsave(&ihost->scic_lock, flags);
 
1303
                sci_phy_stop(iphy);
 
1304
                sci_phy_start(iphy);
 
1305
                spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
1306
                break;
 
1307
 
 
1308
        case PHY_FUNC_HARD_RESET:
 
1309
                if (!iport)
 
1310
                        return -ENODEV;
 
1311
 
 
1312
                /* Perform the port reset. */
 
1313
                ret = isci_port_perform_hard_reset(ihost, iport, iphy);
 
1314
 
 
1315
                break;
 
1316
        case PHY_FUNC_GET_EVENTS: {
 
1317
                struct scu_link_layer_registers __iomem *r;
 
1318
                struct sas_phy *phy = sas_phy->phy;
 
1319
 
 
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);
 
1325
                break;
 
1326
        }
 
1327
 
 
1328
        default:
 
1329
                dev_dbg(&ihost->pdev->dev,
 
1330
                           "%s: phy %p; func %d NOT IMPLEMENTED!\n",
 
1331
                           __func__, sas_phy, func);
 
1332
                ret = -ENOSYS;
 
1333
                break;
 
1334
        }
 
1335
        return ret;
 
1336
}