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