1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3  *
4  * This file is provided under a dual BSD/GPLv2 license.  When using or
5  * redistributing this file, you may do so under either license.
6  *
7  * GPL LICENSE SUMMARY
8  *
9  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of version 2 of the GNU General Public License as
13  * published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23  * The full GNU General Public License is included in this distribution
24  * in the file called LICENSE.GPL.
25  *
26  * BSD LICENSE
27  *
28  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29  * All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  *
35  *   * Redistributions of source code must retain the above copyright
36  *     notice, this list of conditions and the following disclaimer.
37  *   * Redistributions in binary form must reproduce the above copyright
38  *     notice, this list of conditions and the following disclaimer in
39  *     the documentation and/or other materials provided with the
40  *     distribution.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53  *
54  * $FreeBSD$
55  */
56 #ifndef _SCIF_SAS_SMP_REMOTE_DEVICE_H_
57 #define _SCIF_SAS_SMP_REMOTE_DEVICE_H_
58 
59 #ifdef __cplusplus
60 extern "C" {
61 #endif // __cplusplus
62 
63 
64 #include <dev/isci/scil/sci_fast_list.h>
65 #include <dev/isci/scil/scif_sas_smp_phy.h>
66 
67 /**
68  * @file
69  *
70  * @brief This file contains the protected interface structures, constants,
71  *        and methods for the SCIF_SAS_SMP_REMOTE_DEVICE object.
72  */
73 
74 struct SCIF_SAS_CONTROLLER;
75 struct SCIF_SAS_REMOTE_DEVICE;
76 struct SCIF_SAS_INTERNAL_IO_REQUEST;
77 struct SCIF_SAS_REQUEST;
78 struct SCIF_SAS_SMP_PHY;
79 
80 #define SMP_REQUEST_RETRY_WAIT_DURATION   20
81 #define SMP_SPINUP_HOLD_RELEASE_WAIT_DURATION 100
82 
83 /**
84  * @name SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CODES
85  *
86  * These constants depict the various SMP remote device activities.
87  */
88 /*@{*/
89 #define NOT_IN_SMP_ACTIVITY 0xff
90 #define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_NONE         0x0
91 #define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_DISCOVER     0x1
92 #define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET 0x2
93 #define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_SATA_SPINUP_HOLD_RELEASE 0x3
94 #define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CONFIG_ROUTE_TABLE 0x4
95 #define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CLEAN_ROUTE_TABLE 0x5
96 #define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CLEAR_AFFILIATION 0x6
97 /*@}*/
98 
99 
100 
101 /**
102  * @name SCIF_SAS_CONFIG_ROUTE_TABLE_OPTION_CODES
103  *
104  * These constants depict the various configure route table options.
105  */
106 /*@{*/
107 #define SCIF_SAS_CONFIG_ROUTE_TABLE_LOWEST_PHY_ONLY   0
108 #define SCIF_SAS_CONFIG_ROUTE_TABLE_MIDDLE_PHY_ONLY   1
109 #define SCIF_SAS_CONFIG_ROUTE_TABLE_HIGHEST_PHY_ONLY  2
110 #define SCIF_SAS_CONFIG_ROUTE_TABLE_ALL_PHYS          3
111 /*@}*/
112 
113 /**
114  * @struct SCIF_SAS_SMP_REMOTE_DEVICE
115  *
116  * @brief The SCIF_SAS_SMP_REMOTE_DEVICE stores data for smp remote devices
117  *        (expanders) discovering attached targets.
118  *
119  */
120 typedef struct SCIF_SAS_SMP_REMOTE_DEVICE
121 {
122    /**
123     * This field stores the current SMP request function in the discovering
124     * sequence.
125     */
126    U32 current_smp_request;
127 
128    /**
129     * This field indicates a smp device is either in the middle of normal discover
130     * process or in the middle of resetting a expander attahced remote device.
131     */
132    U8 current_activity;
133 
134    /**
135     * This field stores the current expander phy index for sending out SMP
136     * DISCOVER request.
137     */
138    U8 current_activity_phy_index;
139 
140    /**
141     * This field stores the current route index to config route table for
142     * a phy.
143     */
144    U16 curr_config_route_index;
145 
146    /**
147     * This field indicates whether a route table of an expander has been cleaned
148     * since a DISCOVER process starts.
149     */
150    BOOL is_route_table_cleaned;
151 
152    /**
153     * This field stores the smp phy whose route entries are edited by sending
154     * CONFIG ROUTE INFO commands.
155     */
156    struct SCIF_SAS_SMP_PHY * config_route_smp_phy_anchor;
157 
158    /*
159     * This field stores the current smp phy on a destination device's smp phy list whose
160     * attached device's sas address is to be edited into this smp device's route table.
161     * When one config route info response is processed, we can find the next smp phy to edit
162     * using this field's value.
163     */
164    struct SCIF_SAS_SMP_PHY * curr_config_route_destination_smp_phy;
165 
166    /*
167     * This field stores the current smp phy to which a PHY CONTROL (clear affiliation)
168     * command is sent out.
169     */
170    struct SCIF_SAS_SMP_PHY * curr_clear_affiliation_phy;
171 
172    /**
173     * This field is to indicate a smp activity for this smp device is
174     * to be started (not yet). The scheduled activity could be Discover or Config
175     * Route Table.
176     */
177    U8 scheduled_activity;
178 
179    /**
180     * This timer is used for waiting before retrying a smp request, or before
181     * sending Discover request after Phy Control during Target Reset.
182     */
183    void * smp_activity_timer;
184 
185    /**
186     * This field save the retry count for internal smp request. Since when
187     * an internal smp request gets retried, it has been destructed already.
188     */
189    U8 io_retry_count;
190 
191    /**
192     * This field stores the number of phys for expander device found by decoding
193     * the SMP REPORT GENERAL response.
194     */
195    U8  number_of_phys;
196 
197    /**
198     * This field indicates the maximum number of expander route indexes per phy for
199     * this expander device.
200     */
201    U16 expander_route_indexes;
202 
203    /**
204     * This field indicates whether an expander device supports table-to-table
205     * connection.
206     */
207    BOOL is_table_to_table_supported;
208 
209    /**
210     * This field indicates whether an expander device is externally configurable.
211     * If it is, it is not self-configuring and is not able to config others.
212     */
213    BOOL is_externally_configurable;
214 
215    /**
216     * This field indicates whether an expander device is able to config others.
217     */
218    BOOL is_able_to_config_others;
219 
220    /**
221     * This field contains the list of all smp phys that connect to another smp phy.
222     */
223    SCI_FAST_LIST_T smp_phy_list;
224 
225 }SCIF_SAS_SMP_REMOTE_DEVICE_T;
226 
227 void scif_sas_smp_remote_device_clear(
228    struct SCIF_SAS_REMOTE_DEVICE * fw_device
229 );
230 
231 void scif_sas_smp_remote_device_construct(
232    struct SCIF_SAS_REMOTE_DEVICE * fw_device
233 );
234 
235 SCI_STATUS scif_sas_smp_remote_device_decode_smp_response(
236    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
237    struct SCIF_SAS_REQUEST       * fw_request,
238    void                          * response_data,
239    SCI_IO_STATUS                   completion_status
240 );
241 
242 SCI_STATUS scif_sas_smp_remote_device_decode_report_general_response(
243    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
244    SMP_RESPONSE_T                * smp_response
245 );
246 
247 SCI_STATUS scif_sas_smp_remote_device_decode_initial_discover_response(
248    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
249    SMP_RESPONSE_T                * smp_response
250 );
251 
252 SCI_STATUS scif_sas_smp_remote_device_decode_report_phy_sata_response(
253    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
254    SMP_RESPONSE_T                * smp_response
255 );
256 
257 SCI_STATUS scif_sas_smp_remote_device_decode_target_reset_phy_control_response(
258    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
259    SMP_RESPONSE_T           * smp_response
260 );
261 
262 SCI_STATUS scif_sas_smp_remote_device_decode_discover_phy_control_response(
263    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
264    SMP_RESPONSE_T           * smp_response
265 );
266 
267 SCI_STATUS scif_sas_smp_remote_device_decode_target_reset_discover_response(
268    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
269    SMP_RESPONSE_T           * smp_response
270 );
271 
272 SCI_STATUS scif_sas_smp_remote_device_decode_spinup_hold_release_discover_response(
273    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
274    SMP_RESPONSE_T           * smp_response
275 );
276 
277 SCI_STATUS scif_sas_smp_remote_device_decode_config_route_info_response(
278    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
279    SMP_RESPONSE_T           * smp_response
280 );
281 
282 void scif_sas_smp_remote_device_start_discover(
283    struct SCIF_SAS_REMOTE_DEVICE * fw_device
284 );
285 
286 void scif_sas_smp_remote_device_continue_discover(
287    struct SCIF_SAS_REMOTE_DEVICE * fw_device
288 );
289 
290 void scif_sas_smp_remote_device_finish_initial_discover(
291    struct SCIF_SAS_REMOTE_DEVICE * fw_device
292 );
293 
294 void scif_sas_smp_remote_device_finish_discover(
295    struct SCIF_SAS_REMOTE_DEVICE * fw_device
296 );
297 
298 void scif_sas_smp_remote_device_continue_target_reset(
299    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
300    struct SCIF_SAS_REQUEST       * fw_request
301 );
302 
303 void scif_sas_smp_remote_device_fail_discover(
304    struct SCIF_SAS_REMOTE_DEVICE * fw_device
305 );
306 
307 void scif_sas_smp_remote_device_fail_target_reset(
308    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
309    struct SCIF_SAS_REQUEST       * fw_request
310 );
311 
312 void scif_sas_smp_remote_device_continue_current_activity(
313    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
314    struct SCIF_SAS_REQUEST       * fw_request,
315    SCI_STATUS                      status
316 );
317 
318 void scif_sas_smp_remote_device_target_reset_poll(
319    struct SCIF_SAS_REQUEST       * fw_request
320 );
321 
322 void scif_sas_smp_remote_device_sata_spinup_hold_release(
323    struct SCIF_SAS_REMOTE_DEVICE * fw_device
324 );
325 
326 void scif_sas_smp_remote_device_fail_target_spinup_hold_release(
327    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
328    struct SCIF_SAS_REMOTE_DEVICE * target_device
329 );
330 
331 void scif_sas_smp_remote_device_retry_internal_io(
332    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
333    U8                         io_retry_count,
334    U32                        delay
335 );
336 
337 BOOL scif_sas_smp_remote_device_is_in_activity(
338    struct SCIF_SAS_REMOTE_DEVICE * fw_device
339 );
340 
341 SCIF_SAS_SMP_PHY_T * scif_sas_smp_remote_device_find_smp_phy_by_id(
342    U8                                  phy_identifier,
343    struct SCIF_SAS_SMP_REMOTE_DEVICE * smp_remote_device
344 );
345 
346 void scif_sas_smp_remote_device_removed(
347    struct SCIF_SAS_REMOTE_DEVICE * this_device
348 );
349 
350 void scif_sas_smp_remote_device_terminated_request_handler(
351    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
352    struct SCIF_SAS_REQUEST       * fw_request
353 );
354 
355 void scif_sas_smp_remote_device_populate_smp_phy_list(
356    struct SCIF_SAS_REMOTE_DEVICE * fw_device
357 );
358 
359 SCI_STATUS scif_sas_smp_remote_device_save_smp_phy_info(
360    struct SCIF_SAS_REMOTE_DEVICE * fw_device,
361    SMP_RESPONSE_DISCOVER_T       * discover_response
362 );
363 
364 #ifdef SCI_SMP_PHY_LIST_DEBUG_PRINT
365 void scif_sas_smp_remote_device_print_smp_phy_list(
366    struct SCIF_SAS_REMOTE_DEVICE * fw_device
367 );
368 #endif
369 
370 void scif_sas_smp_remote_device_configure_upstream_expander_route_info(
371    struct SCIF_SAS_REMOTE_DEVICE * this_device
372 );
373 
374 struct SCIF_SAS_REMOTE_DEVICE * scif_sas_remote_device_find_upstream_expander(
375    struct SCIF_SAS_REMOTE_DEVICE * this_device
376 );
377 
378 struct SCIF_SAS_REMOTE_DEVICE * scif_sas_remote_device_find_downstream_expander(
379    struct SCIF_SAS_REMOTE_DEVICE * this_device
380 );
381 
382 BOOL scif_sas_smp_remote_device_do_config_route_info(
383    struct SCIF_SAS_REMOTE_DEVICE * device_being_config,
384    struct SCIF_SAS_SMP_PHY       * destination_smp_phy
385 );
386 
387 void scif_sas_smp_remote_device_configure_route_table(
388    struct SCIF_SAS_REMOTE_DEVICE * device_being_config
389 );
390 
391 void scif_sas_smp_remote_device_clean_route_table(
392    struct SCIF_SAS_REMOTE_DEVICE * fw_device
393 );
394 
395 void scif_sas_smp_remote_device_clean_route_table_entry(
396    struct SCIF_SAS_REMOTE_DEVICE * fw_device
397 );
398 
399 void scif_sas_smp_remote_device_cancel_config_route_table_activity(
400    struct SCIF_SAS_REMOTE_DEVICE * fw_device
401 );
402 
403 void scif_sas_smp_remote_device_cancel_smp_activity(
404    struct SCIF_SAS_REMOTE_DEVICE * fw_device
405 );
406 
407 U8 scif_sas_smp_remote_device_get_config_route_table_method(
408    struct SCIF_SAS_REMOTE_DEVICE * fw_device
409 );
410 
411 void scif_sas_smp_remote_device_start_clear_affiliation(
412    struct SCIF_SAS_REMOTE_DEVICE * fw_device
413 );
414 
415 void scif_sas_smp_remote_device_continue_clear_affiliation(
416    struct SCIF_SAS_REMOTE_DEVICE * fw_device
417 );
418 
419 void scif_sas_smp_remote_device_finish_clear_affiliation(
420    struct SCIF_SAS_REMOTE_DEVICE * fw_device
421 );
422 
423 void scif_sas_smp_remote_device_start_target_reset(
424    struct SCIF_SAS_REMOTE_DEVICE * expander_device,
425    struct SCIF_SAS_REMOTE_DEVICE * target_device,
426    struct SCIF_SAS_REQUEST       * fw_request
427 );
428 
429 #ifdef __cplusplus
430 }
431 #endif // __cplusplus
432 
433 #endif // _SCIF_SAS_SMP_REMOTE_DEVICE_H_
434