1eb82ff87SDaniel Beauregard /*
2eb82ff87SDaniel Beauregard  * CDDL HEADER START
3eb82ff87SDaniel Beauregard  *
4eb82ff87SDaniel Beauregard  * The contents of this file are subject to the terms of the
5eb82ff87SDaniel Beauregard  * Common Development and Distribution License (the "License").
6eb82ff87SDaniel Beauregard  * You may not use this file except in compliance with the License.
7eb82ff87SDaniel Beauregard  *
8eb82ff87SDaniel Beauregard  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9eb82ff87SDaniel Beauregard  * or http://www.opensolaris.org/os/licensing.
10eb82ff87SDaniel Beauregard  * See the License for the specific language governing permissions
11eb82ff87SDaniel Beauregard  * and limitations under the License.
12eb82ff87SDaniel Beauregard  *
13eb82ff87SDaniel Beauregard  * When distributing Covered Code, include this CDDL HEADER in each
14eb82ff87SDaniel Beauregard  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15eb82ff87SDaniel Beauregard  * If applicable, add the following below this CDDL HEADER, with the
16eb82ff87SDaniel Beauregard  * fields enclosed by brackets "[]" replaced with your own identifying
17eb82ff87SDaniel Beauregard  * information: Portions Copyright [yyyy] [name of copyright owner]
18eb82ff87SDaniel Beauregard  *
19eb82ff87SDaniel Beauregard  * CDDL HEADER END
20eb82ff87SDaniel Beauregard  */
21eb82ff87SDaniel Beauregard 
22eb82ff87SDaniel Beauregard /*
23eb82ff87SDaniel Beauregard  * Copyright 2010 QLogic Corporation.  All rights reserved.
24eb82ff87SDaniel Beauregard  * Use is subject to license terms.
25eb82ff87SDaniel Beauregard  */
26eb82ff87SDaniel Beauregard 
27eb82ff87SDaniel Beauregard #pragma ident	"Copyright 2010 QLogic Corporation; ql_nx.c"
28eb82ff87SDaniel Beauregard 
29eb82ff87SDaniel Beauregard /*
30eb82ff87SDaniel Beauregard  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
31eb82ff87SDaniel Beauregard  *
32eb82ff87SDaniel Beauregard  * ***********************************************************************
33eb82ff87SDaniel Beauregard  * *									**
34eb82ff87SDaniel Beauregard  * *				NOTICE					**
35eb82ff87SDaniel Beauregard  * *		COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION		**
36eb82ff87SDaniel Beauregard  * *			ALL RIGHTS RESERVED				**
37eb82ff87SDaniel Beauregard  * *									**
38eb82ff87SDaniel Beauregard  * ***********************************************************************
39eb82ff87SDaniel Beauregard  *
40eb82ff87SDaniel Beauregard  */
41eb82ff87SDaniel Beauregard 
42eb82ff87SDaniel Beauregard #include <ql_apps.h>
43eb82ff87SDaniel Beauregard #include <ql_api.h>
44eb82ff87SDaniel Beauregard #include <ql_debug.h>
45eb82ff87SDaniel Beauregard #include <ql_mbx.h>
46eb82ff87SDaniel Beauregard #include <ql_nx.h>
47eb82ff87SDaniel Beauregard 
48eb82ff87SDaniel Beauregard /*
49eb82ff87SDaniel Beauregard  *  Local Function Prototypes.
50eb82ff87SDaniel Beauregard  */
51eb82ff87SDaniel Beauregard static void *ql_8021_pci_base_offsetfset(ql_adapter_state_t *, uint64_t);
52eb82ff87SDaniel Beauregard static void ql_crb_addr_transform_setup(ql_adapter_state_t *);
53eb82ff87SDaniel Beauregard static void ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *, uint64_t *);
54eb82ff87SDaniel Beauregard static void ql_8021_wr_32(ql_adapter_state_t *, uint64_t, uint32_t);
55eb82ff87SDaniel Beauregard static void ql_8021_rd_32(ql_adapter_state_t *, uint64_t, uint32_t *);
56eb82ff87SDaniel Beauregard static int ql_8021_crb_win_lock(ql_adapter_state_t *);
57eb82ff87SDaniel Beauregard static void ql_8021_crb_win_unlock(ql_adapter_state_t *);
58eb82ff87SDaniel Beauregard static int ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *, uint64_t *);
59eb82ff87SDaniel Beauregard static uint32_t ql_8021_pci_mem_bound_check(ql_adapter_state_t *, uint64_t,
60eb82ff87SDaniel Beauregard     uint32_t);
61eb82ff87SDaniel Beauregard static uint64_t ql_8021_pci_set_window(ql_adapter_state_t *, uint64_t);
62eb82ff87SDaniel Beauregard static int ql_8021_pci_is_same_window(ql_adapter_state_t *, uint64_t);
63eb82ff87SDaniel Beauregard static int ql_8021_pci_mem_read_direct(ql_adapter_state_t *, uint64_t, void *,
64eb82ff87SDaniel Beauregard     uint32_t);
65eb82ff87SDaniel Beauregard static int ql_8021_pci_mem_write_direct(ql_adapter_state_t *, uint64_t, void *,
66eb82ff87SDaniel Beauregard     uint32_t);
67eb82ff87SDaniel Beauregard static int ql_8021_pci_mem_read_2M(ql_adapter_state_t *, uint64_t, void *,
68eb82ff87SDaniel Beauregard     uint32_t);
69eb82ff87SDaniel Beauregard static int ql_8021_pci_mem_write_2M(ql_adapter_state_t *, uint64_t, void *,
70eb82ff87SDaniel Beauregard     uint32_t);
71eb82ff87SDaniel Beauregard static uint32_t ql_8021_decode_crb_addr(ql_adapter_state_t *, uint32_t);
72eb82ff87SDaniel Beauregard static int ql_8021_rom_lock(ql_adapter_state_t *);
73eb82ff87SDaniel Beauregard static void ql_8021_rom_unlock(ql_adapter_state_t *);
74eb82ff87SDaniel Beauregard static int ql_8021_wait_rom_done(ql_adapter_state_t *);
75eb82ff87SDaniel Beauregard static int ql_8021_wait_flash_done(ql_adapter_state_t *);
76eb82ff87SDaniel Beauregard static int ql_8021_do_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
77eb82ff87SDaniel Beauregard static int ql_8021_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
78eb82ff87SDaniel Beauregard static int ql_8021_do_rom_write(ql_adapter_state_t *, uint32_t, uint32_t);
79eb82ff87SDaniel Beauregard static int ql_8021_do_rom_erase(ql_adapter_state_t *, uint32_t);
80eb82ff87SDaniel Beauregard static int ql_8021_phantom_init(ql_adapter_state_t *);
81eb82ff87SDaniel Beauregard static int ql_8021_pinit_from_rom(ql_adapter_state_t *);
82eb82ff87SDaniel Beauregard static int ql_8021_load_from_flash(ql_adapter_state_t *);
83eb82ff87SDaniel Beauregard static int ql_8021_load_firmware(ql_adapter_state_t *);
84eb82ff87SDaniel Beauregard static int ql_8021_reset_hw(ql_adapter_state_t *, int);
85eb82ff87SDaniel Beauregard static int ql_8021_init_p3p(ql_adapter_state_t *);
86eb82ff87SDaniel Beauregard static int ql_8021_hw_lock(ql_adapter_state_t *, uint32_t);
87eb82ff87SDaniel Beauregard static void ql_8021_hw_unlock(ql_adapter_state_t *);
88eb82ff87SDaniel Beauregard static void ql_8021_need_reset_handler(ql_adapter_state_t *);
89eb82ff87SDaniel Beauregard 
90eb82ff87SDaniel Beauregard /*
91eb82ff87SDaniel Beauregard  * Local Data.
92eb82ff87SDaniel Beauregard  */
93eb82ff87SDaniel Beauregard static uint32_t	crb_addr_xform[MAX_CRB_XFORM];
94eb82ff87SDaniel Beauregard static int	crb_table_initialized = 0;
95eb82ff87SDaniel Beauregard static int	pci_set_window_warning_count = 0;
96eb82ff87SDaniel Beauregard 
97eb82ff87SDaniel Beauregard static struct legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
98eb82ff87SDaniel Beauregard 
99eb82ff87SDaniel Beauregard static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
100eb82ff87SDaniel Beauregard 	{{{0, 0,	 0,	 0}}},			/* 0: PCI */
101eb82ff87SDaniel Beauregard 	{{{1, 0x0100000, 0x0102000, 0x120000},		/* 1: PCIE */
102eb82ff87SDaniel Beauregard 	    {1, 0x0110000, 0x0120000, 0x130000},
103eb82ff87SDaniel Beauregard 	    {1, 0x0120000, 0x0122000, 0x124000},
104eb82ff87SDaniel Beauregard 	    {1, 0x0130000, 0x0132000, 0x126000},
105eb82ff87SDaniel Beauregard 	    {1, 0x0140000, 0x0142000, 0x128000},
106eb82ff87SDaniel Beauregard 	    {1, 0x0150000, 0x0152000, 0x12a000},
107eb82ff87SDaniel Beauregard 	    {1, 0x0160000, 0x0170000, 0x110000},
108eb82ff87SDaniel Beauregard 	    {1, 0x0170000, 0x0172000, 0x12e000},
109eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
110eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
111eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
112eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
113eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
114eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
115eb82ff87SDaniel Beauregard 	    {1, 0x01e0000, 0x01e0800, 0x122000},
116eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000}}},
117eb82ff87SDaniel Beauregard 	{{{1, 0x0200000, 0x0210000, 0x180000}}},	/* 2: MN */
118eb82ff87SDaniel Beauregard 	{{{0, 0,	 0,	 0}}},			/* 3: */
119eb82ff87SDaniel Beauregard 	{{{1, 0x0400000, 0x0401000, 0x169000}}},	/* 4: P2NR1 */
120eb82ff87SDaniel Beauregard 	{{{1, 0x0500000, 0x0510000, 0x140000}}},	/* 5: SRE   */
121eb82ff87SDaniel Beauregard 	{{{1, 0x0600000, 0x0610000, 0x1c0000}}},	/* 6: NIU   */
122eb82ff87SDaniel Beauregard 	{{{1, 0x0700000, 0x0704000, 0x1b8000}}},	/* 7: QM    */
123eb82ff87SDaniel Beauregard 	{{{1, 0x0800000, 0x0802000, 0x170000},  	/* 8: SQM0  */
124eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
125eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
126eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
127eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
128eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
129eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
130eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
131eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
132eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
133eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
134eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
135eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
136eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
137eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
138eb82ff87SDaniel Beauregard 	    {1, 0x08f0000, 0x08f2000, 0x172000}}},
139eb82ff87SDaniel Beauregard 	{{{1, 0x0900000, 0x0902000, 0x174000},		/* 9: SQM1 */
140eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
141eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
142eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
143eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
144eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
145eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
146eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
147eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
148eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
149eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
150eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
151eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
152eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
153eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
154eb82ff87SDaniel Beauregard 	    {1, 0x09f0000, 0x09f2000, 0x176000}}},
155eb82ff87SDaniel Beauregard 	{{{0, 0x0a00000, 0x0a02000, 0x178000},		/* 10: SQM2 */
156eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
157eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
158eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
159eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
160eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
161eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
162eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
163eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
164eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
165eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
166eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
167eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
168eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
169eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
170eb82ff87SDaniel Beauregard 	    {1, 0x0af0000, 0x0af2000, 0x17a000}}},
171eb82ff87SDaniel Beauregard 	{{{0, 0x0b00000, 0x0b02000, 0x17c000},		/* 11: SQM3 */
172eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
173eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
174eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
175eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
176eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
177eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
178eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
179eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
180eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
181eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
182eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
183eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
184eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
185eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
186eb82ff87SDaniel Beauregard 	    {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
187eb82ff87SDaniel Beauregard 	{{{1, 0x0c00000, 0x0c04000, 0x1d4000}}},	/* 12: I2Q */
188eb82ff87SDaniel Beauregard 	{{{1, 0x0d00000, 0x0d04000, 0x1a4000}}},	/* 13: TMR */
189eb82ff87SDaniel Beauregard 	{{{1, 0x0e00000, 0x0e04000, 0x1a0000}}},	/* 14: ROMUSB */
190eb82ff87SDaniel Beauregard 	{{{1, 0x0f00000, 0x0f01000, 0x164000}}},	/* 15: PEG4 */
191eb82ff87SDaniel Beauregard 	{{{0, 0x1000000, 0x1004000, 0x1a8000}}},	/* 16: XDMA */
192eb82ff87SDaniel Beauregard 	{{{1, 0x1100000, 0x1101000, 0x160000}}},	/* 17: PEG0 */
193eb82ff87SDaniel Beauregard 	{{{1, 0x1200000, 0x1201000, 0x161000}}},	/* 18: PEG1 */
194eb82ff87SDaniel Beauregard 	{{{1, 0x1300000, 0x1301000, 0x162000}}},	/* 19: PEG2 */
195eb82ff87SDaniel Beauregard 	{{{1, 0x1400000, 0x1401000, 0x163000}}},	/* 20: PEG3 */
196eb82ff87SDaniel Beauregard 	{{{1, 0x1500000, 0x1501000, 0x165000}}},	/* 21: P2ND */
197eb82ff87SDaniel Beauregard 	{{{1, 0x1600000, 0x1601000, 0x166000}}},	/* 22: P2NI */
198eb82ff87SDaniel Beauregard 	{{{0, 0,	 0,	 0}}},			/* 23: */
199eb82ff87SDaniel Beauregard 	{{{0, 0,	 0,	 0}}},			/* 24: */
200eb82ff87SDaniel Beauregard 	{{{0, 0,	 0,	 0}}},			/* 25: */
201eb82ff87SDaniel Beauregard 	{{{0, 0,	 0,	 0}}},			/* 26: */
202eb82ff87SDaniel Beauregard 	{{{0, 0,	 0,	 0}}},			/* 27: */
203eb82ff87SDaniel Beauregard 	{{{0, 0,	 0,	 0}}},			/* 28: */
204eb82ff87SDaniel Beauregard 	{{{1, 0x1d00000, 0x1d10000, 0x190000}}},	/* 29: MS */
205eb82ff87SDaniel Beauregard 	{{{1, 0x1e00000, 0x1e01000, 0x16a000}}},	/* 30: P2NR2 */
206eb82ff87SDaniel Beauregard 	{{{1, 0x1f00000, 0x1f10000, 0x150000}}},	/* 31: EPG */
207eb82ff87SDaniel Beauregard 	{{{0}}},					/* 32: PCI */
208eb82ff87SDaniel Beauregard 	{{{1, 0x2100000, 0x2102000, 0x120000},		/* 33: PCIE */
209eb82ff87SDaniel Beauregard 	    {1, 0x2110000, 0x2120000, 0x130000},
210eb82ff87SDaniel Beauregard 	    {1, 0x2120000, 0x2122000, 0x124000},
211eb82ff87SDaniel Beauregard 	    {1, 0x2130000, 0x2132000, 0x126000},
212eb82ff87SDaniel Beauregard 	    {1, 0x2140000, 0x2142000, 0x128000},
213eb82ff87SDaniel Beauregard 	    {1, 0x2150000, 0x2152000, 0x12a000},
214eb82ff87SDaniel Beauregard 	    {1, 0x2160000, 0x2170000, 0x110000},
215eb82ff87SDaniel Beauregard 	    {1, 0x2170000, 0x2172000, 0x12e000},
216eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
217eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
218eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
219eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
220eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
221eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
222eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000},
223eb82ff87SDaniel Beauregard 	    {0, 0x0000000, 0x0000000, 0x000000}}},
224eb82ff87SDaniel Beauregard 	{{{1, 0x2200000, 0x2204000, 0x1b0000}}},	/* 34: CAM */
225eb82ff87SDaniel Beauregard 	{{{0}}},					/* 35: */
226eb82ff87SDaniel Beauregard 	{{{0}}},					/* 36: */
227eb82ff87SDaniel Beauregard 	{{{0}}},					/* 37: */
228eb82ff87SDaniel Beauregard 	{{{0}}},					/* 38: */
229eb82ff87SDaniel Beauregard 	{{{0}}},					/* 39: */
230eb82ff87SDaniel Beauregard 	{{{1, 0x2800000, 0x2804000, 0x1a4000}}},	/* 40: TMR */
231eb82ff87SDaniel Beauregard 	{{{1, 0x2900000, 0x2901000, 0x16b000}}},	/* 41: P2NR3 */
232eb82ff87SDaniel Beauregard 	{{{1, 0x2a00000, 0x2a00400, 0x1ac400}}},	/* 42: RPMX1 */
233eb82ff87SDaniel Beauregard 	{{{1, 0x2b00000, 0x2b00400, 0x1ac800}}},	/* 43: RPMX2 */
234eb82ff87SDaniel Beauregard 	{{{1, 0x2c00000, 0x2c00400, 0x1acc00}}},	/* 44: RPMX3 */
235eb82ff87SDaniel Beauregard 	{{{1, 0x2d00000, 0x2d00400, 0x1ad000}}},	/* 45: RPMX4 */
236eb82ff87SDaniel Beauregard 	{{{1, 0x2e00000, 0x2e00400, 0x1ad400}}},	/* 46: RPMX5 */
237eb82ff87SDaniel Beauregard 	{{{1, 0x2f00000, 0x2f00400, 0x1ad800}}},	/* 47: RPMX6 */
238eb82ff87SDaniel Beauregard 	{{{1, 0x3000000, 0x3000400, 0x1adc00}}},	/* 48: RPMX7 */
239eb82ff87SDaniel Beauregard 	{{{0, 0x3100000, 0x3104000, 0x1a8000}}},	/* 49: XDMA */
240eb82ff87SDaniel Beauregard 	{{{1, 0x3200000, 0x3204000, 0x1d4000}}},	/* 50: I2Q */
241eb82ff87SDaniel Beauregard 	{{{1, 0x3300000, 0x3304000, 0x1a0000}}},	/* 51: ROMUSB */
242eb82ff87SDaniel Beauregard 	{{{0}}},					/* 52: */
243eb82ff87SDaniel Beauregard 	{{{1, 0x3500000, 0x3500400, 0x1ac000}}},	/* 53: RPMX0 */
244eb82ff87SDaniel Beauregard 	{{{1, 0x3600000, 0x3600400, 0x1ae000}}},	/* 54: RPMX8 */
245eb82ff87SDaniel Beauregard 	{{{1, 0x3700000, 0x3700400, 0x1ae400}}},	/* 55: RPMX9 */
246eb82ff87SDaniel Beauregard 	{{{1, 0x3800000, 0x3804000, 0x1d0000}}},	/* 56: OCM0 */
247eb82ff87SDaniel Beauregard 	{{{1, 0x3900000, 0x3904000, 0x1b4000}}},	/* 57: CRYPTO */
248eb82ff87SDaniel Beauregard 	{{{1, 0x3a00000, 0x3a04000, 0x1d8000}}},	/* 58: SMB */
249eb82ff87SDaniel Beauregard 	{{{0}}},					/* 59: I2C0 */
250eb82ff87SDaniel Beauregard 	{{{0}}},					/* 60: I2C1 */
251eb82ff87SDaniel Beauregard 	{{{1, 0x3d00000, 0x3d04000, 0x1dc000}}},	/* 61: LPC */
252eb82ff87SDaniel Beauregard 	{{{1, 0x3e00000, 0x3e01000, 0x167000}}},	/* 62: P2NC */
253eb82ff87SDaniel Beauregard 	{{{1, 0x3f00000, 0x3f01000, 0x168000}}}		/* 63: P2NR0 */
254eb82ff87SDaniel Beauregard };
255eb82ff87SDaniel Beauregard 
256eb82ff87SDaniel Beauregard /*
257eb82ff87SDaniel Beauregard  * top 12 bits of crb internal address (hub, agent)
258eb82ff87SDaniel Beauregard  */
259eb82ff87SDaniel Beauregard static uint32_t crb_hub_agt[64] = {
260eb82ff87SDaniel Beauregard 	0,
261eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PS,
262eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_MN,
263eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_MS,
264eb82ff87SDaniel Beauregard 	0,
265eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_SRE,
266eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_NIU,
267eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_QMN,
268eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_SQN0,
269eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_SQN1,
270eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_SQN2,
271eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_SQN3,
272eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
273eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
274eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
275eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGN4,
276eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
277eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGN0,
278eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGN1,
279eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGN2,
280eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGN3,
281eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGND,
282eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGNI,
283eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGS0,
284eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGS1,
285eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGS2,
286eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGS3,
287eb82ff87SDaniel Beauregard 	0,
288eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGSI,
289eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_SN,
290eb82ff87SDaniel Beauregard 	0,
291eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_EG,
292eb82ff87SDaniel Beauregard 	0,
293eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PS,
294eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_CAM,
295eb82ff87SDaniel Beauregard 	0,
296eb82ff87SDaniel Beauregard 	0,
297eb82ff87SDaniel Beauregard 	0,
298eb82ff87SDaniel Beauregard 	0,
299eb82ff87SDaniel Beauregard 	0,
300eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
301eb82ff87SDaniel Beauregard 	0,
302eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
303eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
304eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
305eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
306eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
307eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
308eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
309eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
310eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
311eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
312eb82ff87SDaniel Beauregard 	0,
313eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
314eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
315eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
316eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_OCM0,
317eb82ff87SDaniel Beauregard 	0,
318eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_SMB,
319eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_I2C0,
320eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_I2C1,
321eb82ff87SDaniel Beauregard 	0,
322eb82ff87SDaniel Beauregard 	UNM_HW_CRB_HUB_AGT_ADR_PGNC,
323eb82ff87SDaniel Beauregard 	0,
324eb82ff87SDaniel Beauregard };
325eb82ff87SDaniel Beauregard 
326eb82ff87SDaniel Beauregard static void *
ql_8021_pci_base_offsetfset(ql_adapter_state_t * ha,uint64_t off)327eb82ff87SDaniel Beauregard ql_8021_pci_base_offsetfset(ql_adapter_state_t *ha, uint64_t off)
328eb82ff87SDaniel Beauregard {
329eb82ff87SDaniel Beauregard 	if ((off < ha->first_page_group_end) &&
330eb82ff87SDaniel Beauregard 	    (off >= ha->first_page_group_start)) {
331eb82ff87SDaniel Beauregard 		return ((void *)(ha->nx_pcibase + off));
332eb82ff87SDaniel Beauregard 	}
333eb82ff87SDaniel Beauregard 
334eb82ff87SDaniel Beauregard 	return (NULL);
335eb82ff87SDaniel Beauregard }
336eb82ff87SDaniel Beauregard 
337eb82ff87SDaniel Beauregard /* ARGSUSED */
338eb82ff87SDaniel Beauregard static void
ql_crb_addr_transform_setup(ql_adapter_state_t * ha)339eb82ff87SDaniel Beauregard ql_crb_addr_transform_setup(ql_adapter_state_t *ha)
340eb82ff87SDaniel Beauregard {
341eb82ff87SDaniel Beauregard 	crb_addr_transform(XDMA);
342eb82ff87SDaniel Beauregard 	crb_addr_transform(TIMR);
343eb82ff87SDaniel Beauregard 	crb_addr_transform(SRE);
344eb82ff87SDaniel Beauregard 	crb_addr_transform(SQN3);
345eb82ff87SDaniel Beauregard 	crb_addr_transform(SQN2);
346eb82ff87SDaniel Beauregard 	crb_addr_transform(SQN1);
347eb82ff87SDaniel Beauregard 	crb_addr_transform(SQN0);
348eb82ff87SDaniel Beauregard 	crb_addr_transform(SQS3);
349eb82ff87SDaniel Beauregard 	crb_addr_transform(SQS2);
350eb82ff87SDaniel Beauregard 	crb_addr_transform(SQS1);
351eb82ff87SDaniel Beauregard 	crb_addr_transform(SQS0);
352eb82ff87SDaniel Beauregard 	crb_addr_transform(RPMX7);
353eb82ff87SDaniel Beauregard 	crb_addr_transform(RPMX6);
354eb82ff87SDaniel Beauregard 	crb_addr_transform(RPMX5);
355eb82ff87SDaniel Beauregard 	crb_addr_transform(RPMX4);
356eb82ff87SDaniel Beauregard 	crb_addr_transform(RPMX3);
357eb82ff87SDaniel Beauregard 	crb_addr_transform(RPMX2);
358eb82ff87SDaniel Beauregard 	crb_addr_transform(RPMX1);
359eb82ff87SDaniel Beauregard 	crb_addr_transform(RPMX0);
360eb82ff87SDaniel Beauregard 	crb_addr_transform(ROMUSB);
361eb82ff87SDaniel Beauregard 	crb_addr_transform(SN);
362eb82ff87SDaniel Beauregard 	crb_addr_transform(QMN);
363eb82ff87SDaniel Beauregard 	crb_addr_transform(QMS);
364eb82ff87SDaniel Beauregard 	crb_addr_transform(PGNI);
365eb82ff87SDaniel Beauregard 	crb_addr_transform(PGND);
366eb82ff87SDaniel Beauregard 	crb_addr_transform(PGN3);
367eb82ff87SDaniel Beauregard 	crb_addr_transform(PGN2);
368eb82ff87SDaniel Beauregard 	crb_addr_transform(PGN1);
369eb82ff87SDaniel Beauregard 	crb_addr_transform(PGN0);
370eb82ff87SDaniel Beauregard 	crb_addr_transform(PGSI);
371eb82ff87SDaniel Beauregard 	crb_addr_transform(PGSD);
372eb82ff87SDaniel Beauregard 	crb_addr_transform(PGS3);
373eb82ff87SDaniel Beauregard 	crb_addr_transform(PGS2);
374eb82ff87SDaniel Beauregard 	crb_addr_transform(PGS1);
375eb82ff87SDaniel Beauregard 	crb_addr_transform(PGS0);
376eb82ff87SDaniel Beauregard 	crb_addr_transform(PS);
377eb82ff87SDaniel Beauregard 	crb_addr_transform(PH);
378eb82ff87SDaniel Beauregard 	crb_addr_transform(NIU);
379eb82ff87SDaniel Beauregard 	crb_addr_transform(I2Q);
380eb82ff87SDaniel Beauregard 	crb_addr_transform(EG);
381eb82ff87SDaniel Beauregard 	crb_addr_transform(MN);
382eb82ff87SDaniel Beauregard 	crb_addr_transform(MS);
383eb82ff87SDaniel Beauregard 	crb_addr_transform(CAS2);
384eb82ff87SDaniel Beauregard 	crb_addr_transform(CAS1);
385eb82ff87SDaniel Beauregard 	crb_addr_transform(CAS0);
386eb82ff87SDaniel Beauregard 	crb_addr_transform(CAM);
387eb82ff87SDaniel Beauregard 	crb_addr_transform(C2C1);
388eb82ff87SDaniel Beauregard 	crb_addr_transform(C2C0);
389eb82ff87SDaniel Beauregard 	crb_addr_transform(SMB);
390eb82ff87SDaniel Beauregard 	crb_addr_transform(OCM0);
391eb82ff87SDaniel Beauregard 	/*
392eb82ff87SDaniel Beauregard 	 * Used only in P3 just define it for P2 also.
393eb82ff87SDaniel Beauregard 	 */
394eb82ff87SDaniel Beauregard 	crb_addr_transform(I2C0);
395eb82ff87SDaniel Beauregard 
396eb82ff87SDaniel Beauregard 	crb_table_initialized = 1;
397eb82ff87SDaniel Beauregard }
398eb82ff87SDaniel Beauregard 
399eb82ff87SDaniel Beauregard /*
400eb82ff87SDaniel Beauregard  * In: 'off' is offset from CRB space in 128M pci map
401eb82ff87SDaniel Beauregard  * Out: 'off' is 2M pci map addr
402eb82ff87SDaniel Beauregard  * side effect: lock crb window
403eb82ff87SDaniel Beauregard  */
404eb82ff87SDaniel Beauregard static void
ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t * ha,uint64_t * off)405eb82ff87SDaniel Beauregard ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *ha, uint64_t *off)
406eb82ff87SDaniel Beauregard {
407eb82ff87SDaniel Beauregard 	uint32_t	win_read;
408eb82ff87SDaniel Beauregard 
409eb82ff87SDaniel Beauregard 	ha->crb_win = (uint32_t)CRB_HI(*off);
410eb82ff87SDaniel Beauregard 	WRT_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase, ha->crb_win);
411eb82ff87SDaniel Beauregard 
412eb82ff87SDaniel Beauregard 	/*
413eb82ff87SDaniel Beauregard 	 * Read back value to make sure write has gone through before trying
414eb82ff87SDaniel Beauregard 	 * to use it.
415eb82ff87SDaniel Beauregard 	 */
416eb82ff87SDaniel Beauregard 	win_read = RD_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase);
417eb82ff87SDaniel Beauregard 	if (win_read != ha->crb_win) {
418eb82ff87SDaniel Beauregard 		EL(ha, "Written crbwin (0x%x) != Read crbwin (0x%x), "
419eb82ff87SDaniel Beauregard 		    "off=0x%llx\n", ha->crb_win, win_read, *off);
420eb82ff87SDaniel Beauregard 	}
421eb82ff87SDaniel Beauregard 	*off = (*off & MASK(16)) + CRB_INDIRECT_2M + (uintptr_t)ha->nx_pcibase;
422eb82ff87SDaniel Beauregard }
423eb82ff87SDaniel Beauregard 
424eb82ff87SDaniel Beauregard static void
ql_8021_wr_32(ql_adapter_state_t * ha,uint64_t off,uint32_t data)425eb82ff87SDaniel Beauregard ql_8021_wr_32(ql_adapter_state_t *ha, uint64_t off, uint32_t data)
426eb82ff87SDaniel Beauregard {
427eb82ff87SDaniel Beauregard 	int	rv;
428eb82ff87SDaniel Beauregard 
429eb82ff87SDaniel Beauregard 	rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
430eb82ff87SDaniel Beauregard 	if (rv == -1) {
431eb82ff87SDaniel Beauregard 		cmn_err(CE_PANIC, "ql_8021_wr_32, ql_8021_pci_get_crb_addr_"
432eb82ff87SDaniel Beauregard 		    "2M=-1\n");
433eb82ff87SDaniel Beauregard 	}
434eb82ff87SDaniel Beauregard 	if (rv == 1) {
435eb82ff87SDaniel Beauregard 		(void) ql_8021_crb_win_lock(ha);
436eb82ff87SDaniel Beauregard 		ql_8021_pci_set_crbwindow_2M(ha, &off);
437eb82ff87SDaniel Beauregard 	}
438eb82ff87SDaniel Beauregard 
439eb82ff87SDaniel Beauregard 	WRT_REG_DWORD(ha, (uintptr_t)off, data);
440eb82ff87SDaniel Beauregard 
441eb82ff87SDaniel Beauregard 	if (rv == 1) {
442eb82ff87SDaniel Beauregard 		ql_8021_crb_win_unlock(ha);
443eb82ff87SDaniel Beauregard 	}
444eb82ff87SDaniel Beauregard }
445eb82ff87SDaniel Beauregard 
446eb82ff87SDaniel Beauregard static void
ql_8021_rd_32(ql_adapter_state_t * ha,uint64_t off,uint32_t * data)447eb82ff87SDaniel Beauregard ql_8021_rd_32(ql_adapter_state_t *ha, uint64_t off, uint32_t *data)
448eb82ff87SDaniel Beauregard {
449eb82ff87SDaniel Beauregard 	int		rv;
450eb82ff87SDaniel Beauregard 	uint32_t	n;
451eb82ff87SDaniel Beauregard 
452eb82ff87SDaniel Beauregard 	rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
453eb82ff87SDaniel Beauregard 	if (rv == -1) {
454eb82ff87SDaniel Beauregard 		cmn_err(CE_PANIC, "ql_8021_rd_32, ql_8021_pci_get_crb_addr_"
455eb82ff87SDaniel Beauregard 		    "2M=-1\n");
456eb82ff87SDaniel Beauregard 	}
457eb82ff87SDaniel Beauregard 
458eb82ff87SDaniel Beauregard 	if (rv == 1) {
459eb82ff87SDaniel Beauregard 		(void) ql_8021_crb_win_lock(ha);
460eb82ff87SDaniel Beauregard 		ql_8021_pci_set_crbwindow_2M(ha, &off);
461eb82ff87SDaniel Beauregard 	}
462eb82ff87SDaniel Beauregard 	n = RD_REG_DWORD(ha, (uintptr_t)off);
463eb82ff87SDaniel Beauregard 
464eb82ff87SDaniel Beauregard 	if (data != NULL) {
465eb82ff87SDaniel Beauregard 		*data = n;
466eb82ff87SDaniel Beauregard 	}
467eb82ff87SDaniel Beauregard 
468eb82ff87SDaniel Beauregard 	if (rv == 1) {
469eb82ff87SDaniel Beauregard 		ql_8021_crb_win_unlock(ha);
470eb82ff87SDaniel Beauregard 	}
471eb82ff87SDaniel Beauregard }
472eb82ff87SDaniel Beauregard 
473eb82ff87SDaniel Beauregard static int
ql_8021_crb_win_lock(ql_adapter_state_t * ha)474eb82ff87SDaniel Beauregard ql_8021_crb_win_lock(ql_adapter_state_t *ha)
475eb82ff87SDaniel Beauregard {
476eb82ff87SDaniel Beauregard 	uint32_t	done = 0, timeout = 0;
477eb82ff87SDaniel Beauregard 
478eb82ff87SDaniel Beauregard 	while (!done) {
479eb82ff87SDaniel Beauregard 		/* acquire semaphore3 from PCI HW block */
480eb82ff87SDaniel Beauregard 		ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_LOCK), &done);
481eb82ff87SDaniel Beauregard 		if (done == 1) {
482eb82ff87SDaniel Beauregard 			break;
483eb82ff87SDaniel Beauregard 		}
484eb82ff87SDaniel Beauregard 		if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
485eb82ff87SDaniel Beauregard 			EL(ha, "timeout\n");
486eb82ff87SDaniel Beauregard 			return (-1);
487eb82ff87SDaniel Beauregard 		}
488eb82ff87SDaniel Beauregard 		timeout++;
489eb82ff87SDaniel Beauregard 
490eb82ff87SDaniel Beauregard 		/* Yield CPU */
491eb82ff87SDaniel Beauregard 		delay(1);
492eb82ff87SDaniel Beauregard 	}
493eb82ff87SDaniel Beauregard 	ql_8021_wr_32(ha, UNM_CRB_WIN_LOCK_ID, ha->function_number);
494eb82ff87SDaniel Beauregard 
495eb82ff87SDaniel Beauregard 	return (0);
496eb82ff87SDaniel Beauregard }
497eb82ff87SDaniel Beauregard 
498eb82ff87SDaniel Beauregard static void
ql_8021_crb_win_unlock(ql_adapter_state_t * ha)499eb82ff87SDaniel Beauregard ql_8021_crb_win_unlock(ql_adapter_state_t *ha)
500eb82ff87SDaniel Beauregard {
501eb82ff87SDaniel Beauregard 	ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_UNLOCK), NULL);
502eb82ff87SDaniel Beauregard }
503eb82ff87SDaniel Beauregard 
504eb82ff87SDaniel Beauregard static int
ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t * ha,uint64_t * off)505eb82ff87SDaniel Beauregard ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *ha, uint64_t *off)
506eb82ff87SDaniel Beauregard {
507eb82ff87SDaniel Beauregard 	crb_128M_2M_sub_block_map_t	*m;
508eb82ff87SDaniel Beauregard 
509eb82ff87SDaniel Beauregard 	if (*off >= UNM_CRB_MAX) {
510eb82ff87SDaniel Beauregard 		EL(ha, "%llx >= %llx\n", *off, UNM_CRB_MAX);
511eb82ff87SDaniel Beauregard 		return (-1);
512eb82ff87SDaniel Beauregard 	}
513eb82ff87SDaniel Beauregard 
514eb82ff87SDaniel Beauregard 	if (*off >= UNM_PCI_CAMQM && (*off < UNM_PCI_CAMQM_2M_END)) {
515eb82ff87SDaniel Beauregard 		*off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
516eb82ff87SDaniel Beauregard 		    (uintptr_t)ha->nx_pcibase;
517eb82ff87SDaniel Beauregard 		return (0);
518eb82ff87SDaniel Beauregard 	}
519eb82ff87SDaniel Beauregard 
520eb82ff87SDaniel Beauregard 	if (*off < UNM_PCI_CRBSPACE) {
521eb82ff87SDaniel Beauregard 		EL(ha, "%llx < %llx\n", *off, UNM_PCI_CRBSPACE);
522eb82ff87SDaniel Beauregard 		return (-1);
523eb82ff87SDaniel Beauregard 	}
524eb82ff87SDaniel Beauregard 
525eb82ff87SDaniel Beauregard 	*off -= UNM_PCI_CRBSPACE;
526eb82ff87SDaniel Beauregard 	/*
527eb82ff87SDaniel Beauregard 	 * Try direct map
528eb82ff87SDaniel Beauregard 	 */
529eb82ff87SDaniel Beauregard 
530eb82ff87SDaniel Beauregard 	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
531eb82ff87SDaniel Beauregard 
532eb82ff87SDaniel Beauregard 	if (m->valid && ((uint64_t)m->start_128M <= *off) &&
533eb82ff87SDaniel Beauregard 	    ((uint64_t)m->end_128M > *off)) {
534eb82ff87SDaniel Beauregard 		*off = (uint64_t)(*off + m->start_2M - m->start_128M +
535eb82ff87SDaniel Beauregard 		    (uintptr_t)ha->nx_pcibase);
536eb82ff87SDaniel Beauregard 		return (0);
537eb82ff87SDaniel Beauregard 	}
538eb82ff87SDaniel Beauregard 
539eb82ff87SDaniel Beauregard 	/*
540eb82ff87SDaniel Beauregard 	 * Not in direct map, use crb window
541eb82ff87SDaniel Beauregard 	 */
542eb82ff87SDaniel Beauregard 	return (1);
543eb82ff87SDaniel Beauregard }
544eb82ff87SDaniel Beauregard 
545eb82ff87SDaniel Beauregard /*
546eb82ff87SDaniel Beauregard  * check memory access boundary.
547eb82ff87SDaniel Beauregard  * used by test agent. support ddr access only for now
548eb82ff87SDaniel Beauregard  */
549eb82ff87SDaniel Beauregard /* ARGSUSED */
550eb82ff87SDaniel Beauregard static uint32_t
ql_8021_pci_mem_bound_check(ql_adapter_state_t * ha,uint64_t addr,uint32_t size)551eb82ff87SDaniel Beauregard ql_8021_pci_mem_bound_check(ql_adapter_state_t *ha, uint64_t addr,
552eb82ff87SDaniel Beauregard     uint32_t size)
553eb82ff87SDaniel Beauregard {
554eb82ff87SDaniel Beauregard 	/*LINTED suspicious 0 comparison*/
555eb82ff87SDaniel Beauregard 	if (!QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
556eb82ff87SDaniel Beauregard 	    UNM_ADDR_DDR_NET_MAX) ||
557eb82ff87SDaniel Beauregard 	    /*LINTED suspicious 0 comparison*/
558eb82ff87SDaniel Beauregard 	    !QL_8021_ADDR_IN_RANGE(addr + size - 1, UNM_ADDR_DDR_NET,
559eb82ff87SDaniel Beauregard 	    UNM_ADDR_DDR_NET_MAX) ||
560eb82ff87SDaniel Beauregard 	    ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
561eb82ff87SDaniel Beauregard 		return (0);
562eb82ff87SDaniel Beauregard 	}
563eb82ff87SDaniel Beauregard 
564eb82ff87SDaniel Beauregard 	return (1);
565eb82ff87SDaniel Beauregard }
566eb82ff87SDaniel Beauregard 
567eb82ff87SDaniel Beauregard static uint64_t
ql_8021_pci_set_window(ql_adapter_state_t * ha,uint64_t addr)568eb82ff87SDaniel Beauregard ql_8021_pci_set_window(ql_adapter_state_t *ha, uint64_t addr)
569eb82ff87SDaniel Beauregard {
570eb82ff87SDaniel Beauregard 	uint32_t	window, win_read;
571eb82ff87SDaniel Beauregard 
572eb82ff87SDaniel Beauregard 	/*LINTED suspicious 0 comparison*/
573eb82ff87SDaniel Beauregard 	if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
574eb82ff87SDaniel Beauregard 	    UNM_ADDR_DDR_NET_MAX)) {
575eb82ff87SDaniel Beauregard 		/* DDR network side */
576eb82ff87SDaniel Beauregard 		window = (uint32_t)MN_WIN(addr);
577eb82ff87SDaniel Beauregard 		ha->ddr_mn_window = window;
578eb82ff87SDaniel Beauregard 		ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
579eb82ff87SDaniel Beauregard 		ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
580eb82ff87SDaniel Beauregard 		    &win_read);
581eb82ff87SDaniel Beauregard 		if ((win_read << 17) != window) {
582eb82ff87SDaniel Beauregard 			EL(ha, "Warning, Written MNwin (0x%x) != Read MNwin "
583eb82ff87SDaniel Beauregard 			    "(0x%x)\n", window, win_read);
584eb82ff87SDaniel Beauregard 		}
585eb82ff87SDaniel Beauregard 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
586eb82ff87SDaniel Beauregard 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
587eb82ff87SDaniel Beauregard 	    UNM_ADDR_OCM0_MAX)) {
588eb82ff87SDaniel Beauregard 		uint32_t	temp1;
589eb82ff87SDaniel Beauregard 
590eb82ff87SDaniel Beauregard 		if ((addr & 0x00ff800) == 0xff800) {
591eb82ff87SDaniel Beauregard 			/* if bits 19:18&17:11 are on */
592eb82ff87SDaniel Beauregard 			EL(ha, "QM access not handled\n");
593eb82ff87SDaniel Beauregard 			addr = -1UL;
594eb82ff87SDaniel Beauregard 		}
595eb82ff87SDaniel Beauregard 
596eb82ff87SDaniel Beauregard 		window = (uint32_t)OCM_WIN(addr);
597eb82ff87SDaniel Beauregard 		ha->ddr_mn_window = window;
598eb82ff87SDaniel Beauregard 		ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
599eb82ff87SDaniel Beauregard 		ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
600eb82ff87SDaniel Beauregard 		    &win_read);
601eb82ff87SDaniel Beauregard 		temp1 = ((window & 0x1FF) << 7) |
602eb82ff87SDaniel Beauregard 		    ((window & 0x0FFFE0000) >> 17);
603eb82ff87SDaniel Beauregard 		if (win_read != temp1) {
604eb82ff87SDaniel Beauregard 			EL(ha, "Written OCMwin (0x%x) != Read OCMwin (0x%x)\n",
605eb82ff87SDaniel Beauregard 			    temp1, win_read);
606eb82ff87SDaniel Beauregard 		}
607eb82ff87SDaniel Beauregard 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
608eb82ff87SDaniel Beauregard 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
609eb82ff87SDaniel Beauregard 	    NX_P3_ADDR_QDR_NET_MAX)) {
610eb82ff87SDaniel Beauregard 		/* QDR network side */
611eb82ff87SDaniel Beauregard 		window = (uint32_t)MS_WIN(addr);
612eb82ff87SDaniel Beauregard 		ha->qdr_sn_window = window;
613eb82ff87SDaniel Beauregard 		ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
614eb82ff87SDaniel Beauregard 		ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
615eb82ff87SDaniel Beauregard 		    &win_read);
616eb82ff87SDaniel Beauregard 		if (win_read != window) {
617eb82ff87SDaniel Beauregard 			EL(ha, "Written MSwin (0x%x) != Read MSwin (0x%x)\n",
618eb82ff87SDaniel Beauregard 			    window, win_read);
619eb82ff87SDaniel Beauregard 		}
620eb82ff87SDaniel Beauregard 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
621eb82ff87SDaniel Beauregard 	} else {
622eb82ff87SDaniel Beauregard 		/*
623eb82ff87SDaniel Beauregard 		 * peg gdb frequently accesses memory that doesn't exist,
624eb82ff87SDaniel Beauregard 		 * this limits the chit chat so debugging isn't slowed down.
625eb82ff87SDaniel Beauregard 		 */
626eb82ff87SDaniel Beauregard 		if ((pci_set_window_warning_count++ < 8) ||
627eb82ff87SDaniel Beauregard 		    (pci_set_window_warning_count % 64 == 0)) {
628eb82ff87SDaniel Beauregard 			EL(ha, "Unknown address range\n");
629eb82ff87SDaniel Beauregard 		}
630eb82ff87SDaniel Beauregard 		addr = -1UL;
631eb82ff87SDaniel Beauregard 	}
632eb82ff87SDaniel Beauregard 
633eb82ff87SDaniel Beauregard 	return (addr);
634eb82ff87SDaniel Beauregard }
635eb82ff87SDaniel Beauregard 
636eb82ff87SDaniel Beauregard /* check if address is in the same windows as the previous access */
637eb82ff87SDaniel Beauregard static int
ql_8021_pci_is_same_window(ql_adapter_state_t * ha,uint64_t addr)638eb82ff87SDaniel Beauregard ql_8021_pci_is_same_window(ql_adapter_state_t *ha, uint64_t addr)
639eb82ff87SDaniel Beauregard {
640eb82ff87SDaniel Beauregard 	uint32_t	window;
641eb82ff87SDaniel Beauregard 	uint64_t	qdr_max;
642eb82ff87SDaniel Beauregard 
643eb82ff87SDaniel Beauregard 	qdr_max = NX_P3_ADDR_QDR_NET_MAX;
644eb82ff87SDaniel Beauregard 
645eb82ff87SDaniel Beauregard 	/*LINTED suspicious 0 comparison*/
646eb82ff87SDaniel Beauregard 	if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
647eb82ff87SDaniel Beauregard 	    UNM_ADDR_DDR_NET_MAX)) {
648eb82ff87SDaniel Beauregard 		/* DDR network side */
649eb82ff87SDaniel Beauregard 		EL(ha, "DDR network side\n");
650eb82ff87SDaniel Beauregard 		return (0);	/* MN access can not come here */
651eb82ff87SDaniel Beauregard 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
652eb82ff87SDaniel Beauregard 	    UNM_ADDR_OCM0_MAX)) {
653eb82ff87SDaniel Beauregard 		return (1);
654eb82ff87SDaniel Beauregard 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM1,
655eb82ff87SDaniel Beauregard 	    UNM_ADDR_OCM1_MAX)) {
656eb82ff87SDaniel Beauregard 		return (1);
657eb82ff87SDaniel Beauregard 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
658eb82ff87SDaniel Beauregard 		/* QDR network side */
659eb82ff87SDaniel Beauregard 		window = (uint32_t)(((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f);
660eb82ff87SDaniel Beauregard 		if (ha->qdr_sn_window == window) {
661eb82ff87SDaniel Beauregard 			return (1);
662eb82ff87SDaniel Beauregard 		}
663eb82ff87SDaniel Beauregard 	}
664eb82ff87SDaniel Beauregard 
665eb82ff87SDaniel Beauregard 	return (0);
666eb82ff87SDaniel Beauregard }
667eb82ff87SDaniel Beauregard 
668eb82ff87SDaniel Beauregard static int
ql_8021_pci_mem_read_direct(ql_adapter_state_t * ha,uint64_t off,void * data,uint32_t size)669eb82ff87SDaniel Beauregard ql_8021_pci_mem_read_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
670eb82ff87SDaniel Beauregard     uint32_t size)
671eb82ff87SDaniel Beauregard {
672eb82ff87SDaniel Beauregard 	void		*addr;
673eb82ff87SDaniel Beauregard 	int		ret = 0;
674eb82ff87SDaniel Beauregard 	uint64_t	start;
675eb82ff87SDaniel Beauregard 
676eb82ff87SDaniel Beauregard 	/*
677eb82ff87SDaniel Beauregard 	 * If attempting to access unknown address or straddle hw windows,
678eb82ff87SDaniel Beauregard 	 * do not access.
679eb82ff87SDaniel Beauregard 	 */
680eb82ff87SDaniel Beauregard 	if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
681eb82ff87SDaniel Beauregard 	    (ql_8021_pci_is_same_window(ha, off + size - 1) == 0)) {
682eb82ff87SDaniel Beauregard 		EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
683eb82ff87SDaniel Beauregard 		    off);
684eb82ff87SDaniel Beauregard 		return (-1);
685eb82ff87SDaniel Beauregard 	}
686eb82ff87SDaniel Beauregard 
687eb82ff87SDaniel Beauregard 	addr = ql_8021_pci_base_offsetfset(ha, start);
688eb82ff87SDaniel Beauregard 	if (!addr) {
689eb82ff87SDaniel Beauregard 		addr = (void *)((uint8_t *)ha->nx_pcibase + start);
690eb82ff87SDaniel Beauregard 	}
691eb82ff87SDaniel Beauregard 
692eb82ff87SDaniel Beauregard 	switch (size) {
693eb82ff87SDaniel Beauregard 	case 1:
694eb82ff87SDaniel Beauregard 		*(uint8_t  *)data = RD_REG_BYTE(ha, addr);
695eb82ff87SDaniel Beauregard 		break;
696eb82ff87SDaniel Beauregard 	case 2:
697eb82ff87SDaniel Beauregard 		*(uint16_t  *)data = RD_REG_WORD(ha, addr);
698eb82ff87SDaniel Beauregard 		break;
699eb82ff87SDaniel Beauregard 	case 4:
700eb82ff87SDaniel Beauregard 		*(uint32_t  *)data = RD_REG_DWORD(ha, addr);
701eb82ff87SDaniel Beauregard 		break;
702eb82ff87SDaniel Beauregard 	case 8:
703eb82ff87SDaniel Beauregard 		*(uint64_t  *)data = RD_REG_DDWORD(ha, addr);
704eb82ff87SDaniel Beauregard 		break;