isci: Intel(R) C600 Series Chipset Storage Control Unit Driver
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / isci / core / scic_sds_port.h
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_PORT_H_
57 #define _SCIC_SDS_PORT_H_
58
59 /**
60  * This file contains the structures, constants and prototypes for the
61  *    struct scic_sds_port object.
62  *
63  *
64  */
65
66 #include "sci_controller_constants.h"
67 #include "intel_sas.h"
68 #include "sci_base_port.h"
69 #include "sci_base_phy.h"
70 #include "scu_registers.h"
71
72 #define SCIC_SDS_DUMMY_PORT   0xFF
73
74 /**
75  * enum SCIC_SDS_PORT_READY_SUBSTATES -
76  *
77  * This enumeration depicts all of the states for the core port ready substate
78  * machine.
79  */
80 enum SCIC_SDS_PORT_READY_SUBSTATES {
81         /**
82          * The substate where the port is started and ready but has no active phys.
83          */
84         SCIC_SDS_PORT_READY_SUBSTATE_WAITING,
85
86         /**
87          * The substate where the port is started and ready and there is at least one
88          * phy operational.
89          */
90         SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL,
91
92         /**
93          * The substate where the port is started and there was an add/remove phy
94          * event.  This state is only used in Automatic Port Configuration Mode (APC)
95          */
96         SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING,
97
98         SCIC_SDS_PORT_READY_MAX_SUBSTATES
99 };
100
101 struct scic_sds_controller;
102 struct scic_sds_phy;
103 struct scic_sds_remote_device;
104 struct scic_sds_request;
105
106 /**
107  * struct scic_sds_port -
108  *
109  * The core port object provides the the abstraction for an SCU port.
110  */
111 struct scic_sds_port {
112         /**
113          * This field is the oommon base port object.
114          */
115         struct sci_base_port parent;
116
117         /**
118          * This field is the port index that is reported to the SCI USER.  This allows
119          * the actual hardware physical port to change without the SCI USER getting a
120          * different answer for the get port index.
121          */
122         u8 logical_port_index;
123
124         /**
125          * This field is the port index used to program the SCU hardware.
126          */
127         u8 physical_port_index;
128
129         /**
130          * This field contains the active phy mask for the port.  This mask is used in
131          * conjunction with the phy state to determine which phy to select for some
132          * port operations.
133          */
134         u8 active_phy_mask;
135
136         /**
137          * This field contains the count of the io requests started on this port
138          * object.  It is used to control controller shutdown.
139          */
140         u32 started_request_count;
141
142         /**
143          * This field contains the number of devices assigned to this port.  It is
144          * used to control port start requests.
145          */
146         u32 assigned_device_count;
147
148         /**
149          * This field contains the reason for the port not going ready.  It is
150          * assigned in the state handlers and used in the state transition.
151          */
152         u32 not_ready_reason;
153
154         /**
155          * This field is the table of phys assigned to the port.
156          */
157         struct scic_sds_phy *phy_table[SCI_MAX_PHYS];
158
159         /**
160          * This field is a pointer back to the controller that owns this port object.
161          */
162         struct scic_sds_controller *owning_controller;
163
164         /**
165          * This field contains the port start/stop timer handle.
166          */
167         void *timer_handle;
168
169         /**
170          * This field points to the current set of state handlers for this port
171          * object.  These state handlers are assigned at each enter state of the state
172          * machine.
173          */
174         struct scic_sds_port_state_handler *state_handlers;
175
176         /**
177          * This field is the ready substate machine for the port.
178          */
179         struct sci_base_state_machine ready_substate_machine;
180
181         /* / Memory mapped hardware register space */
182         /**
183          * This field is the pointer to the transport layer register for the SCU
184          * hardware.
185          */
186         struct scu_transport_layer_registers *transport_layer_registers;
187
188         /**
189          * This field is the pointer to the port task scheduler registers for the SCU
190          * hardware.
191          */
192         struct scu_port_task_scheduler_registers *port_task_scheduler_registers;
193
194         /**
195          * This field is identical for all port objects and points to the port task
196          * scheduler group PE configuration registers.  It is used to assign PEs to a
197          * port.
198          */
199         SCU_PORT_PE_CONFIGURATION_REGISTER_T *port_pe_configuration_register;
200
201         /**
202          * This field is the VIIT register space for ths port object.
203          */
204         struct scu_viit_entry *viit_registers;
205
206 };
207
208
209 typedef enum sci_status (*SCIC_SDS_PORT_EVENT_HANDLER_T)(struct scic_sds_port *, u32);
210
211 typedef enum sci_status (*SCIC_SDS_PORT_FRAME_HANDLER_T)(struct scic_sds_port *, u32);
212
213 typedef void (*SCIC_SDS_PORT_LINK_HANDLER_T)(struct scic_sds_port *, struct scic_sds_phy *);
214
215 typedef enum sci_status (*SCIC_SDS_PORT_IO_REQUEST_HANDLER_T)(
216         struct scic_sds_port *,
217         struct scic_sds_remote_device *,
218         struct scic_sds_request *);
219
220 struct scic_sds_port_state_handler {
221         struct sci_base_port_state_handler parent;
222
223         SCIC_SDS_PORT_FRAME_HANDLER_T frame_handler;
224         SCIC_SDS_PORT_EVENT_HANDLER_T event_handler;
225
226         SCIC_SDS_PORT_LINK_HANDLER_T link_up_handler;
227         SCIC_SDS_PORT_LINK_HANDLER_T link_down_handler;
228
229         SCIC_SDS_PORT_IO_REQUEST_HANDLER_T start_io_handler;
230         SCIC_SDS_PORT_IO_REQUEST_HANDLER_T complete_io_handler;
231
232 };
233
234 extern const struct sci_base_state scic_sds_port_state_table[];
235 extern const struct sci_base_state scic_sds_port_ready_substate_table[];
236
237 extern struct scic_sds_port_state_handler scic_sds_port_state_handler_table[];
238 extern struct scic_sds_port_state_handler scic_sds_port_ready_substate_handler_table[];
239
240 /**
241  * scic_sds_port_get_controller() -
242  *
243  * Helper macro to get the owning controller of this port
244  */
245 #define scic_sds_port_get_controller(this_port) \
246         ((this_port)->owning_controller)
247
248 /**
249  * scic_sds_port_get_base_state_machine() -
250  *
251  * Helper macro to get the base state machine for this port
252  */
253 #define scic_sds_port_get_base_state_machine(this_port) \
254         (&(this_port)->parent.state_machine)
255
256 /**
257  * scic_sds_port_set_base_state_handlers() -
258  *
259  * This macro will change the state handlers to those of the specified state id
260  */
261 #define scic_sds_port_set_base_state_handlers(this_port, state_id) \
262         scic_sds_port_set_state_handlers(\
263                 (this_port), &scic_sds_port_state_handler_table[(state_id)])
264
265 /**
266  * scic_sds_port_get_ready_substate_machine() -
267  *
268  * Helper macro to get the ready substate machine for this port
269  */
270 #define scic_sds_port_get_ready_substate_machine(this_port) \
271         (&(this_port)->ready_substate_machine)
272
273 /**
274  * scic_sds_port_set_state_handlers() -
275  *
276  * Helper macro to set the port object state handlers
277  */
278 #define scic_sds_port_set_state_handlers(this_port, handlers) \
279         ((this_port)->state_handlers = (handlers))
280
281 /**
282  * scic_sds_port_get_index() -
283  *
284  * This macro returns the physical port index for this port object
285  */
286 #define scic_sds_port_get_index(this_port) \
287         ((this_port)->physical_port_index)
288
289 /**
290  * scic_sds_port_increment_request_count() -
291  *
292  * Helper macro to increment the started request count
293  */
294 #define scic_sds_port_increment_request_count(this_port) \
295         ((this_port)->started_request_count++)
296
297 #ifdef SCIC_DEBUG_ENABLED
298 /**
299  * scic_sds_port_decrement_request_count() - This method decrements the started
300  *    io request count.  The method will not decrment the started io request
301  *    count below 0 and will log a debug message if this is attempted.
302  *
303  *
304  */
305 void scic_sds_port_decrement_request_count(
306         struct scic_sds_port *this_port);
307 #else
308 /**
309  * scic_sds_port_decrement_request_count() -
310  *
311  * Helper macro to decrement the started io request count.  The macro will not
312  * decrement the started io request count below 0.
313  */
314 #define scic_sds_port_decrement_request_count(this_port) \
315         (\
316                 (this_port)->started_request_count = (\
317                         ((this_port)->started_request_count == 0) ? \
318                         (this_port)->started_request_count : \
319                         ((this_port)->started_request_count - 1) \
320                         ) \
321                         )
322 #endif
323
324 /**
325  * scic_sds_port_write_phy_assignment() -
326  *
327  * Helper macro to write the phys port assignment
328  */
329 #define scic_sds_port_write_phy_assignment(port, phy) \
330         SCU_PCSPExCR_WRITE(\
331                 (port), \
332                 (phy)->phy_index, \
333                 (port)->physical_port_index \
334                 )
335
336 /**
337  * scic_sds_port_read_phy_assignment() -
338  *
339  * Helper macro to read the phys port assignment
340  */
341 #define scic_sds_port_read_phy_assignment(port, phy) \
342         SCU_PCSPExCR_READ(\
343                 (port), \
344                 (phy)->phy_index \
345                 )
346
347 #define scic_sds_port_active_phy(port, phy) \
348         (((port)->active_phy_mask & (1 << (phy)->phy_index)) != 0)
349
350 /* --------------------------------------------------------------------------- */
351
352
353
354
355 /* --------------------------------------------------------------------------- */
356
357 /* --------------------------------------------------------------------------- */
358
359 void scic_sds_port_construct(
360         struct scic_sds_port *this_port,
361         u8 port_index,
362         struct scic_sds_controller *owning_controller);
363
364 enum sci_status scic_sds_port_initialize(
365         struct scic_sds_port *this_port,
366         void *transport_layer_registers,
367         void *port_task_scheduler_registers,
368         void *port_configuration_regsiter,
369         void *viit_registers);
370
371 /* --------------------------------------------------------------------------- */
372
373 enum sci_status scic_sds_port_add_phy(
374         struct scic_sds_port *this_port,
375         struct scic_sds_phy *the_phy);
376
377 enum sci_status scic_sds_port_remove_phy(
378         struct scic_sds_port *this_port,
379         struct scic_sds_phy *the_phy);
380
381 void scic_sds_port_set_direct_attached_device_id(
382         struct scic_sds_port *this_port,
383         u32 device_id);
384
385 void scic_sds_port_activate_phy(
386         struct scic_sds_port *this_port,
387         struct scic_sds_phy *phy,
388         bool do_notify_user);
389
390 void scic_sds_port_deactivate_phy(
391         struct scic_sds_port *this_port,
392         struct scic_sds_phy *phy,
393         bool do_notify_user);
394
395
396
397 void scic_sds_port_general_link_up_handler(
398         struct scic_sds_port *this_port,
399         struct scic_sds_phy *the_phy,
400         bool do_notify_user);
401
402 bool scic_sds_port_link_detected(
403         struct scic_sds_port *this_port,
404         struct scic_sds_phy *phy);
405
406 void scic_sds_port_link_up(
407         struct scic_sds_port *this_port,
408         struct scic_sds_phy *phy);
409
410 void scic_sds_port_link_down(
411         struct scic_sds_port *this_port,
412         struct scic_sds_phy *phy);
413
414 /* --------------------------------------------------------------------------- */
415
416
417 /* --------------------------------------------------------------------------- */
418
419 enum sci_status scic_sds_port_start_io(
420         struct scic_sds_port *this_port,
421         struct scic_sds_remote_device *the_device,
422         struct scic_sds_request *the_io_request);
423
424 enum sci_status scic_sds_port_complete_io(
425         struct scic_sds_port *this_port,
426         struct scic_sds_remote_device *the_device,
427         struct scic_sds_request *the_io_request);
428
429 /* --------------------------------------------------------------------------- */
430
431 void scic_sds_port_update_viit_entry(
432         struct scic_sds_port *this_port);
433
434 /* --------------------------------------------------------------------------- */
435
436 enum sci_status scic_sds_port_default_start_handler(
437         struct sci_base_port *port);
438
439
440 enum sci_status scic_sds_port_default_destruct_handler(
441         struct sci_base_port *port);
442
443 enum sci_status scic_sds_port_default_reset_handler(
444         struct sci_base_port *port,
445         u32 timeout);
446
447
448 enum sci_status scic_sds_port_default_remove_phy_handler(
449         struct sci_base_port *port,
450         struct sci_base_phy *phy);
451
452 enum sci_status scic_sds_port_default_frame_handler(
453         struct scic_sds_port *port,
454         u32 frame_index);
455
456 enum sci_status scic_sds_port_default_event_handler(
457         struct scic_sds_port *port,
458         u32 event_code);
459
460 void scic_sds_port_default_link_up_handler(
461         struct scic_sds_port *this_port,
462         struct scic_sds_phy *phy);
463
464 void scic_sds_port_default_link_down_handler(
465         struct scic_sds_port *this_port,
466         struct scic_sds_phy *phy);
467
468 enum sci_status scic_sds_port_default_start_io_handler(
469         struct scic_sds_port *port,
470         struct scic_sds_remote_device *device,
471         struct scic_sds_request *io_request);
472
473
474 enum sci_sas_link_rate scic_sds_port_get_max_allowed_speed(
475         struct scic_sds_port *this_port);
476
477 void scic_sds_port_broadcast_change_received(
478         struct scic_sds_port *this_port,
479         struct scic_sds_phy *this_phy);
480
481 bool scic_sds_port_is_valid_phy_assignment(
482         struct scic_sds_port *this_port,
483         u32 phy_index);
484
485 bool scic_sds_port_is_phy_mask_valid(
486         struct scic_sds_port *this_port,
487         u32 phy_mask);
488
489 u32 scic_sds_port_get_phys(
490         struct scic_sds_port *this_port);
491
492 void scic_sds_port_get_sas_address(
493         struct scic_sds_port *this_port,
494         struct sci_sas_address *sas_address);
495
496 void scic_sds_port_get_attached_sas_address(
497         struct scic_sds_port *this_port,
498         struct sci_sas_address *sas_address);
499
500 void scic_sds_port_get_attached_protocols(
501         struct scic_sds_port *this_port,
502         struct sci_sas_identify_address_frame_protocols *protocols);
503
504 enum sci_status scic_sds_port_set_phy(
505         struct scic_sds_port *port,
506         struct scic_sds_phy *phy);
507
508 enum sci_status scic_sds_port_clear_phy(
509         struct scic_sds_port *port,
510         struct scic_sds_phy *phy);
511
512
513
514 #endif /* _SCIC_SDS_PORT_H_ */