4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER START
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * The contents of this file are subject to the terms of the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Common Development and Distribution License (the "License").
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You may not use this file except in compliance with the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * See the License for the specific language governing permissions
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * and limitations under the License.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * When distributing Covered Code, include this CDDL HEADER in each
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * If applicable, add the following below this CDDL HEADER, with the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * fields enclosed by brackets "[]" replaced with your own identifying
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * information: Portions Copyright [yyyy] [name of copyright owner]
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * CDDL HEADER END
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhextern "C" {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhtypedef enum {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * This structure defines a PHY device that represents what we
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * are connected to.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * The eight real physical PHYs that are in the PMC8X6G are represented
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * as an array of eight of these structures which define what these
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * real PHYs are connected to.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Depending upon what is actually connected to each PHY, the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * type set will define what we're connected to. If it is
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * a direct SATA connection, the phy will describe a SATA endpoint
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * If it is a direct SAS connection, it will describe a SAS
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * endpoint.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * If it is an EXPANDER, this will describe the edge of an expander.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * As we perform discovery on what is in an EXPANDER we define an
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * additional list of phys that represent what the Expander is connected to.
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister#define PMCS_MAX_REENUMERATE 2 /* Maximum re-enumeration attempts */
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister * Number of usecs to wait after last noted activate/deactivate callback
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister * before possibly restarting discovery
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister#define PMCS_REDISCOVERY_DELAY (5 * MICROSEC)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh hw_event_ack : 24; /* XXX: first level phy event acked */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh uint8_t ds_recovery_retries; /* # error retry attempts */
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana uint8_t ds_prev_good_recoveries; /* # successful recoveries */
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana clock_t prev_recovery; /* previous successful recovery */
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana clock_t last_good_recovery; /* oldest successful recovery */
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana /* within PMCS_MAX_DS_RECOVERY_TIME time frame */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh pmcs_dtype_t pend_dtype; /* new dtype (pending change) */
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister reenumerate : 1, /* attempt re-enumeration */
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana deregister_wait : 1; /* phy waiting to get deregistered */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh clock_t config_stop; /* When config attempts will stop */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh kcondvar_t abort_all_cv; /* Wait for ABORT_ALL completion */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh volatile uint32_t ref_count; /* Targets & work on this PHY */
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister uint32_t enum_attempts; /* # of enumeration attempts */
73a3eccd27d9673a6407274ea0de350699562fd9David Hollister pmcs_iport_t *last_iport; /* last iport this PHY was on */
188eaed9d5f14c73dfba1cd0dabaa430bdfd4a9aSrikanth Suravajhala pmcs_xscsi_t **target_addr; /* address of real target pointer */
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister * Attached port phy mask and target port phymask. With 16 bytes
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister * we can represent a phymask for anything with up to 64 ports
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister uint64_t att_port_pm; /* att port pm for this PHY */
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister uint64_t att_port_pm_tmp; /* Temp area for wide-ports */
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister char att_port_pm_str[PMCS_PM_MAX_NAMELEN + 1];
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister uint64_t tgt_port_pm; /* tgt port pm for this PHY */
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister uint64_t tgt_port_pm_tmp; /* Temp area for wide-ports */
499cfd156ad653fc27397c5f021047c091dd12c5David Hollister char tgt_port_pm_str[PMCS_PM_MAX_NAMELEN + 1];
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister smp_routing_attr_t routing_attr; /* Routing attr. from discover resp. */
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister smp_routing_attr_t routing_method; /* Actual routing method used. */
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister smp_report_general_resp_t rg_resp; /* Response to REPORT_GENERAL */
9aed162131f1840d0bc1cd0275f4d7144f3690f0David Hollister smp_discover_resp_t disc_resp; /* Response to DISCOVER */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* maximum number of ds recovery retries (ds_recovery_retries) */
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana/* max time allowed for successful recovery */
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana#define PMCS_MAX_DS_RECOVERY_TIME (60 * 1000000) /* 60 seconds */
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana/* ds recovery on same same phy is not allowed within this interval */
af68568220d139fee6e01579437e660dbfee20a8Srikanth, Ramana#define PMCS_DS_RECOVERY_INTERVAL (1000000) /* 1 second */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Inbound and Outbound Queue Related Definitions.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * The PMC8X6G has a programmable number of inbound and outbound circular
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * queues for use in message passing between the host and the PMC8X6G
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * (up to 64 queues for the Rev C Chip). This driver does not use all
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * possible queues.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Each Queue is given 4K of consistent memory and we set a 64 byte size for
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * the queue entry size (this gives us 256 queue entries per queue).
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * This allocation then continues up a further PMCS_SCRATCH_SIZE bytes
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * that the driver uses as a temporary scratch area for things like
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * SMP discovery.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * This control area looks like this:
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Offset What
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * ------------------------------------------------
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 0 IQ 0 Consumer Index
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 4 IQ 1 Consumer Index
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 8..255 ...
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 252..255 IQ 63 Consumer Index
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 256 OQ 0 Producer Index
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 260 OQ 1 Producer Index
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 264..259 ....
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 508..511 OQ 63 Producer Index
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 512..512+PMCS_SCRATCH_SIZE-1 Scratch area.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Work related structures. Each one of these structures is paired
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * with *any* command that is fed to the PMC8X6G via one of the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Inbound Queues. The work structure has a tag to compare with
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * the message that comes back out of an Outbound Queue. The
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * work structure also points to the phy which this command is
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * tied to. It also has a pointer a callback function (if defined).
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * See that TAG Architecture below for the various kinds of
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * dispositions of a work structure.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Work Structure States
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * NIL -> READY
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * READY -> NIL
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * READY -> ONCHIP
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * ONCHIP -> INTR
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * INTR -> READY
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * INTR -> NIL
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * INTR -> ABORTED
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * INTR -> TIMED_OUT
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * ABORTED -> NIL
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * TIMED_OUT -> NIL
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhtypedef enum {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * This structure defines a PMC-Sierra defined firmware header.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhtypedef struct {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Offlevel work as a bit pattern.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * The actual values as they appear in work_flags
601c90f161ff0319c1b4a2c3362b466043a65d8dSrikanth, Ramana#define PMCS_WORK_FLAG_DEREGISTER_DEV (1 << 11)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * This structure is used by this function to test MPI (and interrupts)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * after MPI has been started to make sure it's working reliably.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhtypedef struct {
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Tag Architecture. The PMC has 32 bit tags for MPI messages.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * We use this tag this way.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * bits what
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * ------------------------
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 31 done bit
978d7443a924cda8208d6a10e72be89383bc7becSrikanth Suravajhala * 30 non-io cmd bit
978d7443a924cda8208d6a10e72be89383bc7becSrikanth Suravajhala * 29..28 tag type
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 27..12 rolling serial number
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * 11..0 index into work area to get pmcwork structure
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * A tag type of NONE means that nobody is waiting on any results,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * so the interrupt code frees the work structure that has this
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * A tag type of CBACK means that the the interrupt handler
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * takes the tag 'arg' in the work structure to be a callback
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * function pointer (see pmcs_cb_t). The callee is responsible
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * for freeing the work structure that has this tag.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * A tag type of WAIT means that the issuer of the work needs
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * be woken up from interrupt level when the command completes
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * (or times out). If work structure tag 'arg' is non-null,
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * up to 2*PMCS_QENTRY_SIZE bits of data from the Outbound Queue
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * entry may be copied to the area pointed to by 'arg'. This
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * allows issuers to get directly at the results of the command
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * they issed. The synchronization point for the issuer and the
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * interrupt code for command done notification is the setting
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * of the 'DONE' bit in the tag as stored in the work structure.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh (((x)->htag == PMCS_TAG_FREE) || (((x)->htag & PMCS_TAG_DONE) != 0))
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ((x)->htag != PMCS_TAG_FREE && (x)->state == PMCS_WORK_STATE_ONCHIP)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Miscellaneous Definitions
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh int _j = x; \
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh m[_j++] = 0; \
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh t[_j++] = 0; \
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, p, NULL, "%s changed in " \
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, p, NULL, "%s changed in " \
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Check to see if the requested work bit is set. Either way, the bit will
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * be cleared upon return.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Check to see if the requested work bit is set. The value will not be
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * changed in this case. The atomic_xx_nv operations can be quite expensive
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * so this should not be used in non-DEBUG code.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ((atomic_and_ulong_nv(&hwp->work_flags, (ulong_t)-1) & (1 << wrk)) != 0)
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh while (!PMCS_COMMAND_DONE(p)) { \
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Signal the next I/O completion thread to start running.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Watchdog/SCSA timer definitions
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh/* usecs to SCSA watchdog ticks */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * More misc
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#define SAS_ADDR_PRT(x) x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ((r == SAS_LINK_RATE_1_5GBIT) || (r == SAS_LINK_RATE_3GBIT) || \
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * This is here to avoid inclusion of <sys/ctype.h> which is not lint clean.
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh ((x) >= 'a' && (x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhtypedef void (*pmcs_cb_t) (pmcs_hw_t *, pmcwork_t *, uint32_t *);
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Defines and structure used for tracing/logging information
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dhtypedef struct {
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh /* Target-specific data */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh /* PHY-specific data */
c3bc407cfbd238a18e4728ad5f36f39cecdb062fdh /* Log data */
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh * Firmware event log header format
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister * Firmware event log entry format
1f81b46471e38fdeb9ab74c25510b2f903f8af12David Hollister#define PMCS_FWLOG_TIMER_DIV 8 /* fw timer has 8ns granularity */
658280b6253b61dbb155f43d0e3cbcffa85ccb90David Hollister * Receptacle information
4c06356b0f0fffb4fc1b6eccc8e5d8e2254a84d6dh#endif /* _PMCS_DEF_H */