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" |
6f231dda | 60 | #include "scu_registers.h" |
d857d9a0 | 61 | #include "sci_base_state_machine.h" |
26bace34 | 62 | #include <scsi/libsas.h> |
6f231dda DW |
63 | |
64 | struct scic_sds_port; | |
65 | /** | |
66 | * | |
67 | * | |
68 | * This is the timeout value for the SATA phy to wait for a SIGNATURE FIS | |
69 | * before restarting the starting state machine. Technically, the old parallel | |
70 | * ATA specification required up to 30 seconds for a device to issue its | |
71 | * signature FIS as a result of a soft reset. Now we see that devices respond | |
72 | * generally within 15 seconds, but we'll use 25 for now. | |
73 | */ | |
74 | #define SCIC_SDS_SIGNATURE_FIS_TIMEOUT 25000 | |
75 | ||
76 | /** | |
77 | * | |
78 | * | |
79 | * This is the timeout for the SATA OOB/SN because the hardware does not | |
80 | * recognize a hot plug after OOB signal but before the SN signals. We need to | |
81 | * make sure after a hotplug timeout if we have not received the speed event | |
82 | * notification from the hardware that we restart the hardware OOB state | |
83 | * machine. | |
84 | */ | |
85 | #define SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT 250 | |
86 | ||
d857d9a0 MT |
87 | enum scic_sds_phy_states { |
88 | /** | |
89 | * Simply the initial state for the base domain state machine. | |
90 | */ | |
91 | SCI_BASE_PHY_STATE_INITIAL, | |
92 | ||
93 | /** | |
94 | * This state indicates that the phy has successfully been stopped. | |
95 | * In this state no new IO operations are permitted on this phy. | |
96 | * This state is entered from the INITIAL state. | |
97 | * This state is entered from the STARTING state. | |
98 | * This state is entered from the READY state. | |
99 | * This state is entered from the RESETTING state. | |
100 | */ | |
101 | SCI_BASE_PHY_STATE_STOPPED, | |
102 | ||
103 | /** | |
104 | * This state indicates that the phy is in the process of becomming | |
105 | * ready. In this state no new IO operations are permitted on this phy. | |
106 | * This state is entered from the STOPPED state. | |
107 | * This state is entered from the READY state. | |
108 | * This state is entered from the RESETTING state. | |
109 | */ | |
110 | SCI_BASE_PHY_STATE_STARTING, | |
111 | ||
112 | /** | |
113 | * This state indicates the the phy is now ready. Thus, the user | |
114 | * is able to perform IO operations utilizing this phy as long as it | |
115 | * is currently part of a valid port. | |
116 | * This state is entered from the STARTING state. | |
117 | */ | |
118 | SCI_BASE_PHY_STATE_READY, | |
119 | ||
120 | /** | |
121 | * This state indicates that the phy is in the process of being reset. | |
122 | * In this state no new IO operations are permitted on this phy. | |
123 | * This state is entered from the READY state. | |
124 | */ | |
125 | SCI_BASE_PHY_STATE_RESETTING, | |
126 | ||
127 | /** | |
128 | * Simply the final state for the base phy state machine. | |
129 | */ | |
130 | SCI_BASE_PHY_STATE_FINAL, | |
131 | }; | |
132 | ||
133 | ||
6f231dda | 134 | /** |
de728b7d | 135 | * enum scic_sds_phy_starting_substates - |
6f231dda DW |
136 | * |
137 | * | |
138 | */ | |
de728b7d | 139 | enum scic_sds_phy_starting_substates { |
6f231dda DW |
140 | /** |
141 | * Initial state | |
142 | */ | |
143 | SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL, | |
144 | ||
145 | /** | |
146 | * Wait state for the hardware OSSP event type notification | |
147 | */ | |
148 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN, | |
149 | ||
150 | /** | |
151 | * Wait state for the PHY speed notification | |
152 | */ | |
153 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN, | |
154 | ||
155 | /** | |
156 | * Wait state for the IAF Unsolicited frame notification | |
157 | */ | |
158 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF, | |
159 | ||
160 | /** | |
161 | * Wait state for the request to consume power | |
162 | */ | |
163 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER, | |
164 | ||
165 | /** | |
166 | * Wait state for request to consume power | |
167 | */ | |
168 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER, | |
169 | ||
170 | /** | |
171 | * Wait state for the SATA PHY notification | |
172 | */ | |
173 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN, | |
174 | ||
175 | /** | |
176 | * Wait for the SATA PHY speed notification | |
177 | */ | |
178 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN, | |
179 | ||
180 | /** | |
181 | * Wait state for the SIGNATURE FIS unsolicited frame notification | |
182 | */ | |
183 | SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF, | |
184 | ||
185 | /** | |
186 | * Exit state for this state machine | |
187 | */ | |
188 | SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL, | |
6f231dda DW |
189 | }; |
190 | ||
191 | struct scic_sds_port; | |
192 | struct scic_sds_controller; | |
193 | ||
6f231dda DW |
194 | /** |
195 | * This enumeration provides a named phy type for the state machine | |
196 | * | |
197 | * | |
198 | */ | |
de728b7d | 199 | enum scic_sds_phy_protocol { |
6f231dda DW |
200 | /** |
201 | * This is an unknown phy type since there is either nothing on the other | |
202 | * end or we have not detected the phy type as yet. | |
203 | */ | |
204 | SCIC_SDS_PHY_PROTOCOL_UNKNOWN, | |
205 | ||
206 | /** | |
207 | * This is a SAS PHY | |
208 | */ | |
209 | SCIC_SDS_PHY_PROTOCOL_SAS, | |
210 | ||
211 | /** | |
212 | * This is a SATA PHY | |
213 | */ | |
214 | SCIC_SDS_PHY_PROTOCOL_SATA, | |
215 | ||
216 | SCIC_SDS_MAX_PHY_PROTOCOLS | |
217 | }; | |
218 | ||
e1e72a00 | 219 | struct isci_phy; |
6f231dda DW |
220 | /** |
221 | * struct scic_sds_phy - This structure contains or references all of the data | |
222 | * necessary to represent the core phy object and SCU harware protocol | |
223 | * engine. | |
224 | * | |
225 | * | |
226 | */ | |
227 | struct scic_sds_phy { | |
d857d9a0 | 228 | /** |
e1e72a00 | 229 | * This field depicts the peer object for the phy. |
d857d9a0 | 230 | */ |
e1e72a00 | 231 | struct isci_phy *iphy; |
d857d9a0 MT |
232 | |
233 | /** | |
234 | * This field contains the information for the base phy state machine. | |
235 | */ | |
236 | struct sci_base_state_machine state_machine; | |
6f231dda DW |
237 | |
238 | /** | |
239 | * This field specifies the port object that owns/contains this phy. | |
240 | */ | |
241 | struct scic_sds_port *owning_port; | |
242 | ||
243 | /** | |
244 | * This field indicates whether the phy supports 1.5 Gb/s, 3.0 Gb/s, | |
245 | * or 6.0 Gb/s operation. | |
246 | */ | |
26bace34 | 247 | enum sas_linkrate max_negotiated_speed; |
6f231dda DW |
248 | |
249 | /** | |
250 | * This member specifies the protocol being utilized on this phy. This | |
251 | * field contains a legitamite value once the PHY has link trained with | |
252 | * a remote phy. | |
253 | */ | |
de728b7d | 254 | enum scic_sds_phy_protocol protocol; |
6f231dda DW |
255 | |
256 | /** | |
257 | * This field specifies the index with which this phy is associated (0-3). | |
258 | */ | |
259 | u8 phy_index; | |
260 | ||
261 | /** | |
262 | * This member indicates if this particular PHY has received a BCN while | |
263 | * it had no port assignement. This BCN will be reported once the phy is | |
264 | * assigned to a port. | |
265 | */ | |
266 | bool bcn_received_while_port_unassigned; | |
267 | ||
268 | /** | |
269 | * This field indicates if this PHY is currently in the process of | |
270 | * link training (i.e. it has started OOB, but has yet to perform | |
271 | * IAF exchange/Signature FIS reception). | |
272 | */ | |
273 | bool is_in_link_training; | |
274 | ||
275 | union { | |
276 | struct { | |
277 | struct sci_sas_identify_address_frame identify_address_frame_buffer; | |
278 | ||
279 | } sas; | |
280 | ||
281 | struct { | |
f2f30080 | 282 | struct dev_to_host_fis signature_fis_buffer; |
6f231dda DW |
283 | |
284 | } sata; | |
285 | ||
286 | } phy_type; | |
287 | ||
288 | /** | |
289 | * This field contains a reference to the timer utilized in detecting | |
290 | * when a signature FIS timeout has occurred. The signature FIS is the | |
291 | * first FIS sent by an attached SATA device after OOB/SN. | |
292 | */ | |
293 | void *sata_timeout_timer; | |
294 | ||
8f31550c | 295 | const struct scic_sds_phy_state_handler *state_handlers; |
6f231dda DW |
296 | |
297 | struct sci_base_state_machine starting_substate_machine; | |
298 | ||
24621466 HD |
299 | /** |
300 | * This field is the pointer to the transport layer register for the SCU | |
301 | * hardware. | |
302 | */ | |
303 | struct scu_transport_layer_registers __iomem *transport_layer_registers; | |
304 | ||
6f231dda DW |
305 | /** |
306 | * This field points to the link layer register set within the SCU. | |
307 | */ | |
24621466 | 308 | struct scu_link_layer_registers __iomem *link_layer_registers; |
6f231dda DW |
309 | |
310 | }; | |
311 | ||
d857d9a0 | 312 | typedef enum sci_status (*scic_sds_phy_handler_t)(struct scic_sds_phy *); |
8f31550c DW |
313 | typedef enum sci_status (*scic_sds_phy_event_handler_t)(struct scic_sds_phy *, u32); |
314 | typedef enum sci_status (*scic_sds_phy_frame_handler_t)(struct scic_sds_phy *, u32); | |
315 | typedef enum sci_status (*scic_sds_phy_power_handler_t)(struct scic_sds_phy *); | |
6f231dda DW |
316 | |
317 | /** | |
318 | * struct scic_sds_phy_state_handler - | |
319 | * | |
320 | * | |
321 | */ | |
322 | struct scic_sds_phy_state_handler { | |
323 | /** | |
d857d9a0 MT |
324 | * The start_handler specifies the method invoked when there is an |
325 | * attempt to start a phy. | |
326 | */ | |
327 | scic_sds_phy_handler_t start_handler; | |
328 | ||
329 | /** | |
330 | * The stop_handler specifies the method invoked when there is an | |
331 | * attempt to stop a phy. | |
332 | */ | |
333 | scic_sds_phy_handler_t stop_handler; | |
334 | ||
335 | /** | |
336 | * The reset_handler specifies the method invoked when there is an | |
337 | * attempt to reset a phy. | |
338 | */ | |
339 | scic_sds_phy_handler_t reset_handler; | |
340 | ||
341 | /** | |
342 | * The destruct_handler specifies the method invoked when attempting to | |
343 | * destruct a phy. | |
6f231dda | 344 | */ |
d857d9a0 | 345 | scic_sds_phy_handler_t destruct_handler; |
6f231dda DW |
346 | |
347 | /** | |
348 | * The state handler for unsolicited frames received from the SCU hardware. | |
349 | */ | |
8f31550c | 350 | scic_sds_phy_frame_handler_t frame_handler; |
6f231dda DW |
351 | |
352 | /** | |
353 | * The state handler for events received from the SCU hardware. | |
354 | */ | |
8f31550c | 355 | scic_sds_phy_event_handler_t event_handler; |
6f231dda DW |
356 | |
357 | /** | |
358 | * The state handler for staggered spinup. | |
359 | */ | |
8f31550c | 360 | scic_sds_phy_power_handler_t consume_power_handler; |
6f231dda DW |
361 | |
362 | }; | |
363 | ||
6f231dda DW |
364 | /** |
365 | * scic_sds_phy_get_index() - | |
366 | * | |
367 | * This macro returns the phy index for the specified phy | |
368 | */ | |
369 | #define scic_sds_phy_get_index(phy) \ | |
370 | ((phy)->phy_index) | |
371 | ||
372 | /** | |
373 | * scic_sds_phy_get_controller() - This macro returns the controller for this | |
374 | * phy | |
375 | * | |
376 | * | |
377 | */ | |
378 | #define scic_sds_phy_get_controller(phy) \ | |
379 | (scic_sds_port_get_controller((phy)->owning_port)) | |
380 | ||
6f231dda DW |
381 | /** |
382 | * scic_sds_phy_set_state_handlers() - This macro sets the state handlers for | |
383 | * this phy object | |
384 | * | |
385 | * | |
386 | */ | |
387 | #define scic_sds_phy_set_state_handlers(phy, handlers) \ | |
388 | ((phy)->state_handlers = (handlers)) | |
389 | ||
390 | /** | |
391 | * scic_sds_phy_set_base_state_handlers() - | |
392 | * | |
393 | * This macro set the base state handlers for the phy object. | |
394 | */ | |
395 | #define scic_sds_phy_set_base_state_handlers(phy, state_id) \ | |
396 | scic_sds_phy_set_state_handlers(\ | |
397 | (phy), \ | |
398 | &scic_sds_phy_state_handler_table[(state_id)] \ | |
399 | ) | |
400 | ||
6f231dda DW |
401 | void scic_sds_phy_construct( |
402 | struct scic_sds_phy *this_phy, | |
403 | struct scic_sds_port *owning_port, | |
404 | u8 phy_index); | |
405 | ||
406 | struct scic_sds_port *scic_sds_phy_get_port( | |
407 | struct scic_sds_phy *this_phy); | |
408 | ||
409 | void scic_sds_phy_set_port( | |
410 | struct scic_sds_phy *this_phy, | |
411 | struct scic_sds_port *owning_port); | |
412 | ||
413 | enum sci_status scic_sds_phy_initialize( | |
414 | struct scic_sds_phy *this_phy, | |
24621466 HD |
415 | struct scu_transport_layer_registers __iomem *transport_layer_registers, |
416 | struct scu_link_layer_registers __iomem *link_layer_registers); | |
6f231dda DW |
417 | |
418 | enum sci_status scic_sds_phy_start( | |
419 | struct scic_sds_phy *this_phy); | |
420 | ||
421 | enum sci_status scic_sds_phy_stop( | |
422 | struct scic_sds_phy *this_phy); | |
423 | ||
424 | enum sci_status scic_sds_phy_reset( | |
425 | struct scic_sds_phy *this_phy); | |
426 | ||
6f231dda DW |
427 | void scic_sds_phy_resume( |
428 | struct scic_sds_phy *this_phy); | |
429 | ||
24621466 HD |
430 | void scic_sds_phy_setup_transport( |
431 | struct scic_sds_phy *this_phy, | |
432 | u32 device_id); | |
433 | ||
6f231dda DW |
434 | enum sci_status scic_sds_phy_event_handler( |
435 | struct scic_sds_phy *this_phy, | |
436 | u32 event_code); | |
437 | ||
438 | enum sci_status scic_sds_phy_frame_handler( | |
439 | struct scic_sds_phy *this_phy, | |
440 | u32 frame_index); | |
441 | ||
442 | enum sci_status scic_sds_phy_consume_power_handler( | |
443 | struct scic_sds_phy *this_phy); | |
444 | ||
445 | void scic_sds_phy_get_sas_address( | |
446 | struct scic_sds_phy *this_phy, | |
447 | struct sci_sas_address *sas_address); | |
448 | ||
449 | void scic_sds_phy_get_attached_sas_address( | |
450 | struct scic_sds_phy *this_phy, | |
451 | struct sci_sas_address *sas_address); | |
452 | ||
453 | void scic_sds_phy_get_protocols( | |
454 | struct scic_sds_phy *this_phy, | |
455 | struct sci_sas_identify_address_frame_protocols *protocols); | |
456 | ||
457 | void scic_sds_phy_get_attached_phy_protocols( | |
458 | struct scic_sds_phy *this_phy, | |
459 | struct sci_sas_identify_address_frame_protocols *protocols); | |
460 | ||
6f231dda | 461 | #endif /* _SCIC_SDS_PHY_H_ */ |