scic_sds_port.h revision 330897
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: stable/11/sys/dev/isci/scil/scic_sds_port.h 330897 2018-03-14 03:19:51Z eadler $ 55 */ 56#ifndef _SCIC_SDS_PORT_H_ 57#define _SCIC_SDS_PORT_H_ 58 59#ifdef __cplusplus 60extern "C" { 61#endif // __cplusplus 62 63/** 64 * @file 65 * 66 * @brief This file contains the structures, constants and prototypes for the 67 * SCIC_SDS_PORT_T object. 68 */ 69 70#include <dev/isci/scil/sci_controller_constants.h> 71#include <dev/isci/scil/intel_sas.h> 72#include <dev/isci/scil/sci_base_port.h> 73#include <dev/isci/scil/sci_base_phy.h> 74#include <dev/isci/scil/scu_registers.h> 75 76#define SCIC_SDS_DUMMY_PORT 0xFF 77 78/** 79 * @enum SCIC_SDS_PORT_READY_SUBSTATES 80 * 81 * This enumeration depicts all of the states for the core port ready substate 82 * machine. 83 */ 84enum SCIC_SDS_PORT_READY_SUBSTATES 85{ 86 /** 87 * The substate where the port is started and ready but has no active phys. 88 */ 89 SCIC_SDS_PORT_READY_SUBSTATE_WAITING, 90 91 /** 92 * The substate where the port is started and ready and there is at least one 93 * phy operational. 94 */ 95 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL, 96 97 /** 98 * The substate where the port is started and there was an add/remove phy 99 * event. This state is only used in Automatic Port Configuration Mode (APC) 100 */ 101 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING, 102 103 SCIC_SDS_PORT_READY_MAX_SUBSTATES 104}; 105 106struct SCIC_SDS_CONTROLLER; 107struct SCIC_SDS_PHY; 108struct SCIC_SDS_REMOTE_DEVICE; 109struct SCIC_SDS_REQUEST; 110 111/** 112 * @struct SCIC_SDS_PORT 113 * 114 * The core port object provides the abstraction for an SCU port. 115 */ 116typedef struct SCIC_SDS_PORT 117{ 118 /** 119 * This field is the oommon base port object. 120 */ 121 SCI_BASE_PORT_T parent; 122 123 /** 124 * This field is the port index that is reported to the SCI USER. This allows 125 * the actual hardware physical port to change without the SCI USER getting a 126 * different answer for the get port index. 127 */ 128 U8 logical_port_index; 129 130 /** 131 * This field is the port index used to program the SCU hardware. 132 */ 133 U8 physical_port_index; 134 135 /** 136 * This field contains the active phy mask for the port. This mask is used in 137 * conjunction with the phy state to determine which phy to select for some 138 * port operations. 139 */ 140 U8 active_phy_mask; 141 142 /** 143 * This field contains the phy mask for the port that are already part of the port. 144 */ 145 U8 enabled_phy_mask; 146 147 U16 reserved_rni; 148 U16 reserved_tci; 149 150 /** 151 * This field contains the count of the io requests started on this port 152 * object. It is used to control controller shutdown. 153 */ 154 U32 started_request_count; 155 156 /** 157 * This field contains the number of devices assigned to this port. It is 158 * used to control port start requests. 159 */ 160 U32 assigned_device_count; 161 162 /** 163 * This field contains the reason for the port not going ready. It is 164 * assigned in the state handlers and used in the state transition. 165 */ 166 U32 not_ready_reason; 167 168 /** 169 * This field is the table of phys assigned to the port. 170 */ 171 struct SCIC_SDS_PHY *phy_table[SCI_MAX_PHYS]; 172 173 /** 174 * This field is a pointer back to the controller that owns this port object. 175 */ 176 struct SCIC_SDS_CONTROLLER *owning_controller; 177 178 /** 179 * This field contains the port start/stop timer handle. 180 */ 181 void *timer_handle; 182 183 /** 184 * This field points to the current set of state handlers for this port 185 * object. These state handlers are assigned at each enter state of the state 186 * machine. 187 */ 188 struct SCIC_SDS_PORT_STATE_HANDLER *state_handlers; 189 190 /** 191 * This field is the ready substate machine for the port. 192 */ 193 SCI_BASE_STATE_MACHINE_T ready_substate_machine; 194 195 #ifdef SCI_LOGGING 196 /** 197 * This field is the ready substate machine logger. It logs each state 198 * transition request in the ready substate machine. 199 */ 200 SCI_BASE_STATE_MACHINE_LOGGER_T ready_substate_machine_logger; 201 #endif 202 203 /// Memory mapped hardware register space 204 205 /** 206 * This field is the pointer to the port task scheduler registers for the SCU 207 * hardware. 208 */ 209 SCU_PORT_TASK_SCHEDULER_REGISTERS_T *port_task_scheduler_registers; 210 211 /** 212 * This field is identical for all port objects and points to the port task 213 * scheduler group PE configuration registers. It is used to assign PEs to a 214 * port. 215 */ 216 SCU_PORT_PE_CONFIGURATION_REGISTER_T *port_pe_configuration_register; 217 218 /** 219 * This field is the VIIT register space for this port object. 220 */ 221 SCU_VIIT_ENTRY_T *viit_registers; 222 223} SCIC_SDS_PORT_T; 224 225 226typedef SCI_STATUS (*SCIC_SDS_PORT_EVENT_HANDLER_T)(struct SCIC_SDS_PORT *, U32); 227 228typedef SCI_STATUS (*SCIC_SDS_PORT_FRAME_HANDLER_T)(struct SCIC_SDS_PORT *, U32); 229 230typedef void (*SCIC_SDS_PORT_LINK_HANDLER_T)(struct SCIC_SDS_PORT *, struct SCIC_SDS_PHY *); 231 232typedef SCI_STATUS (*SCIC_SDS_PORT_IO_REQUEST_HANDLER_T)( 233 struct SCIC_SDS_PORT *, 234 struct SCIC_SDS_REMOTE_DEVICE *, 235 struct SCIC_SDS_REQUEST *); 236 237typedef struct SCIC_SDS_PORT_STATE_HANDLER 238{ 239 SCI_BASE_PORT_STATE_HANDLER_T parent; 240 241 SCIC_SDS_PORT_FRAME_HANDLER_T frame_handler; 242 SCIC_SDS_PORT_EVENT_HANDLER_T event_handler; 243 244 SCIC_SDS_PORT_LINK_HANDLER_T link_up_handler; 245 SCIC_SDS_PORT_LINK_HANDLER_T link_down_handler; 246 247 SCIC_SDS_PORT_IO_REQUEST_HANDLER_T start_io_handler; 248 SCIC_SDS_PORT_IO_REQUEST_HANDLER_T complete_io_handler; 249 250} SCIC_SDS_PORT_STATE_HANDLER_T; 251 252extern SCI_BASE_STATE_T scic_sds_port_state_table[]; 253extern SCI_BASE_STATE_T scic_sds_port_ready_substate_table[]; 254 255extern SCIC_SDS_PORT_STATE_HANDLER_T scic_sds_port_state_handler_table[]; 256extern SCIC_SDS_PORT_STATE_HANDLER_T scic_sds_port_ready_substate_handler_table[]; 257 258/** 259 * Helper macro to get the owning controller of this port 260 */ 261#define scic_sds_port_get_controller(this_port) \ 262 ((this_port)->owning_controller) 263 264/** 265 * Helper macro to get the base state machine for this port 266 */ 267#define scic_sds_port_get_base_state_machine(this_port) \ 268 (&(this_port)->parent.state_machine) 269 270/** 271 * This macro will change the state handlers to those of the specified state 272 * id 273 */ 274#define scic_sds_port_set_base_state_handlers(this_port, state_id) \ 275 scic_sds_port_set_state_handlers( \ 276 (this_port), &scic_sds_port_state_handler_table[(state_id)]) 277 278/** 279 * Helper macro to get the ready substate machine for this port 280 */ 281#define scic_sds_port_get_ready_substate_machine(this_port) \ 282 (&(this_port)->ready_substate_machine) 283 284/** 285 * Helper macro to set the port object state handlers 286 */ 287#define scic_sds_port_set_state_handlers(this_port, handlers) \ 288 ((this_port)->state_handlers = (handlers)) 289 290/** 291 * This macro returns the physical port index for this port object 292 */ 293#define scic_sds_port_get_index(this_port) \ 294 ((this_port)->physical_port_index) 295 296/** 297 * Helper macro to increment the started request count 298 */ 299#define scic_sds_port_increment_request_count(this_port) \ 300 ((this_port)->started_request_count++) 301 302#ifdef SCIC_DEBUG_ENABLED 303/** 304 * @brief This method decrements the started io request count. The method 305 * will not decrment the started io request count below 0 and will 306 * log a debug message if this is attempted. 307 * 308 * @param[in] this_port 309 */ 310void scic_sds_port_decrement_request_count( 311 SCIC_SDS_PORT_T *this_port 312); 313#else 314/** 315 * Helper macro to decrement the started io request count. The macro will 316 * not decrement the started io request count below 0. 317 */ 318#define scic_sds_port_decrement_request_count(this_port) \ 319 ( \ 320 (this_port)->started_request_count = ( \ 321 ((this_port)->started_request_count == 0) ? \ 322 (this_port)->started_request_count : \ 323 ((this_port)->started_request_count - 1) \ 324 ) \ 325 ) 326#endif 327 328/** 329 * Helper macro to write the phys port assignment 330 */ 331#define scic_sds_port_write_phy_assignment(port, phy) \ 332 SCU_PCSPExCR_WRITE( \ 333 (port), \ 334 (phy)->phy_index, \ 335 (port)->physical_port_index \ 336 ) 337 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 352U32 scic_sds_port_get_object_size(void); 353 354U32 scic_sds_port_get_min_timer_count(void); 355 356U32 scic_sds_port_get_max_timer_count(void); 357 358// --------------------------------------------------------------------------- 359 360#ifdef SCI_LOGGING 361void scic_sds_port_initialize_state_logging( 362 SCIC_SDS_PORT_T *this_port 363); 364#else 365#define scic_sds_port_initialize_state_logging(x) 366#endif 367 368// --------------------------------------------------------------------------- 369 370void scic_sds_port_construct( 371 SCIC_SDS_PORT_T *this_port, 372 U8 port_index, 373 struct SCIC_SDS_CONTROLLER *owning_controller 374); 375 376SCI_STATUS scic_sds_port_initialize( 377 SCIC_SDS_PORT_T *this_port, 378 void *port_task_scheduler_registers, 379 void *port_configuration_regsiter, 380 void *viit_registers 381); 382 383// --------------------------------------------------------------------------- 384 385SCI_STATUS scic_sds_port_add_phy( 386 struct SCIC_SDS_PORT * this_port, 387 struct SCIC_SDS_PHY * the_phy 388); 389 390SCI_STATUS scic_sds_port_remove_phy( 391 struct SCIC_SDS_PORT * this_port, 392 struct SCIC_SDS_PHY * the_phy 393); 394 395void scic_sds_port_setup_transports( 396 SCIC_SDS_PORT_T * this_port, 397 U32 device_id 398); 399 400void scic_sds_port_activate_phy( 401 SCIC_SDS_PORT_T *this_port, 402 struct SCIC_SDS_PHY *phy, 403 BOOL do_notify_user, 404 BOOL do_resume_phy 405); 406 407void scic_sds_port_deactivate_phy( 408 SCIC_SDS_PORT_T *this_port, 409 struct SCIC_SDS_PHY *phy, 410 BOOL do_notify_user 411); 412 413struct SCIC_SDS_PHY * scic_sds_port_get_a_connected_phy( 414 SCIC_SDS_PORT_T * this_port 415); 416 417void scic_sds_port_invalid_link_up( 418 SCIC_SDS_PORT_T *this_port, 419 struct SCIC_SDS_PHY *phy 420); 421 422void scic_sds_port_general_link_up_handler( 423 SCIC_SDS_PORT_T *this_port, 424 struct SCIC_SDS_PHY *the_phy, 425 BOOL do_notify_user, 426 BOOL do_resume_phy 427); 428 429BOOL scic_sds_port_link_detected( 430 SCIC_SDS_PORT_T *this_port, 431 struct SCIC_SDS_PHY *phy 432); 433 434void scic_sds_port_link_up( 435 SCIC_SDS_PORT_T *this_port, 436 struct SCIC_SDS_PHY *phy 437); 438 439void scic_sds_port_link_down( 440 SCIC_SDS_PORT_T *this_port, 441 struct SCIC_SDS_PHY *phy 442); 443 444// --------------------------------------------------------------------------- 445 446void scic_sds_port_timeout_handler( 447 void *port 448); 449 450// --------------------------------------------------------------------------- 451 452SCI_STATUS scic_sds_port_start_io( 453 SCIC_SDS_PORT_T *this_port, 454 struct SCIC_SDS_REMOTE_DEVICE *the_device, 455 struct SCIC_SDS_REQUEST *the_io_request 456); 457 458SCI_STATUS scic_sds_port_complete_io( 459 SCIC_SDS_PORT_T *this_port, 460 struct SCIC_SDS_REMOTE_DEVICE *the_device, 461 struct SCIC_SDS_REQUEST *the_io_request 462); 463 464// --------------------------------------------------------------------------- 465 466void scic_sds_port_update_viit_entry( 467 SCIC_SDS_PORT_T *this_port 468); 469 470// --------------------------------------------------------------------------- 471 472SCI_STATUS scic_sds_port_default_start_handler( 473 SCI_BASE_PORT_T *port 474); 475 476SCI_STATUS scic_sds_port_default_stop_handler( 477 SCI_BASE_PORT_T *port 478); 479 480SCI_STATUS scic_sds_port_default_destruct_handler( 481 SCI_BASE_PORT_T *port 482); 483 484SCI_STATUS scic_sds_port_default_reset_handler( 485 SCI_BASE_PORT_T * port, 486 U32 timeout 487); 488 489SCI_STATUS scic_sds_port_default_add_phy_handler( 490 SCI_BASE_PORT_T *port, 491 SCI_BASE_PHY_T *phy 492); 493 494SCI_STATUS scic_sds_port_default_remove_phy_handler( 495 SCI_BASE_PORT_T *port, 496 SCI_BASE_PHY_T *phy 497); 498 499SCI_STATUS scic_sds_port_default_frame_handler( 500 struct SCIC_SDS_PORT * port, 501 U32 frame_index 502); 503 504SCI_STATUS scic_sds_port_default_event_handler( 505 struct SCIC_SDS_PORT * port, 506 U32 event_code 507); 508 509void scic_sds_port_default_link_up_handler( 510 struct SCIC_SDS_PORT *this_port, 511 struct SCIC_SDS_PHY *phy 512); 513 514void scic_sds_port_default_link_down_handler( 515 struct SCIC_SDS_PORT *this_port, 516 struct SCIC_SDS_PHY *phy 517); 518 519SCI_STATUS scic_sds_port_default_start_io_handler( 520 struct SCIC_SDS_PORT *port, 521 struct SCIC_SDS_REMOTE_DEVICE *device, 522 struct SCIC_SDS_REQUEST *io_request 523); 524 525SCI_STATUS scic_sds_port_default_complete_io_handler( 526 struct SCIC_SDS_PORT *port, 527 struct SCIC_SDS_REMOTE_DEVICE *device, 528 struct SCIC_SDS_REQUEST *io_request 529); 530 531SCI_SAS_LINK_RATE scic_sds_port_get_max_allowed_speed( 532 SCIC_SDS_PORT_T * this_port 533); 534 535void scic_sds_port_broadcast_change_received( 536 struct SCIC_SDS_PORT * this_port, 537 struct SCIC_SDS_PHY * this_phy 538); 539 540BOOL scic_sds_port_is_valid_phy_assignment( 541 SCIC_SDS_PORT_T *this_port, 542 U32 phy_index 543); 544 545BOOL scic_sds_port_is_phy_mask_valid( 546 SCIC_SDS_PORT_T * this_port, 547 U32 phy_mask 548); 549 550U32 scic_sds_port_get_phys( 551 SCIC_SDS_PORT_T * this_port 552); 553 554void scic_sds_port_get_sas_address( 555 SCIC_SDS_PORT_T * this_port, 556 SCI_SAS_ADDRESS_T * sas_address 557); 558 559void scic_sds_port_get_attached_sas_address( 560 SCIC_SDS_PORT_T * this_port, 561 SCI_SAS_ADDRESS_T * sas_address 562); 563 564void scic_sds_port_get_attached_protocols( 565 SCIC_SDS_PORT_T * this_port, 566 SCI_SAS_IDENTIFY_ADDRESS_FRAME_PROTOCOLS_T * protocols 567); 568 569SCI_STATUS scic_sds_port_set_phy( 570 struct SCIC_SDS_PORT *port, 571 struct SCIC_SDS_PHY *phy 572); 573 574SCI_STATUS scic_sds_port_clear_phy( 575 struct SCIC_SDS_PORT *port, 576 struct SCIC_SDS_PHY *phy 577); 578 579void scic_sds_port_suspend_port_task_scheduler( 580 SCIC_SDS_PORT_T *this_port 581); 582 583void scic_sds_port_resume_port_task_scheduler( 584 SCIC_SDS_PORT_T *this_port 585); 586 587void scic_sds_port_release_resource( 588 struct SCIC_SDS_CONTROLLER * controller, 589 struct SCIC_SDS_PORT * port 590); 591 592#ifdef __cplusplus 593} 594#endif // __cplusplus 595 596 597#endif // _SCIC_SDS_PORT_H_ 598