1/*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2020-2024, Broadcom Inc. All rights reserved.
5 * Support: <fbsd-storage-driver.pdl@broadcom.com>
6 *
7 * Authors: Sumit Saxena <sumit.saxena@broadcom.com>
8 *	    Chandrakanth Patil <chandrakanth.patil@broadcom.com>
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met:
13 *
14 * 1. Redistributions of source code must retain the above copyright notice,
15 *    this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 *    this list of conditions and the following disclaimer in the documentation and/or other
18 *    materials provided with the distribution.
19 * 3. Neither the name of the Broadcom Inc. nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software without
21 *    specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 * The views and conclusions contained in the software and documentation are
36 * those of the authors and should not be interpreted as representing
37 * official policies,either expressed or implied, of the FreeBSD Project.
38 *
39 * Mail to: Broadcom Inc 1320 Ridder Park Dr, San Jose, CA 95131
40 *
41 * Broadcom Inc. (Broadcom) MPI3MR Adapter FreeBSD
42 */
43#include "mpi3mr.h"
44
45struct mpi3mr_fw_event_work;
46
47struct mpi3mr_throttle_group_info {
48	U8 io_divert;
49	U16 fw_qd;
50	U16 modified_qd;
51	U16 id;
52	U32 high;
53	U32 low;
54	mpi3mr_atomic_t pend_large_data_sz;
55};
56
57struct mpi3mr_tgt_dev_sassata {
58	U64 sas_address;
59	U16 dev_info;
60};
61
62struct mpi3mr_tgt_dev_pcie {
63	U32 mdts;
64	U16 capb;
65	U8 pgsz;
66	U8 abort_to;
67	U8 reset_to;
68	U16 dev_info;
69};
70
71struct mpi3mr_tgt_dev_volume {
72	U8 state;
73	U16 tg_id;
74	U32 tg_high;
75	U32 tg_low;
76	struct mpi3mr_throttle_group_info *tg;
77};
78
79typedef union _mpi3mr_form_spec_inf {
80	struct mpi3mr_tgt_dev_sassata sassata_inf;
81	struct mpi3mr_tgt_dev_pcie pcie_inf;
82	struct mpi3mr_tgt_dev_volume vol_inf;
83} mpi3mr_form_spec_inf;
84
85struct mpi3mr_target {
86	uint16_t dev_handle;
87	uint16_t slot;
88	uint16_t per_id;
89	uint8_t dev_type;
90	volatile uint8_t	is_hidden;
91	volatile uint8_t	dev_removed;
92	U8 dev_removedelay;
93	mpi3mr_atomic_t block_io;
94	uint8_t exposed_to_os;
95	uint16_t qdepth;
96	uint64_t wwid;
97	mpi3mr_form_spec_inf dev_spec;
98	uint16_t	tid;
99	uint16_t        exp_dev_handle;
100	uint16_t        phy_num;
101	uint64_t	sasaddr;
102	uint16_t	parent_handle;
103	uint64_t	parent_sasaddr;
104	uint32_t	parent_devinfo;
105	mpi3mr_atomic_t outstanding;
106	uint8_t		scsi_req_desc_type;
107	TAILQ_ENTRY(mpi3mr_target)	tgt_next;
108	uint16_t	handle;
109	uint8_t		link_rate;
110	uint8_t		encl_level_valid;
111	uint8_t		encl_level;
112	char		connector_name[4];
113	uint64_t	devname;
114	uint32_t	devinfo;
115	uint16_t	encl_handle;
116	uint16_t	encl_slot;
117	uint8_t		flags;
118#define MPI3MRSAS_TARGET_INREMOVAL	(1 << 3)
119	uint8_t		io_throttle_enabled;
120	uint8_t		io_divert;
121	struct mpi3mr_throttle_group_info *throttle_group;
122	uint64_t	q_depth;
123	enum mpi3mr_target_state state;
124	uint16_t	ws_len;
125};
126
127struct mpi3mr_cam_softc {
128	struct mpi3mr_softc	*sc;
129	u_int			flags;
130#define MPI3MRSAS_IN_DISCOVERY	(1 << 0)
131#define MPI3MRSAS_IN_STARTUP	(1 << 1)
132#define MPI3MRSAS_DISCOVERY_TIMEOUT_PENDING	(1 << 2)
133#define MPI3MRSAS_QUEUE_FROZEN	(1 << 3)
134#define	MPI3MRSAS_SHUTDOWN		(1 << 4)
135	u_int			maxtargets;
136	struct cam_devq		*devq;
137	struct cam_sim		*sim;
138	struct cam_path		*path;
139	struct intr_config_hook	sas_ich;
140	struct callout		discovery_callout;
141	struct mpi3mr_event_handle	*mpi3mr_eh;
142
143	u_int                   startup_refcount;
144	struct proc             *sysctl_proc;
145	struct taskqueue	*ev_tq;
146	struct task		ev_task;
147	TAILQ_HEAD(, mpi3mr_fw_event_work)	ev_queue;
148	TAILQ_HEAD(, mpi3mr_target)		tgt_list;
149};
150
151MALLOC_DECLARE(M_MPI3MRSAS);
152
153static __inline void
154mpi3mr_set_ccbstatus(union ccb *ccb, int status)
155{
156	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
157	ccb->ccb_h.status |= status;
158}
159
160static __inline int
161mpi3mr_get_ccbstatus(union ccb *ccb)
162{
163	return (ccb->ccb_h.status & CAM_STATUS_MASK);
164}
165
166static __inline void mpi3mr_print_cdb(union ccb *ccb)
167{
168	struct ccb_scsiio *csio;
169	struct mpi3mr_cam_softc *cam_sc;
170	struct cam_sim *sim;
171	int i;
172
173	sim = xpt_path_sim(ccb->ccb_h.path);
174	cam_sc = cam_sim_softc(sim);
175
176	csio = &ccb->csio;
177
178	mpi3mr_dprint(cam_sc->sc, MPI3MR_INFO, "tgtID: %d  CDB: ", csio->ccb_h.target_id);
179	for (i = 0; i < csio->cdb_len; i++)
180		printf("%x ", csio->cdb_io.cdb_bytes[i]);
181
182	printf("\n");
183}
184
185void mpi3mr_rescan_target(struct mpi3mr_softc *sc, struct mpi3mr_target *targ);
186void mpi3mr_discovery_end(struct mpi3mr_cam_softc *sassc);
187void mpi3mr_prepare_for_tm(struct mpi3mr_softc *sc, struct mpi3mr_cmd *tm,
188    struct mpi3mr_target *target, lun_id_t lun_id);
189void mpi3mr_startup_increment(struct mpi3mr_cam_softc *sassc);
190void mpi3mr_startup_decrement(struct mpi3mr_cam_softc *sassc);
191
192void mpi3mr_firmware_event_work(void *arg, int pending);
193int mpi3mr_check_id(struct mpi3mr_cam_softc *sassc, int id);
194int
195mpi3mr_cam_attach(struct mpi3mr_softc *sc);
196int
197mpi3mr_cam_detach(struct mpi3mr_softc *sc);
198void
199mpi3mr_evt_handler(struct mpi3mr_softc *sc, uintptr_t data,
200    MPI3_EVENT_NOTIFICATION_REPLY *event);
201