111924SDaniel.Beauregard@Sun.COM /*
211924SDaniel.Beauregard@Sun.COM * CDDL HEADER START
311924SDaniel.Beauregard@Sun.COM *
411924SDaniel.Beauregard@Sun.COM * The contents of this file are subject to the terms of the
511924SDaniel.Beauregard@Sun.COM * Common Development and Distribution License (the "License").
611924SDaniel.Beauregard@Sun.COM * You may not use this file except in compliance with the License.
711924SDaniel.Beauregard@Sun.COM *
811924SDaniel.Beauregard@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911924SDaniel.Beauregard@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011924SDaniel.Beauregard@Sun.COM * See the License for the specific language governing permissions
1111924SDaniel.Beauregard@Sun.COM * and limitations under the License.
1211924SDaniel.Beauregard@Sun.COM *
1311924SDaniel.Beauregard@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411924SDaniel.Beauregard@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511924SDaniel.Beauregard@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611924SDaniel.Beauregard@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711924SDaniel.Beauregard@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811924SDaniel.Beauregard@Sun.COM *
1911924SDaniel.Beauregard@Sun.COM * CDDL HEADER END
2011924SDaniel.Beauregard@Sun.COM */
2111924SDaniel.Beauregard@Sun.COM
2211924SDaniel.Beauregard@Sun.COM /*
2311924SDaniel.Beauregard@Sun.COM * Copyright 2010 QLogic Corporation. All rights reserved.
2411924SDaniel.Beauregard@Sun.COM * Use is subject to license terms.
2511924SDaniel.Beauregard@Sun.COM */
2611924SDaniel.Beauregard@Sun.COM
2711924SDaniel.Beauregard@Sun.COM #pragma ident "Copyright 2010 QLogic Corporation; ql_nx.c"
2811924SDaniel.Beauregard@Sun.COM
2911924SDaniel.Beauregard@Sun.COM /*
3011924SDaniel.Beauregard@Sun.COM * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
3111924SDaniel.Beauregard@Sun.COM *
3211924SDaniel.Beauregard@Sun.COM * ***********************************************************************
3311924SDaniel.Beauregard@Sun.COM * * **
3411924SDaniel.Beauregard@Sun.COM * * NOTICE **
3511924SDaniel.Beauregard@Sun.COM * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION **
3611924SDaniel.Beauregard@Sun.COM * * ALL RIGHTS RESERVED **
3711924SDaniel.Beauregard@Sun.COM * * **
3811924SDaniel.Beauregard@Sun.COM * ***********************************************************************
3911924SDaniel.Beauregard@Sun.COM *
4011924SDaniel.Beauregard@Sun.COM */
4111924SDaniel.Beauregard@Sun.COM
4211924SDaniel.Beauregard@Sun.COM #include <ql_apps.h>
4311924SDaniel.Beauregard@Sun.COM #include <ql_api.h>
4411924SDaniel.Beauregard@Sun.COM #include <ql_debug.h>
4511924SDaniel.Beauregard@Sun.COM #include <ql_mbx.h>
4611924SDaniel.Beauregard@Sun.COM #include <ql_nx.h>
4711924SDaniel.Beauregard@Sun.COM
4811924SDaniel.Beauregard@Sun.COM /*
4911924SDaniel.Beauregard@Sun.COM * Local Function Prototypes.
5011924SDaniel.Beauregard@Sun.COM */
5111924SDaniel.Beauregard@Sun.COM static void *ql_8021_pci_base_offsetfset(ql_adapter_state_t *, uint64_t);
5211924SDaniel.Beauregard@Sun.COM static void ql_crb_addr_transform_setup(ql_adapter_state_t *);
5311924SDaniel.Beauregard@Sun.COM static void ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *, uint64_t *);
5411924SDaniel.Beauregard@Sun.COM static void ql_8021_wr_32(ql_adapter_state_t *, uint64_t, uint32_t);
5511924SDaniel.Beauregard@Sun.COM static void ql_8021_rd_32(ql_adapter_state_t *, uint64_t, uint32_t *);
5611924SDaniel.Beauregard@Sun.COM static int ql_8021_crb_win_lock(ql_adapter_state_t *);
5711924SDaniel.Beauregard@Sun.COM static void ql_8021_crb_win_unlock(ql_adapter_state_t *);
5811924SDaniel.Beauregard@Sun.COM static int ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *, uint64_t *);
5911924SDaniel.Beauregard@Sun.COM static uint32_t ql_8021_pci_mem_bound_check(ql_adapter_state_t *, uint64_t,
6011924SDaniel.Beauregard@Sun.COM uint32_t);
6111924SDaniel.Beauregard@Sun.COM static uint64_t ql_8021_pci_set_window(ql_adapter_state_t *, uint64_t);
6211924SDaniel.Beauregard@Sun.COM static int ql_8021_pci_is_same_window(ql_adapter_state_t *, uint64_t);
6311924SDaniel.Beauregard@Sun.COM static int ql_8021_pci_mem_read_direct(ql_adapter_state_t *, uint64_t, void *,
6411924SDaniel.Beauregard@Sun.COM uint32_t);
6511924SDaniel.Beauregard@Sun.COM static int ql_8021_pci_mem_write_direct(ql_adapter_state_t *, uint64_t, void *,
6611924SDaniel.Beauregard@Sun.COM uint32_t);
6711924SDaniel.Beauregard@Sun.COM static int ql_8021_pci_mem_read_2M(ql_adapter_state_t *, uint64_t, void *,
6811924SDaniel.Beauregard@Sun.COM uint32_t);
6911924SDaniel.Beauregard@Sun.COM static int ql_8021_pci_mem_write_2M(ql_adapter_state_t *, uint64_t, void *,
7011924SDaniel.Beauregard@Sun.COM uint32_t);
7111924SDaniel.Beauregard@Sun.COM static uint32_t ql_8021_decode_crb_addr(ql_adapter_state_t *, uint32_t);
7211924SDaniel.Beauregard@Sun.COM static int ql_8021_rom_lock(ql_adapter_state_t *);
7311924SDaniel.Beauregard@Sun.COM static void ql_8021_rom_unlock(ql_adapter_state_t *);
7411924SDaniel.Beauregard@Sun.COM static int ql_8021_wait_rom_done(ql_adapter_state_t *);
7511924SDaniel.Beauregard@Sun.COM static int ql_8021_wait_flash_done(ql_adapter_state_t *);
7611924SDaniel.Beauregard@Sun.COM static int ql_8021_do_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
7711924SDaniel.Beauregard@Sun.COM static int ql_8021_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
7811924SDaniel.Beauregard@Sun.COM static int ql_8021_do_rom_write(ql_adapter_state_t *, uint32_t, uint32_t);
7911924SDaniel.Beauregard@Sun.COM static int ql_8021_do_rom_erase(ql_adapter_state_t *, uint32_t);
8011924SDaniel.Beauregard@Sun.COM static int ql_8021_phantom_init(ql_adapter_state_t *);
8111924SDaniel.Beauregard@Sun.COM static int ql_8021_pinit_from_rom(ql_adapter_state_t *);
8211924SDaniel.Beauregard@Sun.COM static int ql_8021_load_from_flash(ql_adapter_state_t *);
8311924SDaniel.Beauregard@Sun.COM static int ql_8021_load_firmware(ql_adapter_state_t *);
8411924SDaniel.Beauregard@Sun.COM static int ql_8021_reset_hw(ql_adapter_state_t *, int);
8511924SDaniel.Beauregard@Sun.COM static int ql_8021_init_p3p(ql_adapter_state_t *);
8611924SDaniel.Beauregard@Sun.COM static int ql_8021_hw_lock(ql_adapter_state_t *, uint32_t);
8711924SDaniel.Beauregard@Sun.COM static void ql_8021_hw_unlock(ql_adapter_state_t *);
8811924SDaniel.Beauregard@Sun.COM static void ql_8021_need_reset_handler(ql_adapter_state_t *);
8911924SDaniel.Beauregard@Sun.COM
9011924SDaniel.Beauregard@Sun.COM /*
9111924SDaniel.Beauregard@Sun.COM * Local Data.
9211924SDaniel.Beauregard@Sun.COM */
9311924SDaniel.Beauregard@Sun.COM static uint32_t crb_addr_xform[MAX_CRB_XFORM];
9411924SDaniel.Beauregard@Sun.COM static int crb_table_initialized = 0;
9511924SDaniel.Beauregard@Sun.COM static int pci_set_window_warning_count = 0;
9611924SDaniel.Beauregard@Sun.COM
9711924SDaniel.Beauregard@Sun.COM static struct legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
9811924SDaniel.Beauregard@Sun.COM
9911924SDaniel.Beauregard@Sun.COM static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
10011924SDaniel.Beauregard@Sun.COM {{{0, 0, 0, 0}}}, /* 0: PCI */
10111924SDaniel.Beauregard@Sun.COM {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
10211924SDaniel.Beauregard@Sun.COM {1, 0x0110000, 0x0120000, 0x130000},
10311924SDaniel.Beauregard@Sun.COM {1, 0x0120000, 0x0122000, 0x124000},
10411924SDaniel.Beauregard@Sun.COM {1, 0x0130000, 0x0132000, 0x126000},
10511924SDaniel.Beauregard@Sun.COM {1, 0x0140000, 0x0142000, 0x128000},
10611924SDaniel.Beauregard@Sun.COM {1, 0x0150000, 0x0152000, 0x12a000},
10711924SDaniel.Beauregard@Sun.COM {1, 0x0160000, 0x0170000, 0x110000},
10811924SDaniel.Beauregard@Sun.COM {1, 0x0170000, 0x0172000, 0x12e000},
10911924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
11011924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
11111924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
11211924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
11311924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
11411924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
11511924SDaniel.Beauregard@Sun.COM {1, 0x01e0000, 0x01e0800, 0x122000},
11611924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000}}},
11711924SDaniel.Beauregard@Sun.COM {{{1, 0x0200000, 0x0210000, 0x180000}}}, /* 2: MN */
11811924SDaniel.Beauregard@Sun.COM {{{0, 0, 0, 0}}}, /* 3: */
11911924SDaniel.Beauregard@Sun.COM {{{1, 0x0400000, 0x0401000, 0x169000}}}, /* 4: P2NR1 */
12011924SDaniel.Beauregard@Sun.COM {{{1, 0x0500000, 0x0510000, 0x140000}}}, /* 5: SRE */
12111924SDaniel.Beauregard@Sun.COM {{{1, 0x0600000, 0x0610000, 0x1c0000}}}, /* 6: NIU */
12211924SDaniel.Beauregard@Sun.COM {{{1, 0x0700000, 0x0704000, 0x1b8000}}}, /* 7: QM */
12311924SDaniel.Beauregard@Sun.COM {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0 */
12411924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
12511924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
12611924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
12711924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
12811924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
12911924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13011924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13111924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13211924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13311924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13411924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13511924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13611924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13711924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
13811924SDaniel.Beauregard@Sun.COM {1, 0x08f0000, 0x08f2000, 0x172000}}},
13911924SDaniel.Beauregard@Sun.COM {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1 */
14011924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14111924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14211924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14311924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14411924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14511924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14611924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14711924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14811924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
14911924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
15011924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
15111924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
15211924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
15311924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
15411924SDaniel.Beauregard@Sun.COM {1, 0x09f0000, 0x09f2000, 0x176000}}},
15511924SDaniel.Beauregard@Sun.COM {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2 */
15611924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
15711924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
15811924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
15911924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16011924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16111924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16211924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16311924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16411924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16511924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16611924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16711924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16811924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
16911924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
17011924SDaniel.Beauregard@Sun.COM {1, 0x0af0000, 0x0af2000, 0x17a000}}},
17111924SDaniel.Beauregard@Sun.COM {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3 */
17211924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
17311924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
17411924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
17511924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
17611924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
17711924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
17811924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
17911924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
18011924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
18111924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
18211924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
18311924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
18411924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
18511924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
18611924SDaniel.Beauregard@Sun.COM {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
18711924SDaniel.Beauregard@Sun.COM {{{1, 0x0c00000, 0x0c04000, 0x1d4000}}}, /* 12: I2Q */
18811924SDaniel.Beauregard@Sun.COM {{{1, 0x0d00000, 0x0d04000, 0x1a4000}}}, /* 13: TMR */
18911924SDaniel.Beauregard@Sun.COM {{{1, 0x0e00000, 0x0e04000, 0x1a0000}}}, /* 14: ROMUSB */
19011924SDaniel.Beauregard@Sun.COM {{{1, 0x0f00000, 0x0f01000, 0x164000}}}, /* 15: PEG4 */
19111924SDaniel.Beauregard@Sun.COM {{{0, 0x1000000, 0x1004000, 0x1a8000}}}, /* 16: XDMA */
19211924SDaniel.Beauregard@Sun.COM {{{1, 0x1100000, 0x1101000, 0x160000}}}, /* 17: PEG0 */
19311924SDaniel.Beauregard@Sun.COM {{{1, 0x1200000, 0x1201000, 0x161000}}}, /* 18: PEG1 */
19411924SDaniel.Beauregard@Sun.COM {{{1, 0x1300000, 0x1301000, 0x162000}}}, /* 19: PEG2 */
19511924SDaniel.Beauregard@Sun.COM {{{1, 0x1400000, 0x1401000, 0x163000}}}, /* 20: PEG3 */
19611924SDaniel.Beauregard@Sun.COM {{{1, 0x1500000, 0x1501000, 0x165000}}}, /* 21: P2ND */
19711924SDaniel.Beauregard@Sun.COM {{{1, 0x1600000, 0x1601000, 0x166000}}}, /* 22: P2NI */
19811924SDaniel.Beauregard@Sun.COM {{{0, 0, 0, 0}}}, /* 23: */
19911924SDaniel.Beauregard@Sun.COM {{{0, 0, 0, 0}}}, /* 24: */
20011924SDaniel.Beauregard@Sun.COM {{{0, 0, 0, 0}}}, /* 25: */
20111924SDaniel.Beauregard@Sun.COM {{{0, 0, 0, 0}}}, /* 26: */
20211924SDaniel.Beauregard@Sun.COM {{{0, 0, 0, 0}}}, /* 27: */
20311924SDaniel.Beauregard@Sun.COM {{{0, 0, 0, 0}}}, /* 28: */
20411924SDaniel.Beauregard@Sun.COM {{{1, 0x1d00000, 0x1d10000, 0x190000}}}, /* 29: MS */
20511924SDaniel.Beauregard@Sun.COM {{{1, 0x1e00000, 0x1e01000, 0x16a000}}}, /* 30: P2NR2 */
20611924SDaniel.Beauregard@Sun.COM {{{1, 0x1f00000, 0x1f10000, 0x150000}}}, /* 31: EPG */
20711924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 32: PCI */
20811924SDaniel.Beauregard@Sun.COM {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */
20911924SDaniel.Beauregard@Sun.COM {1, 0x2110000, 0x2120000, 0x130000},
21011924SDaniel.Beauregard@Sun.COM {1, 0x2120000, 0x2122000, 0x124000},
21111924SDaniel.Beauregard@Sun.COM {1, 0x2130000, 0x2132000, 0x126000},
21211924SDaniel.Beauregard@Sun.COM {1, 0x2140000, 0x2142000, 0x128000},
21311924SDaniel.Beauregard@Sun.COM {1, 0x2150000, 0x2152000, 0x12a000},
21411924SDaniel.Beauregard@Sun.COM {1, 0x2160000, 0x2170000, 0x110000},
21511924SDaniel.Beauregard@Sun.COM {1, 0x2170000, 0x2172000, 0x12e000},
21611924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
21711924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
21811924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
21911924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
22011924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
22111924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
22211924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000},
22311924SDaniel.Beauregard@Sun.COM {0, 0x0000000, 0x0000000, 0x000000}}},
22411924SDaniel.Beauregard@Sun.COM {{{1, 0x2200000, 0x2204000, 0x1b0000}}}, /* 34: CAM */
22511924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 35: */
22611924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 36: */
22711924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 37: */
22811924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 38: */
22911924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 39: */
23011924SDaniel.Beauregard@Sun.COM {{{1, 0x2800000, 0x2804000, 0x1a4000}}}, /* 40: TMR */
23111924SDaniel.Beauregard@Sun.COM {{{1, 0x2900000, 0x2901000, 0x16b000}}}, /* 41: P2NR3 */
23211924SDaniel.Beauregard@Sun.COM {{{1, 0x2a00000, 0x2a00400, 0x1ac400}}}, /* 42: RPMX1 */
23311924SDaniel.Beauregard@Sun.COM {{{1, 0x2b00000, 0x2b00400, 0x1ac800}}}, /* 43: RPMX2 */
23411924SDaniel.Beauregard@Sun.COM {{{1, 0x2c00000, 0x2c00400, 0x1acc00}}}, /* 44: RPMX3 */
23511924SDaniel.Beauregard@Sun.COM {{{1, 0x2d00000, 0x2d00400, 0x1ad000}}}, /* 45: RPMX4 */
23611924SDaniel.Beauregard@Sun.COM {{{1, 0x2e00000, 0x2e00400, 0x1ad400}}}, /* 46: RPMX5 */
23711924SDaniel.Beauregard@Sun.COM {{{1, 0x2f00000, 0x2f00400, 0x1ad800}}}, /* 47: RPMX6 */
23811924SDaniel.Beauregard@Sun.COM {{{1, 0x3000000, 0x3000400, 0x1adc00}}}, /* 48: RPMX7 */
23911924SDaniel.Beauregard@Sun.COM {{{0, 0x3100000, 0x3104000, 0x1a8000}}}, /* 49: XDMA */
24011924SDaniel.Beauregard@Sun.COM {{{1, 0x3200000, 0x3204000, 0x1d4000}}}, /* 50: I2Q */
24111924SDaniel.Beauregard@Sun.COM {{{1, 0x3300000, 0x3304000, 0x1a0000}}}, /* 51: ROMUSB */
24211924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 52: */
24311924SDaniel.Beauregard@Sun.COM {{{1, 0x3500000, 0x3500400, 0x1ac000}}}, /* 53: RPMX0 */
24411924SDaniel.Beauregard@Sun.COM {{{1, 0x3600000, 0x3600400, 0x1ae000}}}, /* 54: RPMX8 */
24511924SDaniel.Beauregard@Sun.COM {{{1, 0x3700000, 0x3700400, 0x1ae400}}}, /* 55: RPMX9 */
24611924SDaniel.Beauregard@Sun.COM {{{1, 0x3800000, 0x3804000, 0x1d0000}}}, /* 56: OCM0 */
24711924SDaniel.Beauregard@Sun.COM {{{1, 0x3900000, 0x3904000, 0x1b4000}}}, /* 57: CRYPTO */
24811924SDaniel.Beauregard@Sun.COM {{{1, 0x3a00000, 0x3a04000, 0x1d8000}}}, /* 58: SMB */
24911924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 59: I2C0 */
25011924SDaniel.Beauregard@Sun.COM {{{0}}}, /* 60: I2C1 */
25111924SDaniel.Beauregard@Sun.COM {{{1, 0x3d00000, 0x3d04000, 0x1dc000}}}, /* 61: LPC */
25211924SDaniel.Beauregard@Sun.COM {{{1, 0x3e00000, 0x3e01000, 0x167000}}}, /* 62: P2NC */
25311924SDaniel.Beauregard@Sun.COM {{{1, 0x3f00000, 0x3f01000, 0x168000}}} /* 63: P2NR0 */
25411924SDaniel.Beauregard@Sun.COM };
25511924SDaniel.Beauregard@Sun.COM
25611924SDaniel.Beauregard@Sun.COM /*
25711924SDaniel.Beauregard@Sun.COM * top 12 bits of crb internal address (hub, agent)
25811924SDaniel.Beauregard@Sun.COM */
25911924SDaniel.Beauregard@Sun.COM static uint32_t crb_hub_agt[64] = {
26011924SDaniel.Beauregard@Sun.COM 0,
26111924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PS,
26211924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_MN,
26311924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_MS,
26411924SDaniel.Beauregard@Sun.COM 0,
26511924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_SRE,
26611924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_NIU,
26711924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_QMN,
26811924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_SQN0,
26911924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_SQN1,
27011924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_SQN2,
27111924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_SQN3,
27211924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_I2Q,
27311924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_TIMR,
27411924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
27511924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGN4,
27611924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_XDMA,
27711924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGN0,
27811924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGN1,
27911924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGN2,
28011924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGN3,
28111924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGND,
28211924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGNI,
28311924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGS0,
28411924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGS1,
28511924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGS2,
28611924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGS3,
28711924SDaniel.Beauregard@Sun.COM 0,
28811924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGSI,
28911924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_SN,
29011924SDaniel.Beauregard@Sun.COM 0,
29111924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_EG,
29211924SDaniel.Beauregard@Sun.COM 0,
29311924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PS,
29411924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_CAM,
29511924SDaniel.Beauregard@Sun.COM 0,
29611924SDaniel.Beauregard@Sun.COM 0,
29711924SDaniel.Beauregard@Sun.COM 0,
29811924SDaniel.Beauregard@Sun.COM 0,
29911924SDaniel.Beauregard@Sun.COM 0,
30011924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_TIMR,
30111924SDaniel.Beauregard@Sun.COM 0,
30211924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
30311924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
30411924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
30511924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
30611924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
30711924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
30811924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
30911924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_XDMA,
31011924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_I2Q,
31111924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
31211924SDaniel.Beauregard@Sun.COM 0,
31311924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
31411924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
31511924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
31611924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_OCM0,
31711924SDaniel.Beauregard@Sun.COM 0,
31811924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_SMB,
31911924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_I2C0,
32011924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_I2C1,
32111924SDaniel.Beauregard@Sun.COM 0,
32211924SDaniel.Beauregard@Sun.COM UNM_HW_CRB_HUB_AGT_ADR_PGNC,
32311924SDaniel.Beauregard@Sun.COM 0,
32411924SDaniel.Beauregard@Sun.COM };
32511924SDaniel.Beauregard@Sun.COM
32611924SDaniel.Beauregard@Sun.COM static void *
ql_8021_pci_base_offsetfset(ql_adapter_state_t * ha,uint64_t off)32711924SDaniel.Beauregard@Sun.COM ql_8021_pci_base_offsetfset(ql_adapter_state_t *ha, uint64_t off)
32811924SDaniel.Beauregard@Sun.COM {
32911924SDaniel.Beauregard@Sun.COM if ((off < ha->first_page_group_end) &&
33011924SDaniel.Beauregard@Sun.COM (off >= ha->first_page_group_start)) {
33111924SDaniel.Beauregard@Sun.COM return ((void *)(ha->nx_pcibase + off));
33211924SDaniel.Beauregard@Sun.COM }
33311924SDaniel.Beauregard@Sun.COM
33411924SDaniel.Beauregard@Sun.COM return (NULL);
33511924SDaniel.Beauregard@Sun.COM }
33611924SDaniel.Beauregard@Sun.COM
33711924SDaniel.Beauregard@Sun.COM /* ARGSUSED */
33811924SDaniel.Beauregard@Sun.COM static void
ql_crb_addr_transform_setup(ql_adapter_state_t * ha)33911924SDaniel.Beauregard@Sun.COM ql_crb_addr_transform_setup(ql_adapter_state_t *ha)
34011924SDaniel.Beauregard@Sun.COM {
34111924SDaniel.Beauregard@Sun.COM crb_addr_transform(XDMA);
34211924SDaniel.Beauregard@Sun.COM crb_addr_transform(TIMR);
34311924SDaniel.Beauregard@Sun.COM crb_addr_transform(SRE);
34411924SDaniel.Beauregard@Sun.COM crb_addr_transform(SQN3);
34511924SDaniel.Beauregard@Sun.COM crb_addr_transform(SQN2);
34611924SDaniel.Beauregard@Sun.COM crb_addr_transform(SQN1);
34711924SDaniel.Beauregard@Sun.COM crb_addr_transform(SQN0);
34811924SDaniel.Beauregard@Sun.COM crb_addr_transform(SQS3);
34911924SDaniel.Beauregard@Sun.COM crb_addr_transform(SQS2);
35011924SDaniel.Beauregard@Sun.COM crb_addr_transform(SQS1);
35111924SDaniel.Beauregard@Sun.COM crb_addr_transform(SQS0);
35211924SDaniel.Beauregard@Sun.COM crb_addr_transform(RPMX7);
35311924SDaniel.Beauregard@Sun.COM crb_addr_transform(RPMX6);
35411924SDaniel.Beauregard@Sun.COM crb_addr_transform(RPMX5);
35511924SDaniel.Beauregard@Sun.COM crb_addr_transform(RPMX4);
35611924SDaniel.Beauregard@Sun.COM crb_addr_transform(RPMX3);
35711924SDaniel.Beauregard@Sun.COM crb_addr_transform(RPMX2);
35811924SDaniel.Beauregard@Sun.COM crb_addr_transform(RPMX1);
35911924SDaniel.Beauregard@Sun.COM crb_addr_transform(RPMX0);
36011924SDaniel.Beauregard@Sun.COM crb_addr_transform(ROMUSB);
36111924SDaniel.Beauregard@Sun.COM crb_addr_transform(SN);
36211924SDaniel.Beauregard@Sun.COM crb_addr_transform(QMN);
36311924SDaniel.Beauregard@Sun.COM crb_addr_transform(QMS);
36411924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGNI);
36511924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGND);
36611924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGN3);
36711924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGN2);
36811924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGN1);
36911924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGN0);
37011924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGSI);
37111924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGSD);
37211924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGS3);
37311924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGS2);
37411924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGS1);
37511924SDaniel.Beauregard@Sun.COM crb_addr_transform(PGS0);
37611924SDaniel.Beauregard@Sun.COM crb_addr_transform(PS);
37711924SDaniel.Beauregard@Sun.COM crb_addr_transform(PH);
37811924SDaniel.Beauregard@Sun.COM crb_addr_transform(NIU);
37911924SDaniel.Beauregard@Sun.COM crb_addr_transform(I2Q);
38011924SDaniel.Beauregard@Sun.COM crb_addr_transform(EG);
38111924SDaniel.Beauregard@Sun.COM crb_addr_transform(MN);
38211924SDaniel.Beauregard@Sun.COM crb_addr_transform(MS);
38311924SDaniel.Beauregard@Sun.COM crb_addr_transform(CAS2);
38411924SDaniel.Beauregard@Sun.COM crb_addr_transform(CAS1);
38511924SDaniel.Beauregard@Sun.COM crb_addr_transform(CAS0);
38611924SDaniel.Beauregard@Sun.COM crb_addr_transform(CAM);
38711924SDaniel.Beauregard@Sun.COM crb_addr_transform(C2C1);
38811924SDaniel.Beauregard@Sun.COM crb_addr_transform(C2C0);
38911924SDaniel.Beauregard@Sun.COM crb_addr_transform(SMB);
39011924SDaniel.Beauregard@Sun.COM crb_addr_transform(OCM0);
39111924SDaniel.Beauregard@Sun.COM /*
39211924SDaniel.Beauregard@Sun.COM * Used only in P3 just define it for P2 also.
39311924SDaniel.Beauregard@Sun.COM */
39411924SDaniel.Beauregard@Sun.COM crb_addr_transform(I2C0);
39511924SDaniel.Beauregard@Sun.COM
39611924SDaniel.Beauregard@Sun.COM crb_table_initialized = 1;
39711924SDaniel.Beauregard@Sun.COM }
39811924SDaniel.Beauregard@Sun.COM
39911924SDaniel.Beauregard@Sun.COM /*
40011924SDaniel.Beauregard@Sun.COM * In: 'off' is offset from CRB space in 128M pci map
40111924SDaniel.Beauregard@Sun.COM * Out: 'off' is 2M pci map addr
40211924SDaniel.Beauregard@Sun.COM * side effect: lock crb window
40311924SDaniel.Beauregard@Sun.COM */
40411924SDaniel.Beauregard@Sun.COM static void
ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t * ha,uint64_t * off)40511924SDaniel.Beauregard@Sun.COM ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *ha, uint64_t *off)
40611924SDaniel.Beauregard@Sun.COM {
40711924SDaniel.Beauregard@Sun.COM uint32_t win_read;
40811924SDaniel.Beauregard@Sun.COM
40911924SDaniel.Beauregard@Sun.COM ha->crb_win = (uint32_t)CRB_HI(*off);
41011924SDaniel.Beauregard@Sun.COM WRT_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase, ha->crb_win);
41111924SDaniel.Beauregard@Sun.COM
41211924SDaniel.Beauregard@Sun.COM /*
41311924SDaniel.Beauregard@Sun.COM * Read back value to make sure write has gone through before trying
41411924SDaniel.Beauregard@Sun.COM * to use it.
41511924SDaniel.Beauregard@Sun.COM */
41611924SDaniel.Beauregard@Sun.COM win_read = RD_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase);
41711924SDaniel.Beauregard@Sun.COM if (win_read != ha->crb_win) {
41811924SDaniel.Beauregard@Sun.COM EL(ha, "Written crbwin (0x%x) != Read crbwin (0x%x), "
41911924SDaniel.Beauregard@Sun.COM "off=0x%llx\n", ha->crb_win, win_read, *off);
42011924SDaniel.Beauregard@Sun.COM }
42111924SDaniel.Beauregard@Sun.COM *off = (*off & MASK(16)) + CRB_INDIRECT_2M + (uintptr_t)ha->nx_pcibase;
42211924SDaniel.Beauregard@Sun.COM }
42311924SDaniel.Beauregard@Sun.COM
42411924SDaniel.Beauregard@Sun.COM static void
ql_8021_wr_32(ql_adapter_state_t * ha,uint64_t off,uint32_t data)42511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ql_adapter_state_t *ha, uint64_t off, uint32_t data)
42611924SDaniel.Beauregard@Sun.COM {
42711924SDaniel.Beauregard@Sun.COM int rv;
42811924SDaniel.Beauregard@Sun.COM
42911924SDaniel.Beauregard@Sun.COM rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
43011924SDaniel.Beauregard@Sun.COM if (rv == -1) {
43111924SDaniel.Beauregard@Sun.COM cmn_err(CE_PANIC, "ql_8021_wr_32, ql_8021_pci_get_crb_addr_"
43211924SDaniel.Beauregard@Sun.COM "2M=-1\n");
43311924SDaniel.Beauregard@Sun.COM }
43411924SDaniel.Beauregard@Sun.COM if (rv == 1) {
43511924SDaniel.Beauregard@Sun.COM (void) ql_8021_crb_win_lock(ha);
43611924SDaniel.Beauregard@Sun.COM ql_8021_pci_set_crbwindow_2M(ha, &off);
43711924SDaniel.Beauregard@Sun.COM }
43811924SDaniel.Beauregard@Sun.COM
43911924SDaniel.Beauregard@Sun.COM WRT_REG_DWORD(ha, (uintptr_t)off, data);
44011924SDaniel.Beauregard@Sun.COM
44111924SDaniel.Beauregard@Sun.COM if (rv == 1) {
44211924SDaniel.Beauregard@Sun.COM ql_8021_crb_win_unlock(ha);
44311924SDaniel.Beauregard@Sun.COM }
44411924SDaniel.Beauregard@Sun.COM }
44511924SDaniel.Beauregard@Sun.COM
44611924SDaniel.Beauregard@Sun.COM static void
ql_8021_rd_32(ql_adapter_state_t * ha,uint64_t off,uint32_t * data)44711924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ql_adapter_state_t *ha, uint64_t off, uint32_t *data)
44811924SDaniel.Beauregard@Sun.COM {
44911924SDaniel.Beauregard@Sun.COM int rv;
45011924SDaniel.Beauregard@Sun.COM uint32_t n;
45111924SDaniel.Beauregard@Sun.COM
45211924SDaniel.Beauregard@Sun.COM rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
45311924SDaniel.Beauregard@Sun.COM if (rv == -1) {
45411924SDaniel.Beauregard@Sun.COM cmn_err(CE_PANIC, "ql_8021_rd_32, ql_8021_pci_get_crb_addr_"
45511924SDaniel.Beauregard@Sun.COM "2M=-1\n");
45611924SDaniel.Beauregard@Sun.COM }
45711924SDaniel.Beauregard@Sun.COM
45811924SDaniel.Beauregard@Sun.COM if (rv == 1) {
45911924SDaniel.Beauregard@Sun.COM (void) ql_8021_crb_win_lock(ha);
46011924SDaniel.Beauregard@Sun.COM ql_8021_pci_set_crbwindow_2M(ha, &off);
46111924SDaniel.Beauregard@Sun.COM }
46211924SDaniel.Beauregard@Sun.COM n = RD_REG_DWORD(ha, (uintptr_t)off);
46311924SDaniel.Beauregard@Sun.COM
46411924SDaniel.Beauregard@Sun.COM if (data != NULL) {
46511924SDaniel.Beauregard@Sun.COM *data = n;
46611924SDaniel.Beauregard@Sun.COM }
46711924SDaniel.Beauregard@Sun.COM
46811924SDaniel.Beauregard@Sun.COM if (rv == 1) {
46911924SDaniel.Beauregard@Sun.COM ql_8021_crb_win_unlock(ha);
47011924SDaniel.Beauregard@Sun.COM }
47111924SDaniel.Beauregard@Sun.COM }
47211924SDaniel.Beauregard@Sun.COM
47311924SDaniel.Beauregard@Sun.COM static int
ql_8021_crb_win_lock(ql_adapter_state_t * ha)47411924SDaniel.Beauregard@Sun.COM ql_8021_crb_win_lock(ql_adapter_state_t *ha)
47511924SDaniel.Beauregard@Sun.COM {
47611924SDaniel.Beauregard@Sun.COM uint32_t done = 0, timeout = 0;
47711924SDaniel.Beauregard@Sun.COM
47811924SDaniel.Beauregard@Sun.COM while (!done) {
47911924SDaniel.Beauregard@Sun.COM /* acquire semaphore3 from PCI HW block */
48011924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_LOCK), &done);
48111924SDaniel.Beauregard@Sun.COM if (done == 1) {
48211924SDaniel.Beauregard@Sun.COM break;
48311924SDaniel.Beauregard@Sun.COM }
48411924SDaniel.Beauregard@Sun.COM if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
48511924SDaniel.Beauregard@Sun.COM EL(ha, "timeout\n");
48611924SDaniel.Beauregard@Sun.COM return (-1);
48711924SDaniel.Beauregard@Sun.COM }
48811924SDaniel.Beauregard@Sun.COM timeout++;
48911924SDaniel.Beauregard@Sun.COM
49011924SDaniel.Beauregard@Sun.COM /* Yield CPU */
49111924SDaniel.Beauregard@Sun.COM delay(1);
49211924SDaniel.Beauregard@Sun.COM }
49311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_WIN_LOCK_ID, ha->function_number);
49411924SDaniel.Beauregard@Sun.COM
49511924SDaniel.Beauregard@Sun.COM return (0);
49611924SDaniel.Beauregard@Sun.COM }
49711924SDaniel.Beauregard@Sun.COM
49811924SDaniel.Beauregard@Sun.COM static void
ql_8021_crb_win_unlock(ql_adapter_state_t * ha)49911924SDaniel.Beauregard@Sun.COM ql_8021_crb_win_unlock(ql_adapter_state_t *ha)
50011924SDaniel.Beauregard@Sun.COM {
50111924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_UNLOCK), NULL);
50211924SDaniel.Beauregard@Sun.COM }
50311924SDaniel.Beauregard@Sun.COM
50411924SDaniel.Beauregard@Sun.COM static int
ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t * ha,uint64_t * off)50511924SDaniel.Beauregard@Sun.COM ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *ha, uint64_t *off)
50611924SDaniel.Beauregard@Sun.COM {
50711924SDaniel.Beauregard@Sun.COM crb_128M_2M_sub_block_map_t *m;
50811924SDaniel.Beauregard@Sun.COM
50911924SDaniel.Beauregard@Sun.COM if (*off >= UNM_CRB_MAX) {
51011924SDaniel.Beauregard@Sun.COM EL(ha, "%llx >= %llx\n", *off, UNM_CRB_MAX);
51111924SDaniel.Beauregard@Sun.COM return (-1);
51211924SDaniel.Beauregard@Sun.COM }
51311924SDaniel.Beauregard@Sun.COM
51411924SDaniel.Beauregard@Sun.COM if (*off >= UNM_PCI_CAMQM && (*off < UNM_PCI_CAMQM_2M_END)) {
51511924SDaniel.Beauregard@Sun.COM *off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
51611924SDaniel.Beauregard@Sun.COM (uintptr_t)ha->nx_pcibase;
51711924SDaniel.Beauregard@Sun.COM return (0);
51811924SDaniel.Beauregard@Sun.COM }
51911924SDaniel.Beauregard@Sun.COM
52011924SDaniel.Beauregard@Sun.COM if (*off < UNM_PCI_CRBSPACE) {
52111924SDaniel.Beauregard@Sun.COM EL(ha, "%llx < %llx\n", *off, UNM_PCI_CRBSPACE);
52211924SDaniel.Beauregard@Sun.COM return (-1);
52311924SDaniel.Beauregard@Sun.COM }
52411924SDaniel.Beauregard@Sun.COM
52511924SDaniel.Beauregard@Sun.COM *off -= UNM_PCI_CRBSPACE;
52611924SDaniel.Beauregard@Sun.COM /*
52711924SDaniel.Beauregard@Sun.COM * Try direct map
52811924SDaniel.Beauregard@Sun.COM */
52911924SDaniel.Beauregard@Sun.COM
53011924SDaniel.Beauregard@Sun.COM m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
53111924SDaniel.Beauregard@Sun.COM
53211924SDaniel.Beauregard@Sun.COM if (m->valid && ((uint64_t)m->start_128M <= *off) &&
53311924SDaniel.Beauregard@Sun.COM ((uint64_t)m->end_128M > *off)) {
53411924SDaniel.Beauregard@Sun.COM *off = (uint64_t)(*off + m->start_2M - m->start_128M +
53511924SDaniel.Beauregard@Sun.COM (uintptr_t)ha->nx_pcibase);
53611924SDaniel.Beauregard@Sun.COM return (0);
53711924SDaniel.Beauregard@Sun.COM }
53811924SDaniel.Beauregard@Sun.COM
53911924SDaniel.Beauregard@Sun.COM /*
54011924SDaniel.Beauregard@Sun.COM * Not in direct map, use crb window
54111924SDaniel.Beauregard@Sun.COM */
54211924SDaniel.Beauregard@Sun.COM return (1);
54311924SDaniel.Beauregard@Sun.COM }
54411924SDaniel.Beauregard@Sun.COM
54511924SDaniel.Beauregard@Sun.COM /*
54611924SDaniel.Beauregard@Sun.COM * check memory access boundary.
54711924SDaniel.Beauregard@Sun.COM * used by test agent. support ddr access only for now
54811924SDaniel.Beauregard@Sun.COM */
54911924SDaniel.Beauregard@Sun.COM /* ARGSUSED */
55011924SDaniel.Beauregard@Sun.COM static uint32_t
ql_8021_pci_mem_bound_check(ql_adapter_state_t * ha,uint64_t addr,uint32_t size)55111924SDaniel.Beauregard@Sun.COM ql_8021_pci_mem_bound_check(ql_adapter_state_t *ha, uint64_t addr,
55211924SDaniel.Beauregard@Sun.COM uint32_t size)
55311924SDaniel.Beauregard@Sun.COM {
55411924SDaniel.Beauregard@Sun.COM /*LINTED suspicious 0 comparison*/
55511924SDaniel.Beauregard@Sun.COM if (!QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
55611924SDaniel.Beauregard@Sun.COM UNM_ADDR_DDR_NET_MAX) ||
55711924SDaniel.Beauregard@Sun.COM /*LINTED suspicious 0 comparison*/
55811924SDaniel.Beauregard@Sun.COM !QL_8021_ADDR_IN_RANGE(addr + size - 1, UNM_ADDR_DDR_NET,
55911924SDaniel.Beauregard@Sun.COM UNM_ADDR_DDR_NET_MAX) ||
56011924SDaniel.Beauregard@Sun.COM ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
56111924SDaniel.Beauregard@Sun.COM return (0);
56211924SDaniel.Beauregard@Sun.COM }
56311924SDaniel.Beauregard@Sun.COM
56411924SDaniel.Beauregard@Sun.COM return (1);
56511924SDaniel.Beauregard@Sun.COM }
56611924SDaniel.Beauregard@Sun.COM
56711924SDaniel.Beauregard@Sun.COM static uint64_t
ql_8021_pci_set_window(ql_adapter_state_t * ha,uint64_t addr)56811924SDaniel.Beauregard@Sun.COM ql_8021_pci_set_window(ql_adapter_state_t *ha, uint64_t addr)
56911924SDaniel.Beauregard@Sun.COM {
57011924SDaniel.Beauregard@Sun.COM uint32_t window, win_read;
57111924SDaniel.Beauregard@Sun.COM
57211924SDaniel.Beauregard@Sun.COM /*LINTED suspicious 0 comparison*/
57311924SDaniel.Beauregard@Sun.COM if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
57411924SDaniel.Beauregard@Sun.COM UNM_ADDR_DDR_NET_MAX)) {
57511924SDaniel.Beauregard@Sun.COM /* DDR network side */
57611924SDaniel.Beauregard@Sun.COM window = (uint32_t)MN_WIN(addr);
57711924SDaniel.Beauregard@Sun.COM ha->ddr_mn_window = window;
57811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
57911924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
58011924SDaniel.Beauregard@Sun.COM &win_read);
58111924SDaniel.Beauregard@Sun.COM if ((win_read << 17) != window) {
58211924SDaniel.Beauregard@Sun.COM EL(ha, "Warning, Written MNwin (0x%x) != Read MNwin "
58311924SDaniel.Beauregard@Sun.COM "(0x%x)\n", window, win_read);
58411924SDaniel.Beauregard@Sun.COM }
58511924SDaniel.Beauregard@Sun.COM addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
58611924SDaniel.Beauregard@Sun.COM } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
58711924SDaniel.Beauregard@Sun.COM UNM_ADDR_OCM0_MAX)) {
58811924SDaniel.Beauregard@Sun.COM uint32_t temp1;
58911924SDaniel.Beauregard@Sun.COM
59011924SDaniel.Beauregard@Sun.COM if ((addr & 0x00ff800) == 0xff800) {
59111924SDaniel.Beauregard@Sun.COM /* if bits 19:18&17:11 are on */
59211924SDaniel.Beauregard@Sun.COM EL(ha, "QM access not handled\n");
59311924SDaniel.Beauregard@Sun.COM addr = -1UL;
59411924SDaniel.Beauregard@Sun.COM }
59511924SDaniel.Beauregard@Sun.COM
59611924SDaniel.Beauregard@Sun.COM window = (uint32_t)OCM_WIN(addr);
59711924SDaniel.Beauregard@Sun.COM ha->ddr_mn_window = window;
59811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
59911924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
60011924SDaniel.Beauregard@Sun.COM &win_read);
60111924SDaniel.Beauregard@Sun.COM temp1 = ((window & 0x1FF) << 7) |
60211924SDaniel.Beauregard@Sun.COM ((window & 0x0FFFE0000) >> 17);
60311924SDaniel.Beauregard@Sun.COM if (win_read != temp1) {
60411924SDaniel.Beauregard@Sun.COM EL(ha, "Written OCMwin (0x%x) != Read OCMwin (0x%x)\n",
60511924SDaniel.Beauregard@Sun.COM temp1, win_read);
60611924SDaniel.Beauregard@Sun.COM }
60711924SDaniel.Beauregard@Sun.COM addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
60811924SDaniel.Beauregard@Sun.COM } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
60911924SDaniel.Beauregard@Sun.COM NX_P3_ADDR_QDR_NET_MAX)) {
61011924SDaniel.Beauregard@Sun.COM /* QDR network side */
61111924SDaniel.Beauregard@Sun.COM window = (uint32_t)MS_WIN(addr);
61211924SDaniel.Beauregard@Sun.COM ha->qdr_sn_window = window;
61311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
61411924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
61511924SDaniel.Beauregard@Sun.COM &win_read);
61611924SDaniel.Beauregard@Sun.COM if (win_read != window) {
61711924SDaniel.Beauregard@Sun.COM EL(ha, "Written MSwin (0x%x) != Read MSwin (0x%x)\n",
61811924SDaniel.Beauregard@Sun.COM window, win_read);
61911924SDaniel.Beauregard@Sun.COM }
62011924SDaniel.Beauregard@Sun.COM addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
62111924SDaniel.Beauregard@Sun.COM } else {
62211924SDaniel.Beauregard@Sun.COM /*
62311924SDaniel.Beauregard@Sun.COM * peg gdb frequently accesses memory that doesn't exist,
62411924SDaniel.Beauregard@Sun.COM * this limits the chit chat so debugging isn't slowed down.
62511924SDaniel.Beauregard@Sun.COM */
62611924SDaniel.Beauregard@Sun.COM if ((pci_set_window_warning_count++ < 8) ||
62711924SDaniel.Beauregard@Sun.COM (pci_set_window_warning_count % 64 == 0)) {
62811924SDaniel.Beauregard@Sun.COM EL(ha, "Unknown address range\n");
62911924SDaniel.Beauregard@Sun.COM }
63011924SDaniel.Beauregard@Sun.COM addr = -1UL;
63111924SDaniel.Beauregard@Sun.COM }
63211924SDaniel.Beauregard@Sun.COM
63311924SDaniel.Beauregard@Sun.COM return (addr);
63411924SDaniel.Beauregard@Sun.COM }
63511924SDaniel.Beauregard@Sun.COM
63611924SDaniel.Beauregard@Sun.COM /* check if address is in the same windows as the previous access */
63711924SDaniel.Beauregard@Sun.COM static int
ql_8021_pci_is_same_window(ql_adapter_state_t * ha,uint64_t addr)63811924SDaniel.Beauregard@Sun.COM ql_8021_pci_is_same_window(ql_adapter_state_t *ha, uint64_t addr)
63911924SDaniel.Beauregard@Sun.COM {
64011924SDaniel.Beauregard@Sun.COM uint32_t window;
64111924SDaniel.Beauregard@Sun.COM uint64_t qdr_max;
64211924SDaniel.Beauregard@Sun.COM
64311924SDaniel.Beauregard@Sun.COM qdr_max = NX_P3_ADDR_QDR_NET_MAX;
64411924SDaniel.Beauregard@Sun.COM
64511924SDaniel.Beauregard@Sun.COM /*LINTED suspicious 0 comparison*/
64611924SDaniel.Beauregard@Sun.COM if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
64711924SDaniel.Beauregard@Sun.COM UNM_ADDR_DDR_NET_MAX)) {
64811924SDaniel.Beauregard@Sun.COM /* DDR network side */
64911924SDaniel.Beauregard@Sun.COM EL(ha, "DDR network side\n");
65011924SDaniel.Beauregard@Sun.COM return (0); /* MN access can not come here */
65111924SDaniel.Beauregard@Sun.COM } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
65211924SDaniel.Beauregard@Sun.COM UNM_ADDR_OCM0_MAX)) {
65311924SDaniel.Beauregard@Sun.COM return (1);
65411924SDaniel.Beauregard@Sun.COM } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM1,
65511924SDaniel.Beauregard@Sun.COM UNM_ADDR_OCM1_MAX)) {
65611924SDaniel.Beauregard@Sun.COM return (1);
65711924SDaniel.Beauregard@Sun.COM } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
65811924SDaniel.Beauregard@Sun.COM /* QDR network side */
65911924SDaniel.Beauregard@Sun.COM window = (uint32_t)(((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f);
66011924SDaniel.Beauregard@Sun.COM if (ha->qdr_sn_window == window) {
66111924SDaniel.Beauregard@Sun.COM return (1);
66211924SDaniel.Beauregard@Sun.COM }
66311924SDaniel.Beauregard@Sun.COM }
66411924SDaniel.Beauregard@Sun.COM
66511924SDaniel.Beauregard@Sun.COM return (0);
66611924SDaniel.Beauregard@Sun.COM }
66711924SDaniel.Beauregard@Sun.COM
66811924SDaniel.Beauregard@Sun.COM static int
ql_8021_pci_mem_read_direct(ql_adapter_state_t * ha,uint64_t off,void * data,uint32_t size)66911924SDaniel.Beauregard@Sun.COM ql_8021_pci_mem_read_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
67011924SDaniel.Beauregard@Sun.COM uint32_t size)
67111924SDaniel.Beauregard@Sun.COM {
67211924SDaniel.Beauregard@Sun.COM void *addr;
67311924SDaniel.Beauregard@Sun.COM int ret = 0;
67411924SDaniel.Beauregard@Sun.COM uint64_t start;
67511924SDaniel.Beauregard@Sun.COM
67611924SDaniel.Beauregard@Sun.COM /*
67711924SDaniel.Beauregard@Sun.COM * If attempting to access unknown address or straddle hw windows,
67811924SDaniel.Beauregard@Sun.COM * do not access.
67911924SDaniel.Beauregard@Sun.COM */
68011924SDaniel.Beauregard@Sun.COM if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
68111924SDaniel.Beauregard@Sun.COM (ql_8021_pci_is_same_window(ha, off + size - 1) == 0)) {
68211924SDaniel.Beauregard@Sun.COM EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
68311924SDaniel.Beauregard@Sun.COM off);
68411924SDaniel.Beauregard@Sun.COM return (-1);
68511924SDaniel.Beauregard@Sun.COM }
68611924SDaniel.Beauregard@Sun.COM
68711924SDaniel.Beauregard@Sun.COM addr = ql_8021_pci_base_offsetfset(ha, start);
68811924SDaniel.Beauregard@Sun.COM if (!addr) {
68911924SDaniel.Beauregard@Sun.COM addr = (void *)((uint8_t *)ha->nx_pcibase + start);
69011924SDaniel.Beauregard@Sun.COM }
69111924SDaniel.Beauregard@Sun.COM
69211924SDaniel.Beauregard@Sun.COM switch (size) {
69311924SDaniel.Beauregard@Sun.COM case 1:
69411924SDaniel.Beauregard@Sun.COM *(uint8_t *)data = RD_REG_BYTE(ha, addr);
69511924SDaniel.Beauregard@Sun.COM break;
69611924SDaniel.Beauregard@Sun.COM case 2:
69711924SDaniel.Beauregard@Sun.COM *(uint16_t *)data = RD_REG_WORD(ha, addr);
69811924SDaniel.Beauregard@Sun.COM break;
69911924SDaniel.Beauregard@Sun.COM case 4:
70011924SDaniel.Beauregard@Sun.COM *(uint32_t *)data = RD_REG_DWORD(ha, addr);
70111924SDaniel.Beauregard@Sun.COM break;
70211924SDaniel.Beauregard@Sun.COM case 8:
70311924SDaniel.Beauregard@Sun.COM *(uint64_t *)data = RD_REG_DDWORD(ha, addr);
70411924SDaniel.Beauregard@Sun.COM break;
70511924SDaniel.Beauregard@Sun.COM default:
70611924SDaniel.Beauregard@Sun.COM EL(ha, "invalid size=%x\n", size);
70711924SDaniel.Beauregard@Sun.COM ret = -1;
70811924SDaniel.Beauregard@Sun.COM break;
70911924SDaniel.Beauregard@Sun.COM }
71011924SDaniel.Beauregard@Sun.COM
71111924SDaniel.Beauregard@Sun.COM return (ret);
71211924SDaniel.Beauregard@Sun.COM }
71311924SDaniel.Beauregard@Sun.COM
71411924SDaniel.Beauregard@Sun.COM static int
ql_8021_pci_mem_write_direct(ql_adapter_state_t * ha,uint64_t off,void * data,uint32_t size)71511924SDaniel.Beauregard@Sun.COM ql_8021_pci_mem_write_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
71611924SDaniel.Beauregard@Sun.COM uint32_t size)
71711924SDaniel.Beauregard@Sun.COM {
71811924SDaniel.Beauregard@Sun.COM void *addr;
71911924SDaniel.Beauregard@Sun.COM int ret = 0;
72011924SDaniel.Beauregard@Sun.COM uint64_t start;
72111924SDaniel.Beauregard@Sun.COM
72211924SDaniel.Beauregard@Sun.COM /*
72311924SDaniel.Beauregard@Sun.COM * If attempting to access unknown address or straddle hw windows,
72411924SDaniel.Beauregard@Sun.COM * do not access.
72511924SDaniel.Beauregard@Sun.COM */
72611924SDaniel.Beauregard@Sun.COM if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
72711924SDaniel.Beauregard@Sun.COM (ql_8021_pci_is_same_window(ha, off + size -1) == 0)) {
72811924SDaniel.Beauregard@Sun.COM EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
72911924SDaniel.Beauregard@Sun.COM off);
73011924SDaniel.Beauregard@Sun.COM return (-1);
73111924SDaniel.Beauregard@Sun.COM }
73211924SDaniel.Beauregard@Sun.COM
73311924SDaniel.Beauregard@Sun.COM addr = ql_8021_pci_base_offsetfset(ha, start);
73411924SDaniel.Beauregard@Sun.COM if (!addr) {
73511924SDaniel.Beauregard@Sun.COM addr = (void *)((uint8_t *)ha->nx_pcibase + start);
73611924SDaniel.Beauregard@Sun.COM }
73711924SDaniel.Beauregard@Sun.COM
73811924SDaniel.Beauregard@Sun.COM switch (size) {
73911924SDaniel.Beauregard@Sun.COM case 1:
74011924SDaniel.Beauregard@Sun.COM WRT_REG_BYTE(ha, addr, *(uint8_t *)data);
74111924SDaniel.Beauregard@Sun.COM break;
74211924SDaniel.Beauregard@Sun.COM case 2:
74311924SDaniel.Beauregard@Sun.COM WRT_REG_WORD(ha, addr, *(uint16_t *)data);
74411924SDaniel.Beauregard@Sun.COM break;
74511924SDaniel.Beauregard@Sun.COM case 4:
74611924SDaniel.Beauregard@Sun.COM WRT_REG_DWORD(ha, addr, *(uint32_t *)data);
74711924SDaniel.Beauregard@Sun.COM break;
74811924SDaniel.Beauregard@Sun.COM case 8:
74911924SDaniel.Beauregard@Sun.COM WRT_REG_DDWORD(ha, addr, *(uint64_t *)data);
75011924SDaniel.Beauregard@Sun.COM break;
75111924SDaniel.Beauregard@Sun.COM default:
75211924SDaniel.Beauregard@Sun.COM EL(ha, "invalid size=%x\n", size);
75311924SDaniel.Beauregard@Sun.COM ret = -1;
75411924SDaniel.Beauregard@Sun.COM break;
75511924SDaniel.Beauregard@Sun.COM }
75611924SDaniel.Beauregard@Sun.COM
75711924SDaniel.Beauregard@Sun.COM return (ret);
75811924SDaniel.Beauregard@Sun.COM }
75911924SDaniel.Beauregard@Sun.COM
76011924SDaniel.Beauregard@Sun.COM static int
ql_8021_pci_mem_read_2M(ql_adapter_state_t * ha,uint64_t off,void * data,uint32_t size)76111924SDaniel.Beauregard@Sun.COM ql_8021_pci_mem_read_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
76211924SDaniel.Beauregard@Sun.COM uint32_t size)
76311924SDaniel.Beauregard@Sun.COM {
76411924SDaniel.Beauregard@Sun.COM int j = 0;
76511924SDaniel.Beauregard@Sun.COM uint32_t i, temp, sz[2], loop, shift_amount;
76611924SDaniel.Beauregard@Sun.COM uint64_t start, end, k;
76711924SDaniel.Beauregard@Sun.COM uint64_t off8, off0[2], val, mem_crb, word[2] = {0, 0};
76811924SDaniel.Beauregard@Sun.COM
76911924SDaniel.Beauregard@Sun.COM /*
77011924SDaniel.Beauregard@Sun.COM * If not MN, go check for MS or invalid.
77111924SDaniel.Beauregard@Sun.COM */
77211924SDaniel.Beauregard@Sun.COM
77311924SDaniel.Beauregard@Sun.COM if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
77411924SDaniel.Beauregard@Sun.COM mem_crb = UNM_CRB_QDR_NET;
77511924SDaniel.Beauregard@Sun.COM } else {
77611924SDaniel.Beauregard@Sun.COM mem_crb = UNM_CRB_DDR_NET;
77711924SDaniel.Beauregard@Sun.COM if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
77811924SDaniel.Beauregard@Sun.COM return (ql_8021_pci_mem_read_direct(ha, off, data,
77911924SDaniel.Beauregard@Sun.COM size));
78011924SDaniel.Beauregard@Sun.COM }
78111924SDaniel.Beauregard@Sun.COM }
78211924SDaniel.Beauregard@Sun.COM
78311924SDaniel.Beauregard@Sun.COM if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
78411924SDaniel.Beauregard@Sun.COM off8 = off & 0xfffffff0;
78511924SDaniel.Beauregard@Sun.COM off0[0] = off & 0xf;
78611924SDaniel.Beauregard@Sun.COM sz[0] = (uint32_t)(((uint64_t)size < (16 - off0[0])) ? size :
78711924SDaniel.Beauregard@Sun.COM (16 - off0[0]));
78811924SDaniel.Beauregard@Sun.COM shift_amount = 4;
78911924SDaniel.Beauregard@Sun.COM } else {
79011924SDaniel.Beauregard@Sun.COM off8 = off & 0xfffffff8;
79111924SDaniel.Beauregard@Sun.COM off0[0] = off & 0x7;
79211924SDaniel.Beauregard@Sun.COM sz[0] = (uint32_t)(((uint64_t)size < (8 - off0[0])) ? size :
79311924SDaniel.Beauregard@Sun.COM (8 - off0[0]));
79411924SDaniel.Beauregard@Sun.COM shift_amount = 3;
79511924SDaniel.Beauregard@Sun.COM }
79611924SDaniel.Beauregard@Sun.COM loop = (uint32_t)(((off0[0] + size - 1) >> shift_amount) + 1);
79711924SDaniel.Beauregard@Sun.COM off0[1] = 0;
79811924SDaniel.Beauregard@Sun.COM sz[1] = size - sz[0];
79911924SDaniel.Beauregard@Sun.COM
80011924SDaniel.Beauregard@Sun.COM /*
80111924SDaniel.Beauregard@Sun.COM * don't lock here - write_wx gets the lock if each time
80211924SDaniel.Beauregard@Sun.COM * write_lock_irqsave(&adapter->adapter_lock, flags);
80311924SDaniel.Beauregard@Sun.COM * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
80411924SDaniel.Beauregard@Sun.COM */
80511924SDaniel.Beauregard@Sun.COM
80611924SDaniel.Beauregard@Sun.COM for (i = 0; i < loop; i++) {
80711924SDaniel.Beauregard@Sun.COM temp = (uint32_t)(off8 + (i << shift_amount));
80811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
80911924SDaniel.Beauregard@Sun.COM temp = 0;
81011924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
81111924SDaniel.Beauregard@Sun.COM temp = MIU_TA_CTL_ENABLE;
81211924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
81311924SDaniel.Beauregard@Sun.COM temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
81411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
81511924SDaniel.Beauregard@Sun.COM
81611924SDaniel.Beauregard@Sun.COM for (j = 0; j < MAX_CTL_CHECK; j++) {
81711924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
81811924SDaniel.Beauregard@Sun.COM if ((temp & MIU_TA_CTL_BUSY) == 0) {
81911924SDaniel.Beauregard@Sun.COM break;
82011924SDaniel.Beauregard@Sun.COM }
82111924SDaniel.Beauregard@Sun.COM }
82211924SDaniel.Beauregard@Sun.COM
82311924SDaniel.Beauregard@Sun.COM if (j >= MAX_CTL_CHECK) {
82411924SDaniel.Beauregard@Sun.COM EL(ha, "failed to read through agent\n");
82511924SDaniel.Beauregard@Sun.COM break;
82611924SDaniel.Beauregard@Sun.COM }
82711924SDaniel.Beauregard@Sun.COM
82811924SDaniel.Beauregard@Sun.COM start = off0[i] >> 2;
82911924SDaniel.Beauregard@Sun.COM end = (off0[i] + sz[i] - 1) >> 2;
83011924SDaniel.Beauregard@Sun.COM for (k = start; k <= end; k++) {
83111924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_RDDATA(k),
83211924SDaniel.Beauregard@Sun.COM &temp);
83311924SDaniel.Beauregard@Sun.COM word[i] |= ((uint64_t)temp << (32 * (k & 1)));
83411924SDaniel.Beauregard@Sun.COM }
83511924SDaniel.Beauregard@Sun.COM }
83611924SDaniel.Beauregard@Sun.COM
83711924SDaniel.Beauregard@Sun.COM /*
83811924SDaniel.Beauregard@Sun.COM * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
83911924SDaniel.Beauregard@Sun.COM * write_unlock_irqrestore(&adapter->adapter_lock, flags);
84011924SDaniel.Beauregard@Sun.COM */
84111924SDaniel.Beauregard@Sun.COM
84211924SDaniel.Beauregard@Sun.COM if (j >= MAX_CTL_CHECK) {
84311924SDaniel.Beauregard@Sun.COM return (-1);
84411924SDaniel.Beauregard@Sun.COM }
84511924SDaniel.Beauregard@Sun.COM
84611924SDaniel.Beauregard@Sun.COM if ((off0[0] & 7) == 0) {
84711924SDaniel.Beauregard@Sun.COM val = word[0];
84811924SDaniel.Beauregard@Sun.COM } else {
84911924SDaniel.Beauregard@Sun.COM val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
85011924SDaniel.Beauregard@Sun.COM ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
85111924SDaniel.Beauregard@Sun.COM }
85211924SDaniel.Beauregard@Sun.COM
85311924SDaniel.Beauregard@Sun.COM switch (size) {
85411924SDaniel.Beauregard@Sun.COM case 1:
85511924SDaniel.Beauregard@Sun.COM *(uint8_t *)data = (uint8_t)val;
85611924SDaniel.Beauregard@Sun.COM break;
85711924SDaniel.Beauregard@Sun.COM case 2:
85811924SDaniel.Beauregard@Sun.COM *(uint16_t *)data = (uint16_t)val;
85911924SDaniel.Beauregard@Sun.COM break;
86011924SDaniel.Beauregard@Sun.COM case 4:
86111924SDaniel.Beauregard@Sun.COM *(uint32_t *)data = (uint32_t)val;
86211924SDaniel.Beauregard@Sun.COM break;
86311924SDaniel.Beauregard@Sun.COM case 8:
86411924SDaniel.Beauregard@Sun.COM *(uint64_t *)data = val;
86511924SDaniel.Beauregard@Sun.COM break;
86611924SDaniel.Beauregard@Sun.COM }
86711924SDaniel.Beauregard@Sun.COM
86811924SDaniel.Beauregard@Sun.COM return (0);
86911924SDaniel.Beauregard@Sun.COM }
87011924SDaniel.Beauregard@Sun.COM
87111924SDaniel.Beauregard@Sun.COM static int
ql_8021_pci_mem_write_2M(ql_adapter_state_t * ha,uint64_t off,void * data,uint32_t size)87211924SDaniel.Beauregard@Sun.COM ql_8021_pci_mem_write_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
87311924SDaniel.Beauregard@Sun.COM uint32_t size)
87411924SDaniel.Beauregard@Sun.COM {
87511924SDaniel.Beauregard@Sun.COM int j, ret = 0;
87611924SDaniel.Beauregard@Sun.COM uint32_t i, temp, loop, sz[2];
87711924SDaniel.Beauregard@Sun.COM uint32_t scale, shift_amount, p3p, startword;
87811924SDaniel.Beauregard@Sun.COM uint64_t off8, off0, mem_crb, tmpw, word[2] = {0, 0};
87911924SDaniel.Beauregard@Sun.COM
88011924SDaniel.Beauregard@Sun.COM /*
88111924SDaniel.Beauregard@Sun.COM * If not MN, go check for MS or invalid.
88211924SDaniel.Beauregard@Sun.COM */
88311924SDaniel.Beauregard@Sun.COM if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
88411924SDaniel.Beauregard@Sun.COM mem_crb = UNM_CRB_QDR_NET;
88511924SDaniel.Beauregard@Sun.COM } else {
88611924SDaniel.Beauregard@Sun.COM mem_crb = UNM_CRB_DDR_NET;
88711924SDaniel.Beauregard@Sun.COM if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
88811924SDaniel.Beauregard@Sun.COM return (ql_8021_pci_mem_write_direct(ha, off, data,
88911924SDaniel.Beauregard@Sun.COM size));
89011924SDaniel.Beauregard@Sun.COM }
89111924SDaniel.Beauregard@Sun.COM }
89211924SDaniel.Beauregard@Sun.COM
89311924SDaniel.Beauregard@Sun.COM off0 = off & 0x7;
89411924SDaniel.Beauregard@Sun.COM sz[0] = (uint32_t)(((uint64_t)size < (8 - off0)) ? size : (8 - off0));
89511924SDaniel.Beauregard@Sun.COM sz[1] = size - sz[0];
89611924SDaniel.Beauregard@Sun.COM
89711924SDaniel.Beauregard@Sun.COM if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
89811924SDaniel.Beauregard@Sun.COM off8 = off & 0xfffffff0;
89911924SDaniel.Beauregard@Sun.COM loop = (uint32_t)((((off & 0xf) + size - 1) >> 4) + 1);
90011924SDaniel.Beauregard@Sun.COM shift_amount = 4;
90111924SDaniel.Beauregard@Sun.COM scale = 2;
90211924SDaniel.Beauregard@Sun.COM p3p = 1;
90311924SDaniel.Beauregard@Sun.COM startword = (uint32_t)((off & 0xf) / 8);
90411924SDaniel.Beauregard@Sun.COM } else {
90511924SDaniel.Beauregard@Sun.COM off8 = off & 0xfffffff8;
90611924SDaniel.Beauregard@Sun.COM loop = (uint32_t)(((off0 + size - 1) >> 3) + 1);
90711924SDaniel.Beauregard@Sun.COM shift_amount = 3;
90811924SDaniel.Beauregard@Sun.COM scale = 1;
90911924SDaniel.Beauregard@Sun.COM p3p = 0;
91011924SDaniel.Beauregard@Sun.COM startword = 0;
91111924SDaniel.Beauregard@Sun.COM }
91211924SDaniel.Beauregard@Sun.COM
91311924SDaniel.Beauregard@Sun.COM if (p3p || (size != 8) || (off0 != 0)) {
91411924SDaniel.Beauregard@Sun.COM for (i = 0; i < loop; i++) {
91511924SDaniel.Beauregard@Sun.COM if (ql_8021_pci_mem_read_2M(ha, off8 +
91611924SDaniel.Beauregard@Sun.COM (i << shift_amount), &word[i * scale], 8)) {
91711924SDaniel.Beauregard@Sun.COM EL(ha, "8021_pci_mem_read_2M != 0\n");
91811924SDaniel.Beauregard@Sun.COM return (-1);
91911924SDaniel.Beauregard@Sun.COM }
92011924SDaniel.Beauregard@Sun.COM }
92111924SDaniel.Beauregard@Sun.COM }
92211924SDaniel.Beauregard@Sun.COM
92311924SDaniel.Beauregard@Sun.COM switch (size) {
92411924SDaniel.Beauregard@Sun.COM case 1:
92511924SDaniel.Beauregard@Sun.COM tmpw = (uint64_t)(*((uint8_t *)data));
92611924SDaniel.Beauregard@Sun.COM break;
92711924SDaniel.Beauregard@Sun.COM case 2:
92811924SDaniel.Beauregard@Sun.COM tmpw = (uint64_t)(*((uint16_t *)data));
92911924SDaniel.Beauregard@Sun.COM break;
93011924SDaniel.Beauregard@Sun.COM case 4:
93111924SDaniel.Beauregard@Sun.COM tmpw = (uint64_t)(*((uint32_t *)data));
93211924SDaniel.Beauregard@Sun.COM break;
93311924SDaniel.Beauregard@Sun.COM case 8:
93411924SDaniel.Beauregard@Sun.COM default:
93511924SDaniel.Beauregard@Sun.COM tmpw = *((uint64_t *)data);
93611924SDaniel.Beauregard@Sun.COM break;
93711924SDaniel.Beauregard@Sun.COM }
93811924SDaniel.Beauregard@Sun.COM
93911924SDaniel.Beauregard@Sun.COM if (p3p) {
94011924SDaniel.Beauregard@Sun.COM if (sz[0] == 8) {
94111924SDaniel.Beauregard@Sun.COM word[startword] = tmpw;
94211924SDaniel.Beauregard@Sun.COM } else {
94311924SDaniel.Beauregard@Sun.COM word[startword] &= ~((~(~0ULL << (sz[0] * 8))) <<
94411924SDaniel.Beauregard@Sun.COM (off0 * 8));
94511924SDaniel.Beauregard@Sun.COM word[startword] |= tmpw << (off0 * 8);
94611924SDaniel.Beauregard@Sun.COM }
94711924SDaniel.Beauregard@Sun.COM if (sz[1] != 0) {
94811924SDaniel.Beauregard@Sun.COM word[startword+1] &= ~(~0ULL << (sz[1] * 8));
94911924SDaniel.Beauregard@Sun.COM word[startword+1] |= tmpw >> (sz[0] * 8);
95011924SDaniel.Beauregard@Sun.COM }
95111924SDaniel.Beauregard@Sun.COM } else {
95211924SDaniel.Beauregard@Sun.COM word[startword] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
95311924SDaniel.Beauregard@Sun.COM word[startword] |= tmpw << (off0 * 8);
95411924SDaniel.Beauregard@Sun.COM
95511924SDaniel.Beauregard@Sun.COM if (loop == 2) {
95611924SDaniel.Beauregard@Sun.COM word[1] &= ~(~0ULL << (sz[1] * 8));
95711924SDaniel.Beauregard@Sun.COM word[1] |= tmpw >> (sz[0] * 8);
95811924SDaniel.Beauregard@Sun.COM }
95911924SDaniel.Beauregard@Sun.COM }
96011924SDaniel.Beauregard@Sun.COM
96111924SDaniel.Beauregard@Sun.COM /*
96211924SDaniel.Beauregard@Sun.COM * don't lock here - write_wx gets the lock if each time
96311924SDaniel.Beauregard@Sun.COM * write_lock_irqsave(&adapter->adapter_lock, flags);
96411924SDaniel.Beauregard@Sun.COM * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
96511924SDaniel.Beauregard@Sun.COM */
96611924SDaniel.Beauregard@Sun.COM
96711924SDaniel.Beauregard@Sun.COM for (i = 0; i < loop; i++) {
96811924SDaniel.Beauregard@Sun.COM temp = (uint32_t)(off8 + (i << shift_amount));
96911924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
97011924SDaniel.Beauregard@Sun.COM temp = 0;
97111924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
97211924SDaniel.Beauregard@Sun.COM temp = (uint32_t)(word[i * scale] & 0xffffffff);
97311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_LO, temp);
97411924SDaniel.Beauregard@Sun.COM temp = (uint32_t)((word[i * scale] >> 32) & 0xffffffff);
97511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_HI, temp);
97611924SDaniel.Beauregard@Sun.COM if (p3p) {
97711924SDaniel.Beauregard@Sun.COM temp = (uint32_t)(word[i * scale + 1] & 0xffffffff);
97811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha,
97911924SDaniel.Beauregard@Sun.COM mem_crb + MIU_TEST_AGT_WRDATA_UPPER_LO, temp);
98011924SDaniel.Beauregard@Sun.COM temp = (uint32_t)((word[i * scale + 1] >> 32) &
98111924SDaniel.Beauregard@Sun.COM 0xffffffff);
98211924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha,
98311924SDaniel.Beauregard@Sun.COM mem_crb + MIU_TEST_AGT_WRDATA_UPPER_HI, temp);
98411924SDaniel.Beauregard@Sun.COM }
98511924SDaniel.Beauregard@Sun.COM temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
98611924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
98711924SDaniel.Beauregard@Sun.COM temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
98811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
98911924SDaniel.Beauregard@Sun.COM
99011924SDaniel.Beauregard@Sun.COM for (j = 0; j < MAX_CTL_CHECK; j++) {
99111924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
99211924SDaniel.Beauregard@Sun.COM if ((temp & MIU_TA_CTL_BUSY) == 0)
99311924SDaniel.Beauregard@Sun.COM break;
99411924SDaniel.Beauregard@Sun.COM }
99511924SDaniel.Beauregard@Sun.COM
99611924SDaniel.Beauregard@Sun.COM if (j >= MAX_CTL_CHECK) {
99711924SDaniel.Beauregard@Sun.COM EL(ha, "failed to write through agent\n");
99811924SDaniel.Beauregard@Sun.COM ret = -1;
99911924SDaniel.Beauregard@Sun.COM break;
100011924SDaniel.Beauregard@Sun.COM }
100111924SDaniel.Beauregard@Sun.COM }
100211924SDaniel.Beauregard@Sun.COM
100311924SDaniel.Beauregard@Sun.COM return (ret);
100411924SDaniel.Beauregard@Sun.COM }
100511924SDaniel.Beauregard@Sun.COM
100611924SDaniel.Beauregard@Sun.COM static uint32_t
ql_8021_decode_crb_addr(ql_adapter_state_t * ha,uint32_t addr)100711924SDaniel.Beauregard@Sun.COM ql_8021_decode_crb_addr(ql_adapter_state_t *ha, uint32_t addr)
100811924SDaniel.Beauregard@Sun.COM {
100911924SDaniel.Beauregard@Sun.COM int i;
101011924SDaniel.Beauregard@Sun.COM uint32_t base_addr, offset, pci_base;
101111924SDaniel.Beauregard@Sun.COM
101211924SDaniel.Beauregard@Sun.COM if (!crb_table_initialized) {
101311924SDaniel.Beauregard@Sun.COM ql_crb_addr_transform_setup(ha);
101411924SDaniel.Beauregard@Sun.COM }
101511924SDaniel.Beauregard@Sun.COM
101611924SDaniel.Beauregard@Sun.COM pci_base = ADDR_ERROR;
101711924SDaniel.Beauregard@Sun.COM base_addr = addr & 0xfff00000;
101811924SDaniel.Beauregard@Sun.COM offset = addr & 0x000fffff;
101911924SDaniel.Beauregard@Sun.COM
102011924SDaniel.Beauregard@Sun.COM for (i = 0; i < MAX_CRB_XFORM; i++) {
102111924SDaniel.Beauregard@Sun.COM if (crb_addr_xform[i] == base_addr) {
102211924SDaniel.Beauregard@Sun.COM pci_base = i << 20;
102311924SDaniel.Beauregard@Sun.COM break;
102411924SDaniel.Beauregard@Sun.COM }
102511924SDaniel.Beauregard@Sun.COM }
102611924SDaniel.Beauregard@Sun.COM if (pci_base == ADDR_ERROR) {
102711924SDaniel.Beauregard@Sun.COM return (pci_base);
102811924SDaniel.Beauregard@Sun.COM } else {
102911924SDaniel.Beauregard@Sun.COM return (pci_base + offset);
103011924SDaniel.Beauregard@Sun.COM }
103111924SDaniel.Beauregard@Sun.COM }
103211924SDaniel.Beauregard@Sun.COM
103311924SDaniel.Beauregard@Sun.COM static int
ql_8021_hw_lock(ql_adapter_state_t * ha,uint32_t timer)103411924SDaniel.Beauregard@Sun.COM ql_8021_hw_lock(ql_adapter_state_t *ha, uint32_t timer)
103511924SDaniel.Beauregard@Sun.COM {
103611924SDaniel.Beauregard@Sun.COM uint32_t done = 0, timeout = 0;
103711924SDaniel.Beauregard@Sun.COM
103811924SDaniel.Beauregard@Sun.COM while (!done) {
103911924SDaniel.Beauregard@Sun.COM /* acquire semaphore5 from PCI HW block */
104011924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_LOCK), &done);
104111924SDaniel.Beauregard@Sun.COM if (done == 1) {
104211924SDaniel.Beauregard@Sun.COM break;
104311924SDaniel.Beauregard@Sun.COM }
104411924SDaniel.Beauregard@Sun.COM if (timeout >= timer) {
104511924SDaniel.Beauregard@Sun.COM EL(ha, "timeout\n");
104611924SDaniel.Beauregard@Sun.COM return (-1);
104711924SDaniel.Beauregard@Sun.COM }
104811924SDaniel.Beauregard@Sun.COM timeout++;
104911924SDaniel.Beauregard@Sun.COM
105011924SDaniel.Beauregard@Sun.COM /*
105111924SDaniel.Beauregard@Sun.COM * Yield CPU
105211924SDaniel.Beauregard@Sun.COM */
105311924SDaniel.Beauregard@Sun.COM delay(1);
105411924SDaniel.Beauregard@Sun.COM }
105511924SDaniel.Beauregard@Sun.COM
105611924SDaniel.Beauregard@Sun.COM return (0);
105711924SDaniel.Beauregard@Sun.COM }
105811924SDaniel.Beauregard@Sun.COM
105911924SDaniel.Beauregard@Sun.COM static void
ql_8021_hw_unlock(ql_adapter_state_t * ha)106011924SDaniel.Beauregard@Sun.COM ql_8021_hw_unlock(ql_adapter_state_t *ha)
106111924SDaniel.Beauregard@Sun.COM {
106211924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_UNLOCK), NULL);
106311924SDaniel.Beauregard@Sun.COM }
106411924SDaniel.Beauregard@Sun.COM
106511924SDaniel.Beauregard@Sun.COM static int
ql_8021_rom_lock(ql_adapter_state_t * ha)106611924SDaniel.Beauregard@Sun.COM ql_8021_rom_lock(ql_adapter_state_t *ha)
106711924SDaniel.Beauregard@Sun.COM {
106811924SDaniel.Beauregard@Sun.COM uint32_t done = 0, timeout = 0;
106911924SDaniel.Beauregard@Sun.COM
107011924SDaniel.Beauregard@Sun.COM while (!done) {
107111924SDaniel.Beauregard@Sun.COM /* acquire semaphore2 from PCI HW block */
107211924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_LOCK), &done);
107311924SDaniel.Beauregard@Sun.COM if (done == 1) {
107411924SDaniel.Beauregard@Sun.COM break;
107511924SDaniel.Beauregard@Sun.COM }
107611924SDaniel.Beauregard@Sun.COM if (timeout >= ROM_LOCK_TIMEOUT) {
107711924SDaniel.Beauregard@Sun.COM EL(ha, "timeout\n");
107811924SDaniel.Beauregard@Sun.COM return (-1);
107911924SDaniel.Beauregard@Sun.COM }
108011924SDaniel.Beauregard@Sun.COM timeout++;
108111924SDaniel.Beauregard@Sun.COM
108211924SDaniel.Beauregard@Sun.COM /*
108311924SDaniel.Beauregard@Sun.COM * Yield CPU
108411924SDaniel.Beauregard@Sun.COM */
108511924SDaniel.Beauregard@Sun.COM delay(1);
108611924SDaniel.Beauregard@Sun.COM }
108711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROM_LOCK_ID, ROM_LOCK_DRIVER);
108811924SDaniel.Beauregard@Sun.COM
108911924SDaniel.Beauregard@Sun.COM return (0);
109011924SDaniel.Beauregard@Sun.COM }
109111924SDaniel.Beauregard@Sun.COM
109211924SDaniel.Beauregard@Sun.COM static void
ql_8021_rom_unlock(ql_adapter_state_t * ha)109311924SDaniel.Beauregard@Sun.COM ql_8021_rom_unlock(ql_adapter_state_t *ha)
109411924SDaniel.Beauregard@Sun.COM {
109511924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_UNLOCK), NULL);
109611924SDaniel.Beauregard@Sun.COM }
109711924SDaniel.Beauregard@Sun.COM
109811924SDaniel.Beauregard@Sun.COM static int
ql_8021_wait_rom_done(ql_adapter_state_t * ha)109911924SDaniel.Beauregard@Sun.COM ql_8021_wait_rom_done(ql_adapter_state_t *ha)
110011924SDaniel.Beauregard@Sun.COM {
110111924SDaniel.Beauregard@Sun.COM uint32_t timeout = 0, done = 0;
110211924SDaniel.Beauregard@Sun.COM
110311924SDaniel.Beauregard@Sun.COM while (done == 0) {
110411924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_ROMUSB_GLB_STATUS, &done);
110511924SDaniel.Beauregard@Sun.COM done &= 2;
110611924SDaniel.Beauregard@Sun.COM timeout++;
110711924SDaniel.Beauregard@Sun.COM if (timeout >= ROM_MAX_TIMEOUT) {
110811924SDaniel.Beauregard@Sun.COM EL(ha, "Timeout reached waiting for rom done\n");
110911924SDaniel.Beauregard@Sun.COM return (-1);
111011924SDaniel.Beauregard@Sun.COM }
111111924SDaniel.Beauregard@Sun.COM }
111211924SDaniel.Beauregard@Sun.COM
111311924SDaniel.Beauregard@Sun.COM return (0);
111411924SDaniel.Beauregard@Sun.COM }
111511924SDaniel.Beauregard@Sun.COM
111611924SDaniel.Beauregard@Sun.COM static int
ql_8021_wait_flash_done(ql_adapter_state_t * ha)111711924SDaniel.Beauregard@Sun.COM ql_8021_wait_flash_done(ql_adapter_state_t *ha)
111811924SDaniel.Beauregard@Sun.COM {
111911924SDaniel.Beauregard@Sun.COM clock_t timer;
112011924SDaniel.Beauregard@Sun.COM uint32_t status;
112111924SDaniel.Beauregard@Sun.COM
112211924SDaniel.Beauregard@Sun.COM for (timer = 30 * drv_usectohz(1000000); timer; timer--) {
112311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
112411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
112511924SDaniel.Beauregard@Sun.COM UNM_ROMUSB_ROM_RDSR_INSTR);
112611924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_rom_done(ha)) {
112711924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for rom done2\n");
112811924SDaniel.Beauregard@Sun.COM return (-1);
112911924SDaniel.Beauregard@Sun.COM }
113011924SDaniel.Beauregard@Sun.COM
113111924SDaniel.Beauregard@Sun.COM /* Get status. */
113211924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, &status);
113311924SDaniel.Beauregard@Sun.COM if (!(status & BIT_0)) {
113411924SDaniel.Beauregard@Sun.COM return (0);
113511924SDaniel.Beauregard@Sun.COM }
113611924SDaniel.Beauregard@Sun.COM delay(1);
113711924SDaniel.Beauregard@Sun.COM }
113811924SDaniel.Beauregard@Sun.COM
113911924SDaniel.Beauregard@Sun.COM EL(ha, "timeout status=%x\n", status);
114011924SDaniel.Beauregard@Sun.COM return (-1);
114111924SDaniel.Beauregard@Sun.COM }
114211924SDaniel.Beauregard@Sun.COM
114311924SDaniel.Beauregard@Sun.COM static int
ql_8021_do_rom_fast_read(ql_adapter_state_t * ha,uint32_t addr,uint32_t * valp)114411924SDaniel.Beauregard@Sun.COM ql_8021_do_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
114511924SDaniel.Beauregard@Sun.COM {
114611924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
114711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
114811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
114911924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
115011924SDaniel.Beauregard@Sun.COM UNM_ROMUSB_ROM_FAST_RD_INSTR);
115111924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_rom_done(ha)) {
115211924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for rom done\n");
115311924SDaniel.Beauregard@Sun.COM return (-1);
115411924SDaniel.Beauregard@Sun.COM }
115511924SDaniel.Beauregard@Sun.COM /* reset abyte_cnt and dummy_byte_cnt */
115611924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
115711924SDaniel.Beauregard@Sun.COM drv_usecwait(10);
115811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
115911924SDaniel.Beauregard@Sun.COM
116011924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, valp);
116111924SDaniel.Beauregard@Sun.COM
116211924SDaniel.Beauregard@Sun.COM return (0);
116311924SDaniel.Beauregard@Sun.COM }
116411924SDaniel.Beauregard@Sun.COM
116511924SDaniel.Beauregard@Sun.COM int
ql_8021_rom_fast_read(ql_adapter_state_t * ha,uint32_t addr,uint32_t * valp)116611924SDaniel.Beauregard@Sun.COM ql_8021_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
116711924SDaniel.Beauregard@Sun.COM {
116811924SDaniel.Beauregard@Sun.COM int ret, loops = 0;
116911924SDaniel.Beauregard@Sun.COM
117011924SDaniel.Beauregard@Sun.COM while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
117111924SDaniel.Beauregard@Sun.COM drv_usecwait(100);
117211924SDaniel.Beauregard@Sun.COM loops++;
117311924SDaniel.Beauregard@Sun.COM }
117411924SDaniel.Beauregard@Sun.COM if (loops >= 50000) {
117511924SDaniel.Beauregard@Sun.COM EL(ha, "rom_lock failed\n");
117611924SDaniel.Beauregard@Sun.COM return (-1);
117711924SDaniel.Beauregard@Sun.COM }
117811924SDaniel.Beauregard@Sun.COM ret = ql_8021_do_rom_fast_read(ha, addr, valp);
117911924SDaniel.Beauregard@Sun.COM ql_8021_rom_unlock(ha);
118011924SDaniel.Beauregard@Sun.COM
118111924SDaniel.Beauregard@Sun.COM return (ret);
118211924SDaniel.Beauregard@Sun.COM }
118311924SDaniel.Beauregard@Sun.COM
118411924SDaniel.Beauregard@Sun.COM static int
ql_8021_do_rom_write(ql_adapter_state_t * ha,uint32_t addr,uint32_t data)118511924SDaniel.Beauregard@Sun.COM ql_8021_do_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
118611924SDaniel.Beauregard@Sun.COM {
118711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
118811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
118911924SDaniel.Beauregard@Sun.COM UNM_ROMUSB_ROM_WREN_INSTR);
119011924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_rom_done(ha)) {
119111924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for rom done\n");
119211924SDaniel.Beauregard@Sun.COM return (-1);
119311924SDaniel.Beauregard@Sun.COM }
119411924SDaniel.Beauregard@Sun.COM
119511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
119611924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
119711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
119811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
119911924SDaniel.Beauregard@Sun.COM UNM_ROMUSB_ROM_PP_INSTR);
120011924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_rom_done(ha)) {
120111924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for rom done1\n");
120211924SDaniel.Beauregard@Sun.COM return (-1);
120311924SDaniel.Beauregard@Sun.COM }
120411924SDaniel.Beauregard@Sun.COM
120511924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_flash_done(ha)) {
120611924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for flash done\n");
120711924SDaniel.Beauregard@Sun.COM return (-1);
120811924SDaniel.Beauregard@Sun.COM }
120911924SDaniel.Beauregard@Sun.COM
121011924SDaniel.Beauregard@Sun.COM return (0);
121111924SDaniel.Beauregard@Sun.COM }
121211924SDaniel.Beauregard@Sun.COM
121311924SDaniel.Beauregard@Sun.COM static int
ql_8021_do_rom_erase(ql_adapter_state_t * ha,uint32_t addr)121411924SDaniel.Beauregard@Sun.COM ql_8021_do_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
121511924SDaniel.Beauregard@Sun.COM {
121611924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
121711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
121811924SDaniel.Beauregard@Sun.COM UNM_ROMUSB_ROM_WREN_INSTR);
121911924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_rom_done(ha)) {
122011924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for rom done\n");
122111924SDaniel.Beauregard@Sun.COM return (-1);
122211924SDaniel.Beauregard@Sun.COM }
122311924SDaniel.Beauregard@Sun.COM
122411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
122511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
122611924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
122711924SDaniel.Beauregard@Sun.COM UNM_ROMUSB_ROM_SE_INSTR);
122811924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_rom_done(ha)) {
122911924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for rom done1\n");
123011924SDaniel.Beauregard@Sun.COM return (-1);
123111924SDaniel.Beauregard@Sun.COM }
123211924SDaniel.Beauregard@Sun.COM
123311924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_flash_done(ha)) {
123411924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for flash done\n");
123511924SDaniel.Beauregard@Sun.COM return (-1);
123611924SDaniel.Beauregard@Sun.COM }
123711924SDaniel.Beauregard@Sun.COM
123811924SDaniel.Beauregard@Sun.COM return (0);
123911924SDaniel.Beauregard@Sun.COM }
124011924SDaniel.Beauregard@Sun.COM
124111924SDaniel.Beauregard@Sun.COM int
ql_8021_rom_read(ql_adapter_state_t * ha,uint32_t addr,uint32_t * bp)124211924SDaniel.Beauregard@Sun.COM ql_8021_rom_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *bp)
124311924SDaniel.Beauregard@Sun.COM {
124411924SDaniel.Beauregard@Sun.COM int ret;
124511924SDaniel.Beauregard@Sun.COM
124611924SDaniel.Beauregard@Sun.COM ret = ql_8021_rom_fast_read(ha, addr << 2, bp) == 0 ? QL_SUCCESS :
124711924SDaniel.Beauregard@Sun.COM QL_FUNCTION_FAILED;
124811924SDaniel.Beauregard@Sun.COM
124911924SDaniel.Beauregard@Sun.COM return (ret);
125011924SDaniel.Beauregard@Sun.COM }
125111924SDaniel.Beauregard@Sun.COM
125211924SDaniel.Beauregard@Sun.COM int
ql_8021_rom_write(ql_adapter_state_t * ha,uint32_t addr,uint32_t data)125311924SDaniel.Beauregard@Sun.COM ql_8021_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
125411924SDaniel.Beauregard@Sun.COM {
125511924SDaniel.Beauregard@Sun.COM int ret, loops = 0;
125611924SDaniel.Beauregard@Sun.COM
125711924SDaniel.Beauregard@Sun.COM while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
125811924SDaniel.Beauregard@Sun.COM drv_usecwait(100);
125911924SDaniel.Beauregard@Sun.COM loops++;
126011924SDaniel.Beauregard@Sun.COM }
126111924SDaniel.Beauregard@Sun.COM if (loops >= 50000) {
126211924SDaniel.Beauregard@Sun.COM EL(ha, "rom_lock failed\n");
126311924SDaniel.Beauregard@Sun.COM ret = QL_FUNCTION_TIMEOUT;
126411924SDaniel.Beauregard@Sun.COM } else {
126511924SDaniel.Beauregard@Sun.COM ret = ql_8021_do_rom_write(ha, addr << 2, data) == 0 ?
126611924SDaniel.Beauregard@Sun.COM QL_SUCCESS : QL_FUNCTION_FAILED;
126711924SDaniel.Beauregard@Sun.COM ql_8021_rom_unlock(ha);
126811924SDaniel.Beauregard@Sun.COM }
126911924SDaniel.Beauregard@Sun.COM
127011924SDaniel.Beauregard@Sun.COM return (ret);
127111924SDaniel.Beauregard@Sun.COM }
127211924SDaniel.Beauregard@Sun.COM
127311924SDaniel.Beauregard@Sun.COM int
ql_8021_rom_erase(ql_adapter_state_t * ha,uint32_t addr)127411924SDaniel.Beauregard@Sun.COM ql_8021_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
127511924SDaniel.Beauregard@Sun.COM {
127611924SDaniel.Beauregard@Sun.COM int ret, loops = 0;
127711924SDaniel.Beauregard@Sun.COM
127811924SDaniel.Beauregard@Sun.COM while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
127911924SDaniel.Beauregard@Sun.COM drv_usecwait(100);
128011924SDaniel.Beauregard@Sun.COM loops++;
128111924SDaniel.Beauregard@Sun.COM }
128211924SDaniel.Beauregard@Sun.COM if (loops >= 50000) {
128311924SDaniel.Beauregard@Sun.COM EL(ha, "rom_lock failed\n");
128411924SDaniel.Beauregard@Sun.COM ret = QL_FUNCTION_TIMEOUT;
128511924SDaniel.Beauregard@Sun.COM } else {
128611924SDaniel.Beauregard@Sun.COM ret = ql_8021_do_rom_erase(ha, addr << 2) == 0 ? QL_SUCCESS :
128711924SDaniel.Beauregard@Sun.COM QL_FUNCTION_FAILED;
128811924SDaniel.Beauregard@Sun.COM ql_8021_rom_unlock(ha);
128911924SDaniel.Beauregard@Sun.COM }
129011924SDaniel.Beauregard@Sun.COM
129111924SDaniel.Beauregard@Sun.COM return (ret);
129211924SDaniel.Beauregard@Sun.COM }
129311924SDaniel.Beauregard@Sun.COM
129411924SDaniel.Beauregard@Sun.COM int
ql_8021_rom_wrsr(ql_adapter_state_t * ha,uint32_t data)129511924SDaniel.Beauregard@Sun.COM ql_8021_rom_wrsr(ql_adapter_state_t *ha, uint32_t data)
129611924SDaniel.Beauregard@Sun.COM {
129711924SDaniel.Beauregard@Sun.COM int ret = QL_SUCCESS, loops = 0;
129811924SDaniel.Beauregard@Sun.COM
129911924SDaniel.Beauregard@Sun.COM while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
130011924SDaniel.Beauregard@Sun.COM drv_usecwait(100);
130111924SDaniel.Beauregard@Sun.COM loops++;
130211924SDaniel.Beauregard@Sun.COM }
130311924SDaniel.Beauregard@Sun.COM if (loops >= 50000) {
130411924SDaniel.Beauregard@Sun.COM EL(ha, "rom_lock failed\n");
130511924SDaniel.Beauregard@Sun.COM ret = QL_FUNCTION_TIMEOUT;
130611924SDaniel.Beauregard@Sun.COM } else {
130711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
130811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
130911924SDaniel.Beauregard@Sun.COM UNM_ROMUSB_ROM_WREN_INSTR);
131011924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_rom_done(ha)) {
131111924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for rom done\n");
131211924SDaniel.Beauregard@Sun.COM ret = QL_FUNCTION_FAILED;
131311924SDaniel.Beauregard@Sun.COM } else {
131411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
131511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
131611924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
131711924SDaniel.Beauregard@Sun.COM UNM_ROMUSB_ROM_WRSR_INSTR);
131811924SDaniel.Beauregard@Sun.COM if (ql_8021_wait_rom_done(ha)) {
131911924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for rom done1\n");
132011924SDaniel.Beauregard@Sun.COM ret = QL_FUNCTION_FAILED;
132111924SDaniel.Beauregard@Sun.COM } else if (ql_8021_wait_flash_done(ha)) {
132211924SDaniel.Beauregard@Sun.COM EL(ha, "Error waiting for flash done\n");
132311924SDaniel.Beauregard@Sun.COM ret = QL_FUNCTION_FAILED;
132411924SDaniel.Beauregard@Sun.COM }
132511924SDaniel.Beauregard@Sun.COM }
132611924SDaniel.Beauregard@Sun.COM ql_8021_rom_unlock(ha);
132711924SDaniel.Beauregard@Sun.COM }
132811924SDaniel.Beauregard@Sun.COM
132911924SDaniel.Beauregard@Sun.COM return (ret);
133011924SDaniel.Beauregard@Sun.COM }
133111924SDaniel.Beauregard@Sun.COM
133211924SDaniel.Beauregard@Sun.COM static int
ql_8021_phantom_init(ql_adapter_state_t * ha)133311924SDaniel.Beauregard@Sun.COM ql_8021_phantom_init(ql_adapter_state_t *ha)
133411924SDaniel.Beauregard@Sun.COM {
133511924SDaniel.Beauregard@Sun.COM uint32_t val = 0, err = 0;
133611924SDaniel.Beauregard@Sun.COM int retries = 60;
133711924SDaniel.Beauregard@Sun.COM
133811924SDaniel.Beauregard@Sun.COM do {
133911924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_CMDPEG_STATE, &val);
134011924SDaniel.Beauregard@Sun.COM
134111924SDaniel.Beauregard@Sun.COM switch (val) {
134211924SDaniel.Beauregard@Sun.COM case PHAN_INITIALIZE_COMPLETE:
134311924SDaniel.Beauregard@Sun.COM case PHAN_INITIALIZE_ACK:
134411924SDaniel.Beauregard@Sun.COM EL(ha, "success=%xh\n", val);
134511924SDaniel.Beauregard@Sun.COM return (0);
134611924SDaniel.Beauregard@Sun.COM case PHAN_INITIALIZE_FAILED:
134711924SDaniel.Beauregard@Sun.COM EL(ha, "PHAN_INITIALIZE_FAILED\n");
134811924SDaniel.Beauregard@Sun.COM err = 1;
134911924SDaniel.Beauregard@Sun.COM break;
135011924SDaniel.Beauregard@Sun.COM default:
135111924SDaniel.Beauregard@Sun.COM break;
135211924SDaniel.Beauregard@Sun.COM }
135311924SDaniel.Beauregard@Sun.COM
135411924SDaniel.Beauregard@Sun.COM if (err) {
135511924SDaniel.Beauregard@Sun.COM break;
135611924SDaniel.Beauregard@Sun.COM }
135711924SDaniel.Beauregard@Sun.COM /* 500 msec wait */
135811924SDaniel.Beauregard@Sun.COM delay(50);
135911924SDaniel.Beauregard@Sun.COM
136011924SDaniel.Beauregard@Sun.COM } while (--retries);
136111924SDaniel.Beauregard@Sun.COM
136211924SDaniel.Beauregard@Sun.COM if (!err) {
136311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
136411924SDaniel.Beauregard@Sun.COM }
136511924SDaniel.Beauregard@Sun.COM
136611924SDaniel.Beauregard@Sun.COM EL(ha, "firmware init failed=%x\n", val);
136711924SDaniel.Beauregard@Sun.COM return (-1);
136811924SDaniel.Beauregard@Sun.COM }
136911924SDaniel.Beauregard@Sun.COM
137011924SDaniel.Beauregard@Sun.COM static int
ql_8021_pinit_from_rom(ql_adapter_state_t * ha)137111924SDaniel.Beauregard@Sun.COM ql_8021_pinit_from_rom(ql_adapter_state_t *ha)
137211924SDaniel.Beauregard@Sun.COM {
137311924SDaniel.Beauregard@Sun.COM int init_delay = 0;
137411924SDaniel.Beauregard@Sun.COM struct crb_addr_pair *buf;
137511924SDaniel.Beauregard@Sun.COM uint32_t offset, off, i, n, addr, val;
137611924SDaniel.Beauregard@Sun.COM
137711924SDaniel.Beauregard@Sun.COM /* Grab the lock so that no one can read flash when we reset the chip */
137811924SDaniel.Beauregard@Sun.COM (void) ql_8021_rom_lock(ha);
137911924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0xffffffff);
138011924SDaniel.Beauregard@Sun.COM /* Just in case it was held when we reset the chip */
138111924SDaniel.Beauregard@Sun.COM ql_8021_rom_unlock(ha);
138211924SDaniel.Beauregard@Sun.COM
138311924SDaniel.Beauregard@Sun.COM if (ql_8021_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafe ||
138411924SDaniel.Beauregard@Sun.COM ql_8021_rom_fast_read(ha, 4, &n) != 0) {
138511924SDaniel.Beauregard@Sun.COM EL(ha, "ERROR Reading crb_init area: n: %08x\n", n);
138611924SDaniel.Beauregard@Sun.COM return (-1);
138711924SDaniel.Beauregard@Sun.COM }
138811924SDaniel.Beauregard@Sun.COM offset = n & 0xffff;
138911924SDaniel.Beauregard@Sun.COM n = (n >> 16) & 0xffff;
139011924SDaniel.Beauregard@Sun.COM if (n >= 1024) {
139111924SDaniel.Beauregard@Sun.COM EL(ha, "n=0x%x Error! NetXen card flash not initialized\n", n);
139211924SDaniel.Beauregard@Sun.COM return (-1);
139311924SDaniel.Beauregard@Sun.COM }
139411924SDaniel.Beauregard@Sun.COM
139511924SDaniel.Beauregard@Sun.COM buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
139611924SDaniel.Beauregard@Sun.COM if (buf == NULL) {
139711924SDaniel.Beauregard@Sun.COM EL(ha, "Unable to zalloc memory\n");
139811924SDaniel.Beauregard@Sun.COM return (-1);
139911924SDaniel.Beauregard@Sun.COM }
140011924SDaniel.Beauregard@Sun.COM
140111924SDaniel.Beauregard@Sun.COM for (i = 0; i < n; i++) {
140211924SDaniel.Beauregard@Sun.COM if (ql_8021_rom_fast_read(ha, 8 * i + 4 * offset, &val) != 0 ||
140311924SDaniel.Beauregard@Sun.COM ql_8021_rom_fast_read(ha, 8 * i + 4 * offset + 4, &addr) !=
140411924SDaniel.Beauregard@Sun.COM 0) {
140511924SDaniel.Beauregard@Sun.COM kmem_free(buf, n * sizeof (struct crb_addr_pair));
140611924SDaniel.Beauregard@Sun.COM EL(ha, "ql_8021_rom_fast_read != 0 to zalloc memory\n");
140711924SDaniel.Beauregard@Sun.COM return (-1);
140811924SDaniel.Beauregard@Sun.COM }
140911924SDaniel.Beauregard@Sun.COM
141011924SDaniel.Beauregard@Sun.COM buf[i].addr = addr;
141111924SDaniel.Beauregard@Sun.COM buf[i].data = val;
141211924SDaniel.Beauregard@Sun.COM }
141311924SDaniel.Beauregard@Sun.COM
141411924SDaniel.Beauregard@Sun.COM for (i = 0; i < n; i++) {
141511924SDaniel.Beauregard@Sun.COM off = ql_8021_decode_crb_addr(ha, buf[i].addr);
141611924SDaniel.Beauregard@Sun.COM if (off == ADDR_ERROR) {
141711924SDaniel.Beauregard@Sun.COM EL(ha, "Err: Unknown addr: 0x%lx\n", buf[i].addr);
141811924SDaniel.Beauregard@Sun.COM continue;
141911924SDaniel.Beauregard@Sun.COM }
142011924SDaniel.Beauregard@Sun.COM off += UNM_PCI_CRBSPACE;
142111924SDaniel.Beauregard@Sun.COM
142211924SDaniel.Beauregard@Sun.COM if (off & 1) {
142311924SDaniel.Beauregard@Sun.COM continue;
142411924SDaniel.Beauregard@Sun.COM }
142511924SDaniel.Beauregard@Sun.COM
142611924SDaniel.Beauregard@Sun.COM /* skipping cold reboot MAGIC */
142711924SDaniel.Beauregard@Sun.COM if (off == UNM_RAM_COLD_BOOT) {
142811924SDaniel.Beauregard@Sun.COM continue;
142911924SDaniel.Beauregard@Sun.COM }
143011924SDaniel.Beauregard@Sun.COM if (off == (UNM_CRB_I2C0 + 0x1c)) {
143111924SDaniel.Beauregard@Sun.COM continue;
143211924SDaniel.Beauregard@Sun.COM }
143311924SDaniel.Beauregard@Sun.COM /* do not reset PCI */
143411924SDaniel.Beauregard@Sun.COM if (off == (ROMUSB_GLB + 0xbc)) {
143511924SDaniel.Beauregard@Sun.COM continue;
143611924SDaniel.Beauregard@Sun.COM }
143711924SDaniel.Beauregard@Sun.COM if (off == (ROMUSB_GLB + 0xa8)) {
143811924SDaniel.Beauregard@Sun.COM continue;
143911924SDaniel.Beauregard@Sun.COM }
144011924SDaniel.Beauregard@Sun.COM if (off == (ROMUSB_GLB + 0xc8)) { /* core clock */
144111924SDaniel.Beauregard@Sun.COM continue;
144211924SDaniel.Beauregard@Sun.COM }
144311924SDaniel.Beauregard@Sun.COM if (off == (ROMUSB_GLB + 0x24)) { /* MN clock */
144411924SDaniel.Beauregard@Sun.COM continue;
144511924SDaniel.Beauregard@Sun.COM }
144611924SDaniel.Beauregard@Sun.COM if (off == (ROMUSB_GLB + 0x1c)) { /* MS clock */
144711924SDaniel.Beauregard@Sun.COM continue;
144811924SDaniel.Beauregard@Sun.COM }
144911924SDaniel.Beauregard@Sun.COM if ((off & 0x0ff00000) == UNM_CRB_DDR_NET) {
145011924SDaniel.Beauregard@Sun.COM continue;
145111924SDaniel.Beauregard@Sun.COM }
145211924SDaniel.Beauregard@Sun.COM if (off == (UNM_CRB_PEG_NET_1 + 0x18) &&
145311924SDaniel.Beauregard@Sun.COM !NX_IS_REVISION_P3PLUS(ha->rev_id)) {
145411924SDaniel.Beauregard@Sun.COM buf[i].data = 0x1020;
145511924SDaniel.Beauregard@Sun.COM }
145611924SDaniel.Beauregard@Sun.COM /* skip the function enable register */
145711924SDaniel.Beauregard@Sun.COM if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
145811924SDaniel.Beauregard@Sun.COM continue;
145911924SDaniel.Beauregard@Sun.COM }
146011924SDaniel.Beauregard@Sun.COM if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
146111924SDaniel.Beauregard@Sun.COM continue;
146211924SDaniel.Beauregard@Sun.COM }
146311924SDaniel.Beauregard@Sun.COM if ((off & 0x0ff00000) == UNM_CRB_SMB) {
146411924SDaniel.Beauregard@Sun.COM continue;
146511924SDaniel.Beauregard@Sun.COM }
146611924SDaniel.Beauregard@Sun.COM
146711924SDaniel.Beauregard@Sun.COM /* After writing this register, HW needs time for CRB */
146811924SDaniel.Beauregard@Sun.COM /* to quiet down (else crb_window returns 0xffffffff) */
146911924SDaniel.Beauregard@Sun.COM init_delay = 1;
147011924SDaniel.Beauregard@Sun.COM if (off == UNM_ROMUSB_GLB_SW_RESET) {
147111924SDaniel.Beauregard@Sun.COM init_delay = 100; /* Sleep 1000 msecs */
147211924SDaniel.Beauregard@Sun.COM }
147311924SDaniel.Beauregard@Sun.COM
147411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, off, buf[i].data);
147511924SDaniel.Beauregard@Sun.COM
147611924SDaniel.Beauregard@Sun.COM delay(init_delay);
147711924SDaniel.Beauregard@Sun.COM }
147811924SDaniel.Beauregard@Sun.COM kmem_free(buf, n * sizeof (struct crb_addr_pair));
147911924SDaniel.Beauregard@Sun.COM
148011924SDaniel.Beauregard@Sun.COM /* disable_peg_cache_all */
148111924SDaniel.Beauregard@Sun.COM
148211924SDaniel.Beauregard@Sun.COM /* p2dn replyCount */
148311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0xec, 0x1e);
148411924SDaniel.Beauregard@Sun.COM /* disable_peg_cache 0 */
148511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0x4c, 8);
148611924SDaniel.Beauregard@Sun.COM /* disable_peg_cache 1 */
148711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_I + 0x4c, 8);
148811924SDaniel.Beauregard@Sun.COM
148911924SDaniel.Beauregard@Sun.COM /* peg_clr_all */
149011924SDaniel.Beauregard@Sun.COM /* peg_clr 0 */
149111924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x8, 0);
149211924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0xc, 0);
149311924SDaniel.Beauregard@Sun.COM /* peg_clr 1 */
149411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0x8, 0);
149511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0xc, 0);
149611924SDaniel.Beauregard@Sun.COM /* peg_clr 2 */
149711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x8, 0);
149811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0xc, 0);
149911924SDaniel.Beauregard@Sun.COM /* peg_clr 3 */
150011924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x8, 0);
150111924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0xc, 0);
150211924SDaniel.Beauregard@Sun.COM
150311924SDaniel.Beauregard@Sun.COM return (0);
150411924SDaniel.Beauregard@Sun.COM }
150511924SDaniel.Beauregard@Sun.COM
150611924SDaniel.Beauregard@Sun.COM static int
ql_8021_load_from_flash(ql_adapter_state_t * ha)150711924SDaniel.Beauregard@Sun.COM ql_8021_load_from_flash(ql_adapter_state_t *ha)
150811924SDaniel.Beauregard@Sun.COM {
150911924SDaniel.Beauregard@Sun.COM int i;
151011924SDaniel.Beauregard@Sun.COM uint32_t flashaddr, memaddr;
151111924SDaniel.Beauregard@Sun.COM uint32_t high, low, size;
151211924SDaniel.Beauregard@Sun.COM uint64_t data;
151311924SDaniel.Beauregard@Sun.COM
151411924SDaniel.Beauregard@Sun.COM size = ha->bootloader_size / 2;
151511924SDaniel.Beauregard@Sun.COM flashaddr = ha->bootloader_addr << 2;
151611924SDaniel.Beauregard@Sun.COM memaddr = BOOTLD_START;
151711924SDaniel.Beauregard@Sun.COM
151811924SDaniel.Beauregard@Sun.COM for (i = 0; i < size; i++) {
151911924SDaniel.Beauregard@Sun.COM if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
152011924SDaniel.Beauregard@Sun.COM (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
152111924SDaniel.Beauregard@Sun.COM EL(ha, "ql_8021_rom_fast_read != 0\n");
152211924SDaniel.Beauregard@Sun.COM return (-1);
152311924SDaniel.Beauregard@Sun.COM }
152411924SDaniel.Beauregard@Sun.COM data = ((uint64_t)high << 32) | low;
152511924SDaniel.Beauregard@Sun.COM (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
152611924SDaniel.Beauregard@Sun.COM flashaddr += 8;
152711924SDaniel.Beauregard@Sun.COM memaddr += 8;
152811924SDaniel.Beauregard@Sun.COM }
152911924SDaniel.Beauregard@Sun.COM
153011924SDaniel.Beauregard@Sun.COM size = ha->flash_fw_size / 2;
153111924SDaniel.Beauregard@Sun.COM flashaddr = ha->flash_fw_addr << 2;
153211924SDaniel.Beauregard@Sun.COM memaddr = IMAGE_START;
153311924SDaniel.Beauregard@Sun.COM
153411924SDaniel.Beauregard@Sun.COM for (i = 0; i < size; i++) {
153511924SDaniel.Beauregard@Sun.COM if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
153611924SDaniel.Beauregard@Sun.COM (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
153711924SDaniel.Beauregard@Sun.COM EL(ha, "ql_8021_rom_fast_read3 != 0\n");
153811924SDaniel.Beauregard@Sun.COM return (-1);
153911924SDaniel.Beauregard@Sun.COM }
154011924SDaniel.Beauregard@Sun.COM data = ((uint64_t)high << 32) | low;
154111924SDaniel.Beauregard@Sun.COM (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
154211924SDaniel.Beauregard@Sun.COM flashaddr += 8;
154311924SDaniel.Beauregard@Sun.COM memaddr += 8;
154411924SDaniel.Beauregard@Sun.COM }
154511924SDaniel.Beauregard@Sun.COM
154611924SDaniel.Beauregard@Sun.COM return (0);
154711924SDaniel.Beauregard@Sun.COM }
154811924SDaniel.Beauregard@Sun.COM
154911924SDaniel.Beauregard@Sun.COM static int
ql_8021_load_firmware(ql_adapter_state_t * ha)155011924SDaniel.Beauregard@Sun.COM ql_8021_load_firmware(ql_adapter_state_t *ha)
155111924SDaniel.Beauregard@Sun.COM {
155211924SDaniel.Beauregard@Sun.COM uint64_t data;
155311924SDaniel.Beauregard@Sun.COM uint32_t i, flashaddr, size;
155411924SDaniel.Beauregard@Sun.COM uint8_t *bp, n, *dp;
155511924SDaniel.Beauregard@Sun.COM
155611924SDaniel.Beauregard@Sun.COM bp = (uint8_t *)(ha->risc_fw[0].code);
155711924SDaniel.Beauregard@Sun.COM dp = (uint8_t *)&size;
155811924SDaniel.Beauregard@Sun.COM for (n = 0; n < 4; n++) {
155911924SDaniel.Beauregard@Sun.COM dp[n] = *bp++;
156011924SDaniel.Beauregard@Sun.COM }
156111924SDaniel.Beauregard@Sun.COM LITTLE_ENDIAN_32(&size);
156211924SDaniel.Beauregard@Sun.COM EL(ha, "signature=%x\n", size);
156311924SDaniel.Beauregard@Sun.COM
156411924SDaniel.Beauregard@Sun.COM size = (IMAGE_START - BOOTLD_START) / 8;
156511924SDaniel.Beauregard@Sun.COM
156611924SDaniel.Beauregard@Sun.COM bp = (uint8_t *)(ha->risc_fw[0].code + BOOTLD_START);
156711924SDaniel.Beauregard@Sun.COM flashaddr = BOOTLD_START;
156811924SDaniel.Beauregard@Sun.COM
156911924SDaniel.Beauregard@Sun.COM dp = (uint8_t *)&data;
157011924SDaniel.Beauregard@Sun.COM for (i = 0; i < size; i++) {
157111924SDaniel.Beauregard@Sun.COM for (n = 0; n < 8; n++) {
157211924SDaniel.Beauregard@Sun.COM dp[n] = *bp++;
157311924SDaniel.Beauregard@Sun.COM }
157411924SDaniel.Beauregard@Sun.COM LITTLE_ENDIAN_64(&data);
157511924SDaniel.Beauregard@Sun.COM (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
157611924SDaniel.Beauregard@Sun.COM flashaddr += 8;
157711924SDaniel.Beauregard@Sun.COM }
157811924SDaniel.Beauregard@Sun.COM
157911924SDaniel.Beauregard@Sun.COM bp = (uint8_t *)(ha->risc_fw[0].code + FW_SIZE_OFFSET);
158011924SDaniel.Beauregard@Sun.COM dp = (uint8_t *)&size;
158111924SDaniel.Beauregard@Sun.COM for (n = 0; n < 4; n++) {
158211924SDaniel.Beauregard@Sun.COM dp[n] = *bp++;
158311924SDaniel.Beauregard@Sun.COM }
158411924SDaniel.Beauregard@Sun.COM LITTLE_ENDIAN_32(&size);
158511924SDaniel.Beauregard@Sun.COM EL(ha, "IMAGE_START size=%llx\n", size);
158611924SDaniel.Beauregard@Sun.COM size = (size + 7) / 8;
158711924SDaniel.Beauregard@Sun.COM
158811924SDaniel.Beauregard@Sun.COM bp = (uint8_t *)(ha->risc_fw[0].code + IMAGE_START);
158911924SDaniel.Beauregard@Sun.COM flashaddr = IMAGE_START;
159011924SDaniel.Beauregard@Sun.COM
159111924SDaniel.Beauregard@Sun.COM dp = (uint8_t *)&data;
159211924SDaniel.Beauregard@Sun.COM for (i = 0; i < size; i++) {
159311924SDaniel.Beauregard@Sun.COM for (n = 0; n < 8; n++) {
159411924SDaniel.Beauregard@Sun.COM dp[n] = *bp++;
159511924SDaniel.Beauregard@Sun.COM }
159611924SDaniel.Beauregard@Sun.COM LITTLE_ENDIAN_64(&data);
159711924SDaniel.Beauregard@Sun.COM (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
159811924SDaniel.Beauregard@Sun.COM flashaddr += 8;
159911924SDaniel.Beauregard@Sun.COM }
160011924SDaniel.Beauregard@Sun.COM
160111924SDaniel.Beauregard@Sun.COM return (0);
160211924SDaniel.Beauregard@Sun.COM }
160311924SDaniel.Beauregard@Sun.COM
160411924SDaniel.Beauregard@Sun.COM static int
ql_8021_init_p3p(ql_adapter_state_t * ha)160511924SDaniel.Beauregard@Sun.COM ql_8021_init_p3p(ql_adapter_state_t *ha)
160611924SDaniel.Beauregard@Sun.COM {
160711924SDaniel.Beauregard@Sun.COM uint32_t data;
160811924SDaniel.Beauregard@Sun.COM
160911924SDaniel.Beauregard@Sun.COM /* ??? */
161011924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_PORT_MODE_ADDR, UNM_PORT_MODE_AUTO_NEG);
161111924SDaniel.Beauregard@Sun.COM delay(drv_usectohz(1000000));
161211924SDaniel.Beauregard@Sun.COM
161311924SDaniel.Beauregard@Sun.COM /* CAM RAM Cold Boot Register */
161411924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_RAM_COLD_BOOT, &data);
161511924SDaniel.Beauregard@Sun.COM if (data == 0x55555555) {
161611924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &data);
161711924SDaniel.Beauregard@Sun.COM if (data != 0x80000f) {
161811924SDaniel.Beauregard@Sun.COM EL(ha, "CRB_UNM_GLB_SW_RST=%x exit\n", data);
161911924SDaniel.Beauregard@Sun.COM return (-1);
162011924SDaniel.Beauregard@Sun.COM }
162111924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_RAM_COLD_BOOT, 0);
162211924SDaniel.Beauregard@Sun.COM }
162311924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, &data);
162411924SDaniel.Beauregard@Sun.COM data |= 1;
162511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, data);
162611924SDaniel.Beauregard@Sun.COM
162711924SDaniel.Beauregard@Sun.COM /*
162811924SDaniel.Beauregard@Sun.COM * ???
162911924SDaniel.Beauregard@Sun.COM * data = ha->pci_bus_addr | BIT_31;
163011924SDaniel.Beauregard@Sun.COM * ql_8021_wr_32(ha, UNM_BUS_DEV_NO, data);
163111924SDaniel.Beauregard@Sun.COM */
163211924SDaniel.Beauregard@Sun.COM
163311924SDaniel.Beauregard@Sun.COM return (0);
163411924SDaniel.Beauregard@Sun.COM }
163511924SDaniel.Beauregard@Sun.COM
163611924SDaniel.Beauregard@Sun.COM /* ARGSUSED */
163711924SDaniel.Beauregard@Sun.COM void
ql_8021_reset_chip(ql_adapter_state_t * ha)163811924SDaniel.Beauregard@Sun.COM ql_8021_reset_chip(ql_adapter_state_t *ha)
163911924SDaniel.Beauregard@Sun.COM {
1640*12279SDaniel.Beauregard@Sun.COM /*
1641*12279SDaniel.Beauregard@Sun.COM * Disable interrupts does not work on a per function bases
1642*12279SDaniel.Beauregard@Sun.COM * leave them enabled
1643*12279SDaniel.Beauregard@Sun.COM */
164411924SDaniel.Beauregard@Sun.COM ql_8021_enable_intrs(ha);
164511924SDaniel.Beauregard@Sun.COM
164611924SDaniel.Beauregard@Sun.COM ADAPTER_STATE_LOCK(ha);
164711924SDaniel.Beauregard@Sun.COM ha->flags |= INTERRUPTS_ENABLED;
164811924SDaniel.Beauregard@Sun.COM ADAPTER_STATE_UNLOCK(ha);
1649*12279SDaniel.Beauregard@Sun.COM
1650*12279SDaniel.Beauregard@Sun.COM (void) ql_stop_firmware(ha);
165111924SDaniel.Beauregard@Sun.COM }
165211924SDaniel.Beauregard@Sun.COM
165311924SDaniel.Beauregard@Sun.COM static int
ql_8021_reset_hw(ql_adapter_state_t * ha,int type)165411924SDaniel.Beauregard@Sun.COM ql_8021_reset_hw(ql_adapter_state_t *ha, int type)
165511924SDaniel.Beauregard@Sun.COM {
165611924SDaniel.Beauregard@Sun.COM int ret;
165711924SDaniel.Beauregard@Sun.COM uint32_t rst;
165811924SDaniel.Beauregard@Sun.COM
165911924SDaniel.Beauregard@Sun.COM /* scrub dma mask expansion register */
166011924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
166111924SDaniel.Beauregard@Sun.COM
166211924SDaniel.Beauregard@Sun.COM /* Overwrite stale initialization register values */
166311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_CMDPEG_STATE, 0);
166411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_RCVPEG_STATE, 0);
166511924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0);
166611924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0);
166711924SDaniel.Beauregard@Sun.COM
166811924SDaniel.Beauregard@Sun.COM (void) ql_8021_pinit_from_rom(ha);
166911924SDaniel.Beauregard@Sun.COM delay(1);
167011924SDaniel.Beauregard@Sun.COM
167111924SDaniel.Beauregard@Sun.COM /* Bring QM and CAMRAM out of reset */
167211924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &rst);
167311924SDaniel.Beauregard@Sun.COM rst &= ~((1 << 28) | (1 << 24));
167411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, rst);
167511924SDaniel.Beauregard@Sun.COM
167611924SDaniel.Beauregard@Sun.COM switch (type) {
167711924SDaniel.Beauregard@Sun.COM case 0:
167811924SDaniel.Beauregard@Sun.COM ret = ql_8021_init_p3p(ha);
167911924SDaniel.Beauregard@Sun.COM break;
168011924SDaniel.Beauregard@Sun.COM case 1:
168111924SDaniel.Beauregard@Sun.COM ret = ql_8021_load_from_flash(ha);
168211924SDaniel.Beauregard@Sun.COM break;
168311924SDaniel.Beauregard@Sun.COM case 2:
168411924SDaniel.Beauregard@Sun.COM ret = ql_8021_load_firmware(ha);
168511924SDaniel.Beauregard@Sun.COM break;
168611924SDaniel.Beauregard@Sun.COM }
168711924SDaniel.Beauregard@Sun.COM delay(1);
168811924SDaniel.Beauregard@Sun.COM
168911924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x18, 0x1020);
169011924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0x80001e);
169111924SDaniel.Beauregard@Sun.COM
169211924SDaniel.Beauregard@Sun.COM if (ret) {
169311924SDaniel.Beauregard@Sun.COM EL(ha, "type=%d, ret=%d\n", type, ret);
169411924SDaniel.Beauregard@Sun.COM } else {
169511924SDaniel.Beauregard@Sun.COM ret = ql_8021_phantom_init(ha);
169611924SDaniel.Beauregard@Sun.COM }
169711924SDaniel.Beauregard@Sun.COM return (ret);
169811924SDaniel.Beauregard@Sun.COM }
169911924SDaniel.Beauregard@Sun.COM
170011924SDaniel.Beauregard@Sun.COM int
ql_8021_load_risc(ql_adapter_state_t * ha)170111924SDaniel.Beauregard@Sun.COM ql_8021_load_risc(ql_adapter_state_t *ha)
170211924SDaniel.Beauregard@Sun.COM {
170311924SDaniel.Beauregard@Sun.COM int rv = 0;
170411924SDaniel.Beauregard@Sun.COM static int ql_8021_fw_loaded = 0;
170511924SDaniel.Beauregard@Sun.COM
170611924SDaniel.Beauregard@Sun.COM GLOBAL_HW_LOCK();
170711924SDaniel.Beauregard@Sun.COM if (!ql_8021_fw_loaded) {
170811924SDaniel.Beauregard@Sun.COM if (ha->risc_fw[0].code) {
170911924SDaniel.Beauregard@Sun.COM EL(ha, "from driver\n");
171011924SDaniel.Beauregard@Sun.COM rv = ql_8021_reset_hw(ha, 2);
171111924SDaniel.Beauregard@Sun.COM } else {
171211924SDaniel.Beauregard@Sun.COM /*
171311924SDaniel.Beauregard@Sun.COM * BIOS method
171411924SDaniel.Beauregard@Sun.COM * ql_8021_reset_hw(ha, 0)
171511924SDaniel.Beauregard@Sun.COM */
171611924SDaniel.Beauregard@Sun.COM EL(ha, "from flash\n");
171711924SDaniel.Beauregard@Sun.COM rv = ql_8021_reset_hw(ha, 1);
171811924SDaniel.Beauregard@Sun.COM }
171911924SDaniel.Beauregard@Sun.COM if (rv == 0) {
172011924SDaniel.Beauregard@Sun.COM ql_8021_fw_loaded = 1;
172111924SDaniel.Beauregard@Sun.COM
172211924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
172311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0x0);
172411924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0x0);
172511924SDaniel.Beauregard@Sun.COM
172611924SDaniel.Beauregard@Sun.COM GLOBAL_HW_UNLOCK();
172711924SDaniel.Beauregard@Sun.COM
172811924SDaniel.Beauregard@Sun.COM ADAPTER_STATE_LOCK(ha);
172911924SDaniel.Beauregard@Sun.COM ha->flags &= ~INTERRUPTS_ENABLED;
173011924SDaniel.Beauregard@Sun.COM ADAPTER_STATE_UNLOCK(ha);
173111924SDaniel.Beauregard@Sun.COM
173211924SDaniel.Beauregard@Sun.COM (void) ql_8021_enable_intrs(ha);
173311924SDaniel.Beauregard@Sun.COM
173411924SDaniel.Beauregard@Sun.COM ADAPTER_STATE_LOCK(ha);
173511924SDaniel.Beauregard@Sun.COM ha->flags |= INTERRUPTS_ENABLED;
173611924SDaniel.Beauregard@Sun.COM ADAPTER_STATE_UNLOCK(ha);
173711924SDaniel.Beauregard@Sun.COM } else {
173811924SDaniel.Beauregard@Sun.COM GLOBAL_HW_UNLOCK();
173911924SDaniel.Beauregard@Sun.COM }
174011924SDaniel.Beauregard@Sun.COM } else {
174111924SDaniel.Beauregard@Sun.COM GLOBAL_HW_UNLOCK();
174211924SDaniel.Beauregard@Sun.COM EL(ha, "Firmware loaded by other function\n");
174311924SDaniel.Beauregard@Sun.COM }
174411924SDaniel.Beauregard@Sun.COM
174511924SDaniel.Beauregard@Sun.COM if (rv == 0) {
174611924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR, &ha->fw_major_version);
174711924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR, &ha->fw_minor_version);
174811924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_FW_VERSION_SUB, &ha->fw_subminor_version);
174911924SDaniel.Beauregard@Sun.COM EL(ha, "fw v%d.%02d.%02d\n", ha->fw_major_version,
175011924SDaniel.Beauregard@Sun.COM ha->fw_minor_version, ha->fw_subminor_version);
175111924SDaniel.Beauregard@Sun.COM } else {
175211924SDaniel.Beauregard@Sun.COM EL(ha, "status = -1\n");
175311924SDaniel.Beauregard@Sun.COM return (QL_FUNCTION_FAILED);
175411924SDaniel.Beauregard@Sun.COM }
175511924SDaniel.Beauregard@Sun.COM
175611924SDaniel.Beauregard@Sun.COM return (QL_SUCCESS);
175711924SDaniel.Beauregard@Sun.COM }
175811924SDaniel.Beauregard@Sun.COM
175911924SDaniel.Beauregard@Sun.COM void
ql_8021_clr_hw_intr(ql_adapter_state_t * ha)176011924SDaniel.Beauregard@Sun.COM ql_8021_clr_hw_intr(ql_adapter_state_t *ha)
176111924SDaniel.Beauregard@Sun.COM {
176211924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
176311924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
176411924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
176511924SDaniel.Beauregard@Sun.COM }
176611924SDaniel.Beauregard@Sun.COM
176711924SDaniel.Beauregard@Sun.COM void
ql_8021_clr_fw_intr(ql_adapter_state_t * ha)176811924SDaniel.Beauregard@Sun.COM ql_8021_clr_fw_intr(ql_adapter_state_t *ha)
176911924SDaniel.Beauregard@Sun.COM {
177011924SDaniel.Beauregard@Sun.COM WRT32_IO_REG(ha, nx_risc_int, 0);
177111924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xfbff);
177211924SDaniel.Beauregard@Sun.COM }
177311924SDaniel.Beauregard@Sun.COM
177411924SDaniel.Beauregard@Sun.COM void
ql_8021_enable_intrs(ql_adapter_state_t * ha)177511924SDaniel.Beauregard@Sun.COM ql_8021_enable_intrs(ql_adapter_state_t *ha)
177611924SDaniel.Beauregard@Sun.COM {
177711924SDaniel.Beauregard@Sun.COM GLOBAL_HW_LOCK();
177811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
177911924SDaniel.Beauregard@Sun.COM GLOBAL_HW_UNLOCK();
178011924SDaniel.Beauregard@Sun.COM (void) ql_toggle_interrupt(ha, 1);
178111924SDaniel.Beauregard@Sun.COM }
178211924SDaniel.Beauregard@Sun.COM
178311924SDaniel.Beauregard@Sun.COM void
ql_8021_disable_intrs(ql_adapter_state_t * ha)178411924SDaniel.Beauregard@Sun.COM ql_8021_disable_intrs(ql_adapter_state_t *ha)
178511924SDaniel.Beauregard@Sun.COM {
178611924SDaniel.Beauregard@Sun.COM (void) ql_toggle_interrupt(ha, 0);
178711924SDaniel.Beauregard@Sun.COM GLOBAL_HW_LOCK();
178811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
178911924SDaniel.Beauregard@Sun.COM GLOBAL_HW_UNLOCK();
179011924SDaniel.Beauregard@Sun.COM }
179111924SDaniel.Beauregard@Sun.COM
179211924SDaniel.Beauregard@Sun.COM void
ql_8021_update_crb_int_ptr(ql_adapter_state_t * ha)179311924SDaniel.Beauregard@Sun.COM ql_8021_update_crb_int_ptr(ql_adapter_state_t *ha)
179411924SDaniel.Beauregard@Sun.COM {
179511924SDaniel.Beauregard@Sun.COM struct legacy_intr_set *nx_legacy_intr;
179611924SDaniel.Beauregard@Sun.COM
179711924SDaniel.Beauregard@Sun.COM ha->qdr_sn_window = (uint32_t)-1;
179811924SDaniel.Beauregard@Sun.COM ha->ddr_mn_window = (uint32_t)-1;
179911924SDaniel.Beauregard@Sun.COM nx_legacy_intr = &legacy_intr[ha->function_number];
180011924SDaniel.Beauregard@Sun.COM
180111924SDaniel.Beauregard@Sun.COM ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
180211924SDaniel.Beauregard@Sun.COM ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;
180311924SDaniel.Beauregard@Sun.COM ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
180411924SDaniel.Beauregard@Sun.COM ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
180511924SDaniel.Beauregard@Sun.COM }
180611924SDaniel.Beauregard@Sun.COM
180711924SDaniel.Beauregard@Sun.COM void
ql_8021_set_drv_active(ql_adapter_state_t * ha)180811924SDaniel.Beauregard@Sun.COM ql_8021_set_drv_active(ql_adapter_state_t *ha)
180911924SDaniel.Beauregard@Sun.COM {
181011924SDaniel.Beauregard@Sun.COM uint32_t val;
181111924SDaniel.Beauregard@Sun.COM
181211924SDaniel.Beauregard@Sun.COM if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
181311924SDaniel.Beauregard@Sun.COM return;
181411924SDaniel.Beauregard@Sun.COM }
181511924SDaniel.Beauregard@Sun.COM
181611924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
181711924SDaniel.Beauregard@Sun.COM if (val == 0xffffffff) {
181811924SDaniel.Beauregard@Sun.COM val = (1 << (ha->function_number * 4));
181911924SDaniel.Beauregard@Sun.COM } else {
182011924SDaniel.Beauregard@Sun.COM val |= (1 << (ha->function_number * 4));
182111924SDaniel.Beauregard@Sun.COM }
182211924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
182311924SDaniel.Beauregard@Sun.COM
182411924SDaniel.Beauregard@Sun.COM ql_8021_hw_unlock(ha);
182511924SDaniel.Beauregard@Sun.COM }
182611924SDaniel.Beauregard@Sun.COM
182711924SDaniel.Beauregard@Sun.COM void
ql_8021_clr_drv_active(ql_adapter_state_t * ha)182811924SDaniel.Beauregard@Sun.COM ql_8021_clr_drv_active(ql_adapter_state_t *ha)
182911924SDaniel.Beauregard@Sun.COM {
183011924SDaniel.Beauregard@Sun.COM uint32_t val;
183111924SDaniel.Beauregard@Sun.COM
183211924SDaniel.Beauregard@Sun.COM if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
183311924SDaniel.Beauregard@Sun.COM return;
183411924SDaniel.Beauregard@Sun.COM }
183511924SDaniel.Beauregard@Sun.COM
183611924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
183711924SDaniel.Beauregard@Sun.COM val &= ~(1 << (ha->function_number * 4));
183811924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
183911924SDaniel.Beauregard@Sun.COM
184011924SDaniel.Beauregard@Sun.COM ql_8021_hw_unlock(ha);
184111924SDaniel.Beauregard@Sun.COM }
184211924SDaniel.Beauregard@Sun.COM
184311924SDaniel.Beauregard@Sun.COM static void
ql_8021_need_reset_handler(ql_adapter_state_t * ha)184411924SDaniel.Beauregard@Sun.COM ql_8021_need_reset_handler(ql_adapter_state_t *ha)
184511924SDaniel.Beauregard@Sun.COM {
184611924SDaniel.Beauregard@Sun.COM uint32_t drv_state, drv_active;
184711924SDaniel.Beauregard@Sun.COM clock_t timer;
184811924SDaniel.Beauregard@Sun.COM
184911924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
185011924SDaniel.Beauregard@Sun.COM
185111924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
185211924SDaniel.Beauregard@Sun.COM drv_state |= (1 << (ha->function_number * 4));
185311924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
185411924SDaniel.Beauregard@Sun.COM
185511924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
185611924SDaniel.Beauregard@Sun.COM
185711924SDaniel.Beauregard@Sun.COM ql_8021_hw_unlock(ha);
185811924SDaniel.Beauregard@Sun.COM
185911924SDaniel.Beauregard@Sun.COM for (timer = 30; timer && drv_state != drv_active; timer--) {
186011924SDaniel.Beauregard@Sun.COM delay(100);
186111924SDaniel.Beauregard@Sun.COM
186211924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
186311924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
186411924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
186511924SDaniel.Beauregard@Sun.COM ql_8021_hw_unlock(ha);
186611924SDaniel.Beauregard@Sun.COM }
186711924SDaniel.Beauregard@Sun.COM }
186811924SDaniel.Beauregard@Sun.COM
186911924SDaniel.Beauregard@Sun.COM uint32_t
ql_8021_idc_handler(ql_adapter_state_t * ha)187011924SDaniel.Beauregard@Sun.COM ql_8021_idc_handler(ql_adapter_state_t *ha)
187111924SDaniel.Beauregard@Sun.COM {
187211924SDaniel.Beauregard@Sun.COM uint32_t dev_state, drv_state, rval;
187311924SDaniel.Beauregard@Sun.COM clock_t timer;
187411924SDaniel.Beauregard@Sun.COM ql_mbx_data_t mr;
187511924SDaniel.Beauregard@Sun.COM boolean_t stalled = B_FALSE, lock = B_FALSE;
187611924SDaniel.Beauregard@Sun.COM
187711924SDaniel.Beauregard@Sun.COM /* wait for 30 seconds for device to go ready */
187811924SDaniel.Beauregard@Sun.COM timer = 30;
187911924SDaniel.Beauregard@Sun.COM while (timer) {
188011924SDaniel.Beauregard@Sun.COM if (lock == B_FALSE) {
188111924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
188211924SDaniel.Beauregard@Sun.COM lock = B_TRUE;
188311924SDaniel.Beauregard@Sun.COM }
188411924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
188511924SDaniel.Beauregard@Sun.COM
188611924SDaniel.Beauregard@Sun.COM switch (dev_state) {
188711924SDaniel.Beauregard@Sun.COM case 0xffffffff:
188811924SDaniel.Beauregard@Sun.COM case NX_DEV_COLD:
188911924SDaniel.Beauregard@Sun.COM EL(ha, "dev_state=NX_DEV_COLD\n");
189011924SDaniel.Beauregard@Sun.COM rval = NX_DEV_COLD;
189111924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
189211924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DRV_IDC_VERSION, NX_IDC_VERSION);
189311924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_unlock(ha);
189411924SDaniel.Beauregard@Sun.COM if (ql_get_fw_version(ha, &mr, 2) == QL_SUCCESS &&
189511924SDaniel.Beauregard@Sun.COM (mr.mb[1] | mr.mb[2] | mr.mb[3])) {
189611924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR,
189711924SDaniel.Beauregard@Sun.COM &ha->fw_major_version);
189811924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR,
189911924SDaniel.Beauregard@Sun.COM &ha->fw_minor_version);
190011924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, UNM_FW_VERSION_SUB,
190111924SDaniel.Beauregard@Sun.COM &ha->fw_subminor_version);
190211924SDaniel.Beauregard@Sun.COM rval = NX_DEV_READY;
190311924SDaniel.Beauregard@Sun.COM } else if (ql_8021_load_risc(ha) == QL_SUCCESS) {
190411924SDaniel.Beauregard@Sun.COM rval = NX_DEV_READY;
190511924SDaniel.Beauregard@Sun.COM }
190611924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
190711924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DEV_STATE, rval);
190811924SDaniel.Beauregard@Sun.COM break;
190911924SDaniel.Beauregard@Sun.COM case NX_DEV_READY:
191011924SDaniel.Beauregard@Sun.COM rval = NX_DEV_READY;
191111924SDaniel.Beauregard@Sun.COM timer = 0;
191211924SDaniel.Beauregard@Sun.COM break;
191311924SDaniel.Beauregard@Sun.COM case NX_DEV_FAILED:
191411924SDaniel.Beauregard@Sun.COM EL(ha, "dev_state=NX_DEV_FAILED\n");
191511924SDaniel.Beauregard@Sun.COM rval = NX_DEV_FAILED;
191611924SDaniel.Beauregard@Sun.COM timer = 0;
191711924SDaniel.Beauregard@Sun.COM break;
191811924SDaniel.Beauregard@Sun.COM
191911924SDaniel.Beauregard@Sun.COM case NX_DEV_NEED_RESET:
192011924SDaniel.Beauregard@Sun.COM EL(ha, "dev_state=NX_DEV_NEED_RESET\n");
192111924SDaniel.Beauregard@Sun.COM rval = NX_DEV_NEED_RESET;
192211924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_unlock(ha);
192311924SDaniel.Beauregard@Sun.COM lock = B_FALSE;
192411924SDaniel.Beauregard@Sun.COM if (ql_stall_driver(ha, 0) == QL_SUCCESS) {
192511924SDaniel.Beauregard@Sun.COM stalled = B_TRUE;
192611924SDaniel.Beauregard@Sun.COM ql_8021_need_reset_handler(ha);
192711924SDaniel.Beauregard@Sun.COM }
192811924SDaniel.Beauregard@Sun.COM break;
192911924SDaniel.Beauregard@Sun.COM
193011924SDaniel.Beauregard@Sun.COM case NX_DEV_NEED_QUIESCENT:
193111924SDaniel.Beauregard@Sun.COM EL(ha, "dev_state=NX_DEV_NEED_QUIESCENT\n");
193211924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_unlock(ha);
193311924SDaniel.Beauregard@Sun.COM lock = B_FALSE;
193411924SDaniel.Beauregard@Sun.COM rval = ql_stall_driver(ha, 0);
193511924SDaniel.Beauregard@Sun.COM if (rval == QL_SUCCESS) {
193611924SDaniel.Beauregard@Sun.COM stalled = B_TRUE;
193711924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
193811924SDaniel.Beauregard@Sun.COM lock = B_TRUE;
193911924SDaniel.Beauregard@Sun.COM ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
194011924SDaniel.Beauregard@Sun.COM drv_state |=
194111924SDaniel.Beauregard@Sun.COM (2 << (ha->function_number * 4));
194211924SDaniel.Beauregard@Sun.COM ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
194311924SDaniel.Beauregard@Sun.COM }
194411924SDaniel.Beauregard@Sun.COM break;
194511924SDaniel.Beauregard@Sun.COM
194611924SDaniel.Beauregard@Sun.COM case NX_DEV_INITIALIZING:
194711924SDaniel.Beauregard@Sun.COM EL(ha, "dev_state=NX_DEV_INITIALIZING\n");
194811924SDaniel.Beauregard@Sun.COM break;
194911924SDaniel.Beauregard@Sun.COM case NX_DEV_QUIESCENT:
195011924SDaniel.Beauregard@Sun.COM EL(ha, "dev_state=NX_DEV_QUIESCENT\n");
195111924SDaniel.Beauregard@Sun.COM break;
195211924SDaniel.Beauregard@Sun.COM default:
195311924SDaniel.Beauregard@Sun.COM EL(ha, "dev_state=%x, default\n", dev_state);
195411924SDaniel.Beauregard@Sun.COM break;
195511924SDaniel.Beauregard@Sun.COM }
195611924SDaniel.Beauregard@Sun.COM if (lock == B_TRUE) {
195711924SDaniel.Beauregard@Sun.COM (void) ql_8021_hw_unlock(ha);
195811924SDaniel.Beauregard@Sun.COM lock = B_FALSE;
195911924SDaniel.Beauregard@Sun.COM }
196011924SDaniel.Beauregard@Sun.COM
196111924SDaniel.Beauregard@Sun.COM if (timer) {
196211924SDaniel.Beauregard@Sun.COM delay(100);
196311924SDaniel.Beauregard@Sun.COM timer--;
196411924SDaniel.Beauregard@Sun.COM }
196511924SDaniel.Beauregard@Sun.COM }
196611924SDaniel.Beauregard@Sun.COM
196711924SDaniel.Beauregard@Sun.COM if (stalled) {
196811924SDaniel.Beauregard@Sun.COM ql_restart_driver(ha);
196911924SDaniel.Beauregard@Sun.COM }
197011924SDaniel.Beauregard@Sun.COM return (rval);
197111924SDaniel.Beauregard@Sun.COM }
1972