Commit | Line | Data |
---|---|---|
6f231dda DW |
1 | /* |
2 | * This file is provided under a dual BSD/GPLv2 license. When using or | |
3 | * redistributing this file, you may do so under either license. | |
4 | * | |
5 | * GPL LICENSE SUMMARY | |
6 | * | |
7 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of version 2 of the GNU General Public License as | |
11 | * published by the Free Software Foundation. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | * The full GNU General Public License is included in this distribution | |
22 | * in the file called LICENSE.GPL. | |
23 | * | |
24 | * BSD LICENSE | |
25 | * | |
26 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | |
27 | * All rights reserved. | |
28 | * | |
29 | * Redistribution and use in source and binary forms, with or without | |
30 | * modification, are permitted provided that the following conditions | |
31 | * are met: | |
32 | * | |
33 | * * Redistributions of source code must retain the above copyright | |
34 | * notice, this list of conditions and the following disclaimer. | |
35 | * * Redistributions in binary form must reproduce the above copyright | |
36 | * notice, this list of conditions and the following disclaimer in | |
37 | * the documentation and/or other materials provided with the | |
38 | * distribution. | |
39 | * * Neither the name of Intel Corporation nor the names of its | |
40 | * contributors may be used to endorse or promote products derived | |
41 | * from this software without specific prior written permission. | |
42 | * | |
43 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
44 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
45 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
46 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
47 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
48 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
49 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
50 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
51 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
52 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
54 | */ | |
55 | ||
56 | #ifndef _SCIC_SDS_PHY_H_ | |
57 | #define _SCIC_SDS_PHY_H_ | |
58 | ||
6f231dda | 59 | #include "intel_sas.h" |
d7b90fc3 | 60 | #include "scic_phy.h" |
6f231dda | 61 | #include "scu_registers.h" |
d857d9a0 | 62 | #include "sci_base_state_machine.h" |
26bace34 | 63 | #include <scsi/libsas.h> |
6f231dda DW |
64 | |
65 | struct scic_sds_port; | |
66 | /** | |
67 | * | |
68 | * | |
69 | * This is the timeout value for the SATA phy to wait for a SIGNATURE FIS | |
70 | * before restarting the starting state machine. Technically, the old parallel | |
71 | * ATA specification required up to 30 seconds for a device to issue its | |
72 | * signature FIS as a result of a soft reset. Now we see that devices respond | |
73 | * generally within 15 seconds, but we'll use 25 for now. | |
74 | */ | |
75 | #define SCIC_SDS_SIGNATURE_FIS_TIMEOUT 25000 | |
76 | ||
77 | /** | |
78 | * | |
79 | * | |
80 | * This is the timeout for the SATA OOB/SN because the hardware does not | |
81 | * recognize a hot plug after OOB signal but before the SN signals. We need to | |
82 | * make sure after a hotplug timeout if we have not received the speed event | |
83 | * notification from the hardware that we restart the hardware OOB state | |
84 | * machine. | |
85 | */ | |
86 | #define SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT 250 | |
87 | ||
d857d9a0 MT |
88 | enum scic_sds_phy_states { |
89 | /** | |
90 | * Simply the initial state for the base domain state machine. | |
91 | */ | |
92 | SCI_BASE_PHY_STATE_INITIAL, | |
93 | ||
94 | /** | |
95 | * This state indicates that the phy has successfully been stopped. | |
96 | * In this state no new IO operations are permitted on this phy. | |
97 | * This state is entered from the INITIAL state. | |
98 | * This state is entered from the STARTING state. | |
99 | * This state is entered from the READY state. | |
100 | * This state is entered from the RESETTING state. | |
101 | */ | |
102 | SCI_BASE_PHY_STATE_STOPPED, | |
103 | ||
104 | /** | |
105 | * This state indicates that the phy is in the process of becomming | |
106 | * ready. In this state no new IO operations are permitted on this phy. | |
107 | * This state is entered from the STOPPED state. | |
108 | * This state is entered from the READY state. | |
109 | * This state is entered from the RESETTING state. | |
110 | */ | |
111 | SCI_BASE_PHY_STATE_STARTING, | |
112 | ||
113 | /** | |
114 | * This state indicates the the phy is now ready. Thus, the user | |
115 | * is able to perform IO operations utilizing this phy as long as it | |
116 | * is currently part of a valid port. | |
117 | * This state is entered from the STARTING state. | |
118 | */ | |
119 | SCI_BASE_PHY_STATE_READY, | |
120 | ||
121 | /** | |
122 | * This state indicates that the phy is in the process of being reset. | |
123 | * In this state no new IO operations are permitted on this phy. | |
124 | * This state is entered from the READY state. | |
125 | */ | |
126 | SCI_BASE_PHY_STATE_RESETTING, | |
127 | ||
128 | /** | |
129 | * Simply the final state for the base phy state machine. | |
130 | */ | |
131 | SCI_BASE_PHY_STATE_FINAL, | |
132 | }; | |
133 | ||
134 | ||
6f231dda | 135 | /** |
de728b7d | 136 | * enum scic_sds_phy_starting_substates - |
6f231dda DW |
137 | * |
138 | * | |
139 | */ | |
de728b7d | 140 | enum scic_sds_phy_starting_substates { |
6f231dda DW |
141 | /** |
142 | * Initial state | |
143 | */ | |
144 | SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL, | |
145 | ||
146 | /** | |
147 | * Wait state for the hardware OSSP event type notification | |
148 | */ | |
149 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN, | |
150 | ||
151 | /** | |
152 | * Wait state for the PHY speed notification | |
153 | */ | |
154 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN, | |
155 | ||
156 | /** | |
157 | * Wait state for the IAF Unsolicited frame notification | |
158 | */ | |
159 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF, | |
160 | ||
161 | /** | |
162 | * Wait state for the request to consume power | |
163 | */ | |
164 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER, | |
165 | ||
166 | /** | |
167 | * Wait state for request to consume power | |
168 | */ | |
169 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER, | |
170 | ||
171 | /** | |
172 | * Wait state for the SATA PHY notification | |
173 | */ | |
174 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN, | |
175 | ||
176 | /** | |
177 | * Wait for the SATA PHY speed notification | |
178 | */ | |
179 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN, | |
180 | ||
181 | /** | |
182 | * Wait state for the SIGNATURE FIS unsolicited frame notification | |
183 | */ | |
184 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF, | |
185 | ||
186 | /** | |
187 | * Exit state for this state machine | |
188 | */ | |
189 | SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL, | |
6f231dda DW |
190 | }; |
191 | ||
192 | struct scic_sds_port; | |
193 | struct scic_sds_controller; | |
194 | ||
6f231dda DW |
195 | /** |
196 | * This enumeration provides a named phy type for the state machine | |
197 | * | |
198 | * | |
199 | */ | |
de728b7d | 200 | enum scic_sds_phy_protocol { |
6f231dda DW |
201 | /** |
202 | * This is an unknown phy type since there is either nothing on the other | |
203 | * end or we have not detected the phy type as yet. | |
204 | */ | |
205 | SCIC_SDS_PHY_PROTOCOL_UNKNOWN, | |
206 | ||
207 | /** | |
208 | * This is a SAS PHY | |
209 | */ | |
210 | SCIC_SDS_PHY_PROTOCOL_SAS, | |
211 | ||
212 | /** | |
213 | * This is a SATA PHY | |
214 | */ | |
215 | SCIC_SDS_PHY_PROTOCOL_SATA, | |
216 | ||
217 | SCIC_SDS_MAX_PHY_PROTOCOLS | |
218 | }; | |
219 | ||
e1e72a00 | 220 | struct isci_phy; |
6f231dda DW |
221 | /** |
222 | * struct scic_sds_phy - This structure contains or references all of the data | |
223 | * necessary to represent the core phy object and SCU harware protocol | |
224 | * engine. | |
225 | * | |
226 | * | |
227 | */ | |
228 | struct scic_sds_phy { | |
d857d9a0 | 229 | /** |
e1e72a00 | 230 | * This field depicts the peer object for the phy. |
d857d9a0 | 231 | */ |
e1e72a00 | 232 | struct isci_phy *iphy; |
d857d9a0 MT |
233 | |
234 | /** | |
235 | * This field contains the information for the base phy state machine. | |
236 | */ | |
237 | struct sci_base_state_machine state_machine; | |
6f231dda DW |
238 | |
239 | /** | |
240 | * This field specifies the port object that owns/contains this phy. | |
241 | */ | |
242 | struct scic_sds_port *owning_port; | |
243 | ||
244 | /** | |
245 | * This field indicates whether the phy supports 1.5 Gb/s, 3.0 Gb/s, | |
246 | * or 6.0 Gb/s operation. | |
247 | */ | |
26bace34 | 248 | enum sas_linkrate max_negotiated_speed; |
6f231dda DW |
249 | |
250 | /** | |
251 | * This member specifies the protocol being utilized on this phy. This | |
252 | * field contains a legitamite value once the PHY has link trained with | |
253 | * a remote phy. | |
254 | */ | |
de728b7d | 255 | enum scic_sds_phy_protocol protocol; |
6f231dda DW |
256 | |
257 | /** | |
258 | * This field specifies the index with which this phy is associated (0-3). | |
259 | */ | |
260 | u8 phy_index; | |
261 | ||
262 | /** | |
263 | * This member indicates if this particular PHY has received a BCN while | |
264 | * it had no port assignement. This BCN will be reported once the phy is | |
265 | * assigned to a port. | |
266 | */ | |
267 | bool bcn_received_while_port_unassigned; | |
268 | ||
269 | /** | |
270 | * This field indicates if this PHY is currently in the process of | |
271 | * link training (i.e. it has started OOB, but has yet to perform | |
272 | * IAF exchange/Signature FIS reception). | |
273 | */ | |
274 | bool is_in_link_training; | |
275 | ||
6f231dda DW |
276 | /** |
277 | * This field contains a reference to the timer utilized in detecting | |
278 | * when a signature FIS timeout has occurred. The signature FIS is the | |
279 | * first FIS sent by an attached SATA device after OOB/SN. | |
280 | */ | |
281 | void *sata_timeout_timer; | |
282 | ||
8f31550c | 283 | const struct scic_sds_phy_state_handler *state_handlers; |
6f231dda DW |
284 | |
285 | struct sci_base_state_machine starting_substate_machine; | |
286 | ||
24621466 HD |
287 | /** |
288 | * This field is the pointer to the transport layer register for the SCU | |
289 | * hardware. | |
290 | */ | |
291 | struct scu_transport_layer_registers __iomem *transport_layer_registers; | |
292 | ||
6f231dda DW |
293 | /** |
294 | * This field points to the link layer register set within the SCU. | |
295 | */ | |
24621466 | 296 | struct scu_link_layer_registers __iomem *link_layer_registers; |
6f231dda DW |
297 | |
298 | }; | |
299 | ||
d857d9a0 | 300 | typedef enum sci_status (*scic_sds_phy_handler_t)(struct scic_sds_phy *); |
8f31550c DW |
301 | typedef enum sci_status (*scic_sds_phy_event_handler_t)(struct scic_sds_phy *, u32); |
302 | typedef enum sci_status (*scic_sds_phy_frame_handler_t)(struct scic_sds_phy *, u32); | |
303 | typedef enum sci_status (*scic_sds_phy_power_handler_t)(struct scic_sds_phy *); | |
6f231dda DW |
304 | |
305 | /** | |
306 | * struct scic_sds_phy_state_handler - | |
307 | * | |
308 | * | |
309 | */ | |
310 | struct scic_sds_phy_state_handler { | |
311 | /** | |
d857d9a0 MT |
312 | * The start_handler specifies the method invoked when there is an |
313 | * attempt to start a phy. | |
314 | */ | |
315 | scic_sds_phy_handler_t start_handler; | |
316 | ||
317 | /** | |
318 | * The stop_handler specifies the method invoked when there is an | |
319 | * attempt to stop a phy. | |
320 | */ | |
321 | scic_sds_phy_handler_t stop_handler; | |
322 | ||
323 | /** | |
324 | * The reset_handler specifies the method invoked when there is an | |
325 | * attempt to reset a phy. | |
326 | */ | |
327 | scic_sds_phy_handler_t reset_handler; | |
328 | ||
329 | /** | |
330 | * The destruct_handler specifies the method invoked when attempting to | |
331 | * destruct a phy. | |
6f231dda | 332 | */ |
d857d9a0 | 333 | scic_sds_phy_handler_t destruct_handler; |
6f231dda DW |
334 | |
335 | /** | |
336 | * The state handler for unsolicited frames received from the SCU hardware. | |
337 | */ | |
8f31550c | 338 | scic_sds_phy_frame_handler_t frame_handler; |
6f231dda DW |
339 | |
340 | /** | |
341 | * The state handler for events received from the SCU hardware. | |
342 | */ | |
8f31550c | 343 | scic_sds_phy_event_handler_t event_handler; |
6f231dda DW |
344 | |
345 | /** | |
346 | * The state handler for staggered spinup. | |
347 | */ | |
8f31550c | 348 | scic_sds_phy_power_handler_t consume_power_handler; |
6f231dda DW |
349 | |
350 | }; | |
351 | ||
6f231dda DW |
352 | /** |
353 | * scic_sds_phy_get_index() - | |
354 | * | |
355 | * This macro returns the phy index for the specified phy | |
356 | */ | |
357 | #define scic_sds_phy_get_index(phy) \ | |
358 | ((phy)->phy_index) | |
359 | ||
360 | /** | |
361 | * scic_sds_phy_get_controller() - This macro returns the controller for this | |
362 | * phy | |
363 | * | |
364 | * | |
365 | */ | |
366 | #define scic_sds_phy_get_controller(phy) \ | |
367 | (scic_sds_port_get_controller((phy)->owning_port)) | |
368 | ||
6f231dda DW |
369 | /** |
370 | * scic_sds_phy_set_state_handlers() - This macro sets the state handlers for | |
371 | * this phy object | |
372 | * | |
373 | * | |
374 | */ | |
375 | #define scic_sds_phy_set_state_handlers(phy, handlers) \ | |
376 | ((phy)->state_handlers = (handlers)) | |
377 | ||
378 | /** | |
379 | * scic_sds_phy_set_base_state_handlers() - | |
380 | * | |
381 | * This macro set the base state handlers for the phy object. | |
382 | */ | |
383 | #define scic_sds_phy_set_base_state_handlers(phy, state_id) \ | |
384 | scic_sds_phy_set_state_handlers(\ | |
385 | (phy), \ | |
386 | &scic_sds_phy_state_handler_table[(state_id)] \ | |
387 | ) | |
388 | ||
6f231dda DW |
389 | void scic_sds_phy_construct( |
390 | struct scic_sds_phy *this_phy, | |
391 | struct scic_sds_port *owning_port, | |
392 | u8 phy_index); | |
393 | ||
394 | struct scic_sds_port *scic_sds_phy_get_port( | |
395 | struct scic_sds_phy *this_phy); | |
396 | ||
397 | void scic_sds_phy_set_port( | |
398 | struct scic_sds_phy *this_phy, | |
399 | struct scic_sds_port *owning_port); | |
400 | ||
401 | enum sci_status scic_sds_phy_initialize( | |
402 | struct scic_sds_phy *this_phy, | |
24621466 HD |
403 | struct scu_transport_layer_registers __iomem *transport_layer_registers, |
404 | struct scu_link_layer_registers __iomem *link_layer_registers); | |
6f231dda DW |
405 | |
406 | enum sci_status scic_sds_phy_start( | |
407 | struct scic_sds_phy *this_phy); | |
408 | ||
409 | enum sci_status scic_sds_phy_stop( | |
410 | struct scic_sds_phy *this_phy); | |
411 | ||
412 | enum sci_status scic_sds_phy_reset( | |
413 | struct scic_sds_phy *this_phy); | |
414 | ||
6f231dda DW |
415 | void scic_sds_phy_resume( |
416 | struct scic_sds_phy *this_phy); | |
417 | ||
24621466 HD |
418 | void scic_sds_phy_setup_transport( |
419 | struct scic_sds_phy *this_phy, | |
420 | u32 device_id); | |
421 | ||
6f231dda DW |
422 | enum sci_status scic_sds_phy_event_handler( |
423 | struct scic_sds_phy *this_phy, | |
424 | u32 event_code); | |
425 | ||
426 | enum sci_status scic_sds_phy_frame_handler( | |
427 | struct scic_sds_phy *this_phy, | |
428 | u32 frame_index); | |
429 | ||
430 | enum sci_status scic_sds_phy_consume_power_handler( | |
431 | struct scic_sds_phy *this_phy); | |
432 | ||
433 | void scic_sds_phy_get_sas_address( | |
434 | struct scic_sds_phy *this_phy, | |
435 | struct sci_sas_address *sas_address); | |
436 | ||
437 | void scic_sds_phy_get_attached_sas_address( | |
438 | struct scic_sds_phy *this_phy, | |
439 | struct sci_sas_address *sas_address); | |
440 | ||
441 | void scic_sds_phy_get_protocols( | |
d7b90fc3 DJ |
442 | struct scic_sds_phy *sci_phy, |
443 | struct scic_phy_proto *protocols); | |
6f231dda | 444 | |
6f231dda | 445 | #endif /* _SCIC_SDS_PHY_H_ */ |