xref: /onnv-gate/usr/src/uts/common/io/ntxn/unm_nic_hw.c (revision 8687:5dca9cd6354a)
17956Sxiuyan.wang@Sun.COM /*
27956Sxiuyan.wang@Sun.COM  * CDDL HEADER START
37956Sxiuyan.wang@Sun.COM  *
47956Sxiuyan.wang@Sun.COM  * The contents of this file are subject to the terms of the
57956Sxiuyan.wang@Sun.COM  * Common Development and Distribution License (the "License").
67956Sxiuyan.wang@Sun.COM  * You may not use this file except in compliance with the License.
77956Sxiuyan.wang@Sun.COM  *
87956Sxiuyan.wang@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97956Sxiuyan.wang@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107956Sxiuyan.wang@Sun.COM  * See the License for the specific language governing permissions
117956Sxiuyan.wang@Sun.COM  * and limitations under the License.
127956Sxiuyan.wang@Sun.COM  *
137956Sxiuyan.wang@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147956Sxiuyan.wang@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157956Sxiuyan.wang@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167956Sxiuyan.wang@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177956Sxiuyan.wang@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187956Sxiuyan.wang@Sun.COM  *
197956Sxiuyan.wang@Sun.COM  * CDDL HEADER END
207956Sxiuyan.wang@Sun.COM  */
21*8687SJing.Xiong@Sun.COM 
227956Sxiuyan.wang@Sun.COM /*
237956Sxiuyan.wang@Sun.COM  * Copyright 2008 NetXen, Inc.  All rights reserved.
247956Sxiuyan.wang@Sun.COM  * Use is subject to license terms.
257956Sxiuyan.wang@Sun.COM  */
26*8687SJing.Xiong@Sun.COM 
277956Sxiuyan.wang@Sun.COM #include <sys/types.h>
287956Sxiuyan.wang@Sun.COM #include <sys/conf.h>
297956Sxiuyan.wang@Sun.COM #include <sys/debug.h>
307956Sxiuyan.wang@Sun.COM #include <sys/stropts.h>
317956Sxiuyan.wang@Sun.COM #include <sys/stream.h>
327956Sxiuyan.wang@Sun.COM #include <sys/strlog.h>
337956Sxiuyan.wang@Sun.COM #include <sys/kmem.h>
347956Sxiuyan.wang@Sun.COM #include <sys/stat.h>
357956Sxiuyan.wang@Sun.COM #include <sys/kstat.h>
367956Sxiuyan.wang@Sun.COM #include <sys/vtrace.h>
377956Sxiuyan.wang@Sun.COM #include <sys/dlpi.h>
387956Sxiuyan.wang@Sun.COM #include <sys/strsun.h>
397956Sxiuyan.wang@Sun.COM #include <sys/ethernet.h>
407956Sxiuyan.wang@Sun.COM #include <sys/modctl.h>
417956Sxiuyan.wang@Sun.COM #include <sys/errno.h>
427956Sxiuyan.wang@Sun.COM #include <sys/dditypes.h>
437956Sxiuyan.wang@Sun.COM #include <sys/ddi.h>
447956Sxiuyan.wang@Sun.COM #include <sys/sunddi.h>
457956Sxiuyan.wang@Sun.COM #include <sys/sysmacros.h>
467956Sxiuyan.wang@Sun.COM 
477956Sxiuyan.wang@Sun.COM #include <sys/pci.h>
487956Sxiuyan.wang@Sun.COM 
497956Sxiuyan.wang@Sun.COM #include "unm_nic.h"
507956Sxiuyan.wang@Sun.COM #include "unm_nic_hw.h"
517956Sxiuyan.wang@Sun.COM #include "nic_cmn.h"
527956Sxiuyan.wang@Sun.COM #include "unm_brdcfg.h"
537956Sxiuyan.wang@Sun.COM #include "driver_info.h"
547956Sxiuyan.wang@Sun.COM 
557956Sxiuyan.wang@Sun.COM long unm_niu_gbe_phy_read(struct unm_adapter_s *,
567956Sxiuyan.wang@Sun.COM 		long reg, unm_crbword_t *readval);
577956Sxiuyan.wang@Sun.COM 
587956Sxiuyan.wang@Sun.COM #define	MASK(n)			((1ULL<<(n))-1)
597956Sxiuyan.wang@Sun.COM #define	MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
607956Sxiuyan.wang@Sun.COM #define	OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) |	\
617956Sxiuyan.wang@Sun.COM 		((addr >> 25) & 0x3ff)) // 64K?
627956Sxiuyan.wang@Sun.COM #define	MS_WIN(addr) (addr & 0x0ffc0000)
637956Sxiuyan.wang@Sun.COM #define	UNM_PCI_MN_2M   (0)
647956Sxiuyan.wang@Sun.COM #define	UNM_PCI_MS_2M   (0x80000)
657956Sxiuyan.wang@Sun.COM #define	UNM_PCI_OCM0_2M (0xc0000)
667956Sxiuyan.wang@Sun.COM #define	VALID_OCM_ADDR(addr) (((addr) & 0x3f800) != 0x3f800)
677956Sxiuyan.wang@Sun.COM #define	GET_MEM_OFFS_2M(addr) (addr & MASK(18))
687956Sxiuyan.wang@Sun.COM 
697956Sxiuyan.wang@Sun.COM #define	CRB_BLK(off)	((off >> 20) & 0x3f)
707956Sxiuyan.wang@Sun.COM #define	CRB_SUBBLK(off)	((off >> 16) & 0xf)
717956Sxiuyan.wang@Sun.COM #define	CRB_WINDOW_2M	(0x130060)
727956Sxiuyan.wang@Sun.COM #define	UNM_PCI_CAMQM_2M_END	(0x04800800UL)
737956Sxiuyan.wang@Sun.COM #define	CRB_HI(off)	((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
747956Sxiuyan.wang@Sun.COM #define	UNM_PCI_CAMQM_2M_BASE	(0x000ff800UL)
757956Sxiuyan.wang@Sun.COM #define	CRB_INDIRECT_2M	(0x1e0000UL)
767956Sxiuyan.wang@Sun.COM 
777956Sxiuyan.wang@Sun.COM static crb_128M_2M_block_map_t	crb_128M_2M_map[64] = {
787956Sxiuyan.wang@Sun.COM 	    {{{0, 0, 0, 0}}}, /* 0: PCI */
797956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
807956Sxiuyan.wang@Sun.COM 	    {1, 0x0110000, 0x0120000, 0x130000},
817956Sxiuyan.wang@Sun.COM 	    {1, 0x0120000, 0x0122000, 0x124000},
827956Sxiuyan.wang@Sun.COM 	    {1, 0x0130000, 0x0132000, 0x126000},
837956Sxiuyan.wang@Sun.COM 	    {1, 0x0140000, 0x0142000, 0x128000},
847956Sxiuyan.wang@Sun.COM 	    {1, 0x0150000, 0x0152000, 0x12a000},
857956Sxiuyan.wang@Sun.COM 	    {1, 0x0160000, 0x0170000, 0x110000},
867956Sxiuyan.wang@Sun.COM 	    {1, 0x0170000, 0x0172000, 0x12e000},
877956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
887956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
897956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
907956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
917956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
927956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
937956Sxiuyan.wang@Sun.COM 	    {1, 0x01e0000, 0x01e0800, 0x122000},
947956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000}}},
957956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0200000, 0x0210000, 0x180000}}}, /* 2: MN */
967956Sxiuyan.wang@Sun.COM 	    {{{0, 0, 0, 0}}}, /* 3: */
977956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0400000, 0x0401000, 0x169000}}}, /* 4: P2NR1 */
987956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0500000, 0x0510000, 0x140000}}}, /* 5: SRE   */
997956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0600000, 0x0610000, 0x1c0000}}}, /* 6: NIU   */
1007956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0700000, 0x0704000, 0x1b8000}}}, /* 7: QM    */
1017956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0  */
1027956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1037956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1047956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1057956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1067956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1077956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1087956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1097956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1107956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1117956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1127956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1137956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1147956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1157956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1167956Sxiuyan.wang@Sun.COM 	    {1, 0x08f0000, 0x08f2000, 0x172000}}},
1177956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1 */
1187956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1197956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1207956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1217956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1227956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1237956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1247956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1257956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1267956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1277956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1287956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1297956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1307956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1317956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1327956Sxiuyan.wang@Sun.COM 	    {1, 0x09f0000, 0x09f2000, 0x176000}}},
1337956Sxiuyan.wang@Sun.COM 	    {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2 */
1347956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1357956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1367956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1377956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1387956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1397956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1407956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1417956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1427956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1437956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1447956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1457956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1467956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1477956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1487956Sxiuyan.wang@Sun.COM 	    {1, 0x0af0000, 0x0af2000, 0x17a000}}},
1497956Sxiuyan.wang@Sun.COM 	    {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3 */
1507956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1517956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1527956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1537956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1547956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1557956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1567956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1577956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1587956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1597956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1607956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1617956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1627956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1637956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1647956Sxiuyan.wang@Sun.COM 	    {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
1657956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0c00000, 0x0c04000, 0x1d4000}}}, /* 12: I2Q */
1667956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0d00000, 0x0d04000, 0x1a4000}}}, /* 13: TMR */
1677956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0e00000, 0x0e04000, 0x1a0000}}}, /* 14: ROMUSB */
1687956Sxiuyan.wang@Sun.COM 	    {{{1, 0x0f00000, 0x0f01000, 0x164000}}}, /* 15: PEG4 */
1697956Sxiuyan.wang@Sun.COM 	    {{{0, 0x1000000, 0x1004000, 0x1a8000}}}, /* 16: XDMA */
1707956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1100000, 0x1101000, 0x160000}}}, /* 17: PEG0 */
1717956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1200000, 0x1201000, 0x161000}}}, /* 18: PEG1 */
1727956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1300000, 0x1301000, 0x162000}}}, /* 19: PEG2 */
1737956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1400000, 0x1401000, 0x163000}}}, /* 20: PEG3 */
1747956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1500000, 0x1501000, 0x165000}}}, /* 21: P2ND */
1757956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1600000, 0x1601000, 0x166000}}}, /* 22: P2NI */
1767956Sxiuyan.wang@Sun.COM 	    {{{0, 0, 0, 0}}}, /* 23: */
1777956Sxiuyan.wang@Sun.COM 	    {{{0, 0, 0, 0}}}, /* 24: */
1787956Sxiuyan.wang@Sun.COM 	    {{{0, 0, 0, 0}}}, /* 25: */
1797956Sxiuyan.wang@Sun.COM 	    {{{0, 0, 0, 0}}}, /* 26: */
1807956Sxiuyan.wang@Sun.COM 	    {{{0, 0, 0, 0}}}, /* 27: */
1817956Sxiuyan.wang@Sun.COM 	    {{{0, 0, 0, 0}}}, /* 28: */
1827956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1d00000, 0x1d10000, 0x190000}}}, /* 29: MS */
1837956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1e00000, 0x1e01000, 0x16a000}}}, /* 30: P2NR2 */
1847956Sxiuyan.wang@Sun.COM 	    {{{1, 0x1f00000, 0x1f10000, 0x150000}}}, /* 31: EPG */
1857956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 32: PCI */
1867956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */
1877956Sxiuyan.wang@Sun.COM 	    {1, 0x2110000, 0x2120000, 0x130000},
1887956Sxiuyan.wang@Sun.COM 	    {1, 0x2120000, 0x2122000, 0x124000},
1897956Sxiuyan.wang@Sun.COM 	    {1, 0x2130000, 0x2132000, 0x126000},
1907956Sxiuyan.wang@Sun.COM 	    {1, 0x2140000, 0x2142000, 0x128000},
1917956Sxiuyan.wang@Sun.COM 	    {1, 0x2150000, 0x2152000, 0x12a000},
1927956Sxiuyan.wang@Sun.COM 	    {1, 0x2160000, 0x2170000, 0x110000},
1937956Sxiuyan.wang@Sun.COM 	    {1, 0x2170000, 0x2172000, 0x12e000},
1947956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1957956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1967956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1977956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1987956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
1997956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
2007956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000},
2017956Sxiuyan.wang@Sun.COM 	    {0, 0x0000000, 0x0000000, 0x000000}}},
2027956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2200000, 0x2204000, 0x1b0000}}}, /* 34: CAM */
2037956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 35: */
2047956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 36: */
2057956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 37: */
2067956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 38: */
2077956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 39: */
2087956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2800000, 0x2804000, 0x1a4000}}}, /* 40: TMR */
2097956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2900000, 0x2901000, 0x16b000}}}, /* 41: P2NR3 */
2107956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2a00000, 0x2a00400, 0x1ac400}}}, /* 42: RPMX1 */
2117956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2b00000, 0x2b00400, 0x1ac800}}}, /* 43: RPMX2 */
2127956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2c00000, 0x2c00400, 0x1acc00}}}, /* 44: RPMX3 */
2137956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2d00000, 0x2d00400, 0x1ad000}}}, /* 45: RPMX4 */
2147956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2e00000, 0x2e00400, 0x1ad400}}}, /* 46: RPMX5 */
2157956Sxiuyan.wang@Sun.COM 	    {{{1, 0x2f00000, 0x2f00400, 0x1ad800}}}, /* 47: RPMX6 */
2167956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3000000, 0x3000400, 0x1adc00}}}, /* 48: RPMX7 */
2177956Sxiuyan.wang@Sun.COM 	    {{{0, 0x3100000, 0x3104000, 0x1a8000}}}, /* 49: XDMA */
2187956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3200000, 0x3204000, 0x1d4000}}}, /* 50: I2Q */
2197956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3300000, 0x3304000, 0x1a0000}}}, /* 51: ROMUSB */
2207956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 52: */
2217956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3500000, 0x3500400, 0x1ac000}}}, /* 53: RPMX0 */
2227956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3600000, 0x3600400, 0x1ae000}}}, /* 54: RPMX8 */
2237956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3700000, 0x3700400, 0x1ae400}}}, /* 55: RPMX9 */
2247956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3800000, 0x3804000, 0x1d0000}}}, /* 56: OCM0 */
2257956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3900000, 0x3904000, 0x1b4000}}}, /* 57: CRYPTO */
2267956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3a00000, 0x3a04000, 0x1d8000}}}, /* 58: SMB */
2277956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 59: I2C0 */
2287956Sxiuyan.wang@Sun.COM 	    {{{0}}}, /* 60: I2C1 */
2297956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3d00000, 0x3d04000, 0x1d8000}}}, /* 61: LPC */
2307956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3e00000, 0x3e01000, 0x167000}}}, /* 62: P2NC */
2317956Sxiuyan.wang@Sun.COM 	    {{{1, 0x3f00000, 0x3f01000, 0x168000}}} /* 63: P2NR0 */
2327956Sxiuyan.wang@Sun.COM };
2337956Sxiuyan.wang@Sun.COM 
2347956Sxiuyan.wang@Sun.COM /*
2357956Sxiuyan.wang@Sun.COM  * top 12 bits of crb internal address (hub, agent)
2367956Sxiuyan.wang@Sun.COM  */
2377956Sxiuyan.wang@Sun.COM static unsigned crb_hub_agt[64] = {
2387956Sxiuyan.wang@Sun.COM 	0,
2397956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PS,
2407956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_MN,
2417956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_MS,
2427956Sxiuyan.wang@Sun.COM 	0,
2437956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_SRE,
2447956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_NIU,
2457956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_QMN,
2467956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_SQN0,
2477956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_SQN1,
2487956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_SQN2,
2497956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_SQN3,
2507956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
2517956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
2527956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
2537956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGN4,
2547956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
2557956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGN0,
2567956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGN1,
2577956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGN2,
2587956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGN3,
2597956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGND,
2607956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGNI,
2617956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGS0,
2627956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGS1,
2637956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGS2,
2647956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGS3,
2657956Sxiuyan.wang@Sun.COM 	0,
2667956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGSI,
2677956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_SN,
2687956Sxiuyan.wang@Sun.COM 	0,
2697956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_EG,
2707956Sxiuyan.wang@Sun.COM 	0,
2717956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PS,
2727956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_CAM,
2737956Sxiuyan.wang@Sun.COM 	0,
2747956Sxiuyan.wang@Sun.COM 	0,
2757956Sxiuyan.wang@Sun.COM 	0,
2767956Sxiuyan.wang@Sun.COM 	0,
2777956Sxiuyan.wang@Sun.COM 	0,
2787956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
2797956Sxiuyan.wang@Sun.COM 	0,
2807956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
2817956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
2827956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
2837956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
2847956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
2857956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
2867956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
2877956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
2887956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
2897956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
2907956Sxiuyan.wang@Sun.COM 	0,
2917956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
2927956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
2937956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
2947956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_OCM0,
2957956Sxiuyan.wang@Sun.COM 	0,
2967956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_SMB,
2977956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_I2C0,
2987956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_I2C1,
2997956Sxiuyan.wang@Sun.COM 	0,
3007956Sxiuyan.wang@Sun.COM 	UNM_HW_CRB_HUB_AGT_ADR_PGNC,
3017956Sxiuyan.wang@Sun.COM 	0,
3027956Sxiuyan.wang@Sun.COM };
3037956Sxiuyan.wang@Sun.COM 
3047956Sxiuyan.wang@Sun.COM #define	CRB_WIN_LOCK_TIMEOUT 100000000
3057956Sxiuyan.wang@Sun.COM 
3067956Sxiuyan.wang@Sun.COM static void
crb_win_lock(struct unm_adapter_s * adapter)3077956Sxiuyan.wang@Sun.COM crb_win_lock(struct unm_adapter_s *adapter)
3087956Sxiuyan.wang@Sun.COM {
3097956Sxiuyan.wang@Sun.COM 	int i;
3107956Sxiuyan.wang@Sun.COM 	int done = 0, timeout = 0;
3117956Sxiuyan.wang@Sun.COM 
3127956Sxiuyan.wang@Sun.COM 	while (!done) {
3137956Sxiuyan.wang@Sun.COM 		/* acquire semaphore3 from PCI HW block */
3147956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_read_wx(adapter,
3157956Sxiuyan.wang@Sun.COM 		    UNM_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
3167956Sxiuyan.wang@Sun.COM 		if (done == 1)
3177956Sxiuyan.wang@Sun.COM 			break;
3187956Sxiuyan.wang@Sun.COM 		if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
3197956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s%d: crb_win_lock timed out\n",
3207956Sxiuyan.wang@Sun.COM 			    adapter->name, adapter->instance);
3217956Sxiuyan.wang@Sun.COM 			return;
3227956Sxiuyan.wang@Sun.COM 		}
3237956Sxiuyan.wang@Sun.COM 		timeout++;
3247956Sxiuyan.wang@Sun.COM 		/*
3257956Sxiuyan.wang@Sun.COM 		 *  Yield CPU
3267956Sxiuyan.wang@Sun.COM 		 */
3277956Sxiuyan.wang@Sun.COM 		for (i = 0; i < 20; i++);
3287956Sxiuyan.wang@Sun.COM 	}
3297956Sxiuyan.wang@Sun.COM 	adapter->unm_crb_writelit_adapter(adapter, UNM_CRB_WIN_LOCK_ID,
3307956Sxiuyan.wang@Sun.COM 	    adapter->portnum);
3317956Sxiuyan.wang@Sun.COM }
3327956Sxiuyan.wang@Sun.COM 
3337956Sxiuyan.wang@Sun.COM static void
crb_win_unlock(struct unm_adapter_s * adapter)3347956Sxiuyan.wang@Sun.COM crb_win_unlock(struct unm_adapter_s *adapter)
3357956Sxiuyan.wang@Sun.COM {
3367956Sxiuyan.wang@Sun.COM 	int	val;
3377956Sxiuyan.wang@Sun.COM 
3387956Sxiuyan.wang@Sun.COM 	adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_SEM7_UNLOCK),
3397956Sxiuyan.wang@Sun.COM 	    &val, 4);
3407956Sxiuyan.wang@Sun.COM }
3417956Sxiuyan.wang@Sun.COM 
3427956Sxiuyan.wang@Sun.COM /*
3437956Sxiuyan.wang@Sun.COM  * Changes the CRB window to the specified window.
3447956Sxiuyan.wang@Sun.COM  */
3457956Sxiuyan.wang@Sun.COM void
unm_nic_pci_change_crbwindow_128M(unm_adapter * adapter,uint32_t wndw)3467956Sxiuyan.wang@Sun.COM unm_nic_pci_change_crbwindow_128M(unm_adapter *adapter, uint32_t wndw)
3477956Sxiuyan.wang@Sun.COM {
3487956Sxiuyan.wang@Sun.COM 	unm_pcix_crb_window_t	window;
3497956Sxiuyan.wang@Sun.COM 	unsigned long			offset;
3507956Sxiuyan.wang@Sun.COM 	uint32_t				tmp;
3517956Sxiuyan.wang@Sun.COM 
3527956Sxiuyan.wang@Sun.COM 	if (adapter->curr_window == wndw) {
3537956Sxiuyan.wang@Sun.COM 		return;
3547956Sxiuyan.wang@Sun.COM 	}
3557956Sxiuyan.wang@Sun.COM 
3567956Sxiuyan.wang@Sun.COM 	/*
3577956Sxiuyan.wang@Sun.COM 	 * Move the CRB window.
3587956Sxiuyan.wang@Sun.COM 	 * We need to write to the "direct access" region of PCI
3597956Sxiuyan.wang@Sun.COM 	 * to avoid a race condition where the window register has
3607956Sxiuyan.wang@Sun.COM 	 * not been successfully written across CRB before the target
3617956Sxiuyan.wang@Sun.COM 	 * register address is received by PCI. The direct region bypasses
3627956Sxiuyan.wang@Sun.COM 	 * the CRB bus.
3637956Sxiuyan.wang@Sun.COM 	 */
3647956Sxiuyan.wang@Sun.COM 	offset = PCI_OFFSET_SECOND_RANGE(adapter,
3657956Sxiuyan.wang@Sun.COM 	    UNM_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(adapter->ahw.pci_func)));
3667956Sxiuyan.wang@Sun.COM 
3677956Sxiuyan.wang@Sun.COM 	*(unm_crbword_t *)&window = 0;
3687956Sxiuyan.wang@Sun.COM 	window.addrbit = wndw;
3697956Sxiuyan.wang@Sun.COM 	UNM_NIC_PCI_WRITE_32(*(unsigned int *)&window, (void*) (offset));
3707956Sxiuyan.wang@Sun.COM 	/* MUST make sure window is set before we forge on... */
3717956Sxiuyan.wang@Sun.COM 	while ((tmp = UNM_NIC_PCI_READ_32((void*) offset)) !=
3727956Sxiuyan.wang@Sun.COM 	    *(uint32_t *)&window) {
3737956Sxiuyan.wang@Sun.COM 		cmn_err(CE_WARN, "%s: %s WARNING: CRB window value not "
3747956Sxiuyan.wang@Sun.COM 		    "registered properly: 0x%08x.\n",
3757956Sxiuyan.wang@Sun.COM 		    unm_nic_driver_name, __FUNCTION__, tmp);
3767956Sxiuyan.wang@Sun.COM 	}
3777956Sxiuyan.wang@Sun.COM 
3787956Sxiuyan.wang@Sun.COM 	adapter->curr_window = wndw;
3797956Sxiuyan.wang@Sun.COM }
3807956Sxiuyan.wang@Sun.COM 
3817956Sxiuyan.wang@Sun.COM 
3827956Sxiuyan.wang@Sun.COM /*
3837956Sxiuyan.wang@Sun.COM  * Changes the CRB window to the specified window.
3847956Sxiuyan.wang@Sun.COM  */
3857956Sxiuyan.wang@Sun.COM /* ARGSUSED */
3867956Sxiuyan.wang@Sun.COM void
unm_nic_pci_change_crbwindow_2M(unm_adapter * adapter,uint32_t wndw)3877956Sxiuyan.wang@Sun.COM unm_nic_pci_change_crbwindow_2M(unm_adapter *adapter, uint32_t wndw)
3887956Sxiuyan.wang@Sun.COM {
3897956Sxiuyan.wang@Sun.COM }
3907956Sxiuyan.wang@Sun.COM 
3917956Sxiuyan.wang@Sun.COM 
3927956Sxiuyan.wang@Sun.COM uint32_t
unm_nic_get_crbwindow(unm_adapter * adapter)3937956Sxiuyan.wang@Sun.COM unm_nic_get_crbwindow(unm_adapter *adapter)
3947956Sxiuyan.wang@Sun.COM {
3957956Sxiuyan.wang@Sun.COM 	return (adapter->curr_window);
3967956Sxiuyan.wang@Sun.COM }
3977956Sxiuyan.wang@Sun.COM 
3987956Sxiuyan.wang@Sun.COM /*
3997956Sxiuyan.wang@Sun.COM  * Return -1 if off is not valid,
4007956Sxiuyan.wang@Sun.COM  *	 1 if window access is needed. 'off' is set to offset from
4017956Sxiuyan.wang@Sun.COM  *	   CRB space in 128M pci map
4027956Sxiuyan.wang@Sun.COM  *	 0 if no window access is needed. 'off' is set to 2M addr
4037956Sxiuyan.wang@Sun.COM  * In: 'off' is offset from base in 128M pci map
4047956Sxiuyan.wang@Sun.COM  */
4057956Sxiuyan.wang@Sun.COM int
unm_nic_pci_get_crb_addr_2M(unm_adapter * adapter,u64 * off,int len)4067956Sxiuyan.wang@Sun.COM unm_nic_pci_get_crb_addr_2M(unm_adapter *adapter, u64 *off, int len)
4077956Sxiuyan.wang@Sun.COM {
4087956Sxiuyan.wang@Sun.COM 	unsigned long end = *off + len;
4097956Sxiuyan.wang@Sun.COM 	crb_128M_2M_sub_block_map_t *m;
4107956Sxiuyan.wang@Sun.COM 
4117956Sxiuyan.wang@Sun.COM 
4127956Sxiuyan.wang@Sun.COM 	if (*off >= UNM_CRB_MAX)
4137956Sxiuyan.wang@Sun.COM 		return (-1);
4147956Sxiuyan.wang@Sun.COM 
4157956Sxiuyan.wang@Sun.COM 	if (*off >= UNM_PCI_CAMQM && (end <= UNM_PCI_CAMQM_2M_END)) {
4167956Sxiuyan.wang@Sun.COM 		*off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
4177956Sxiuyan.wang@Sun.COM 		    adapter->ahw.pci_base0;
4187956Sxiuyan.wang@Sun.COM 		return (0);
4197956Sxiuyan.wang@Sun.COM 	}
4207956Sxiuyan.wang@Sun.COM 
4217956Sxiuyan.wang@Sun.COM 	if (*off < UNM_PCI_CRBSPACE)
4227956Sxiuyan.wang@Sun.COM 		return (-1);
4237956Sxiuyan.wang@Sun.COM 
4247956Sxiuyan.wang@Sun.COM 	*off -= UNM_PCI_CRBSPACE;
4257956Sxiuyan.wang@Sun.COM 	end = *off + len;
4267956Sxiuyan.wang@Sun.COM 	/*
4277956Sxiuyan.wang@Sun.COM 	 * Try direct map
4287956Sxiuyan.wang@Sun.COM 	 */
4297956Sxiuyan.wang@Sun.COM 
4307956Sxiuyan.wang@Sun.COM 	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
4317956Sxiuyan.wang@Sun.COM 
4327956Sxiuyan.wang@Sun.COM 	if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
4337956Sxiuyan.wang@Sun.COM 		*off = *off + m->start_2M - m->start_128M +
4347956Sxiuyan.wang@Sun.COM 		    adapter->ahw.pci_base0;
4357956Sxiuyan.wang@Sun.COM 		return (0);
4367956Sxiuyan.wang@Sun.COM 	}
4377956Sxiuyan.wang@Sun.COM 
4387956Sxiuyan.wang@Sun.COM 	/*
4397956Sxiuyan.wang@Sun.COM 	 * Not in direct map, use crb window
4407956Sxiuyan.wang@Sun.COM 	 */
4417956Sxiuyan.wang@Sun.COM 	return (1);
4427956Sxiuyan.wang@Sun.COM }
4437956Sxiuyan.wang@Sun.COM /*
4447956Sxiuyan.wang@Sun.COM  * In: 'off' is offset from CRB space in 128M pci map
4457956Sxiuyan.wang@Sun.COM  * Out: 'off' is 2M pci map addr
4467956Sxiuyan.wang@Sun.COM  * side effect: lock crb window
4477956Sxiuyan.wang@Sun.COM  */
4487956Sxiuyan.wang@Sun.COM static void
unm_nic_pci_set_crbwindow_2M(unm_adapter * adapter,u64 * off)4497956Sxiuyan.wang@Sun.COM unm_nic_pci_set_crbwindow_2M(unm_adapter *adapter, u64 *off)
4507956Sxiuyan.wang@Sun.COM {
4517956Sxiuyan.wang@Sun.COM 	u32 win_read;
4527956Sxiuyan.wang@Sun.COM 
4537956Sxiuyan.wang@Sun.COM 	adapter->crb_win = CRB_HI(*off);
4547956Sxiuyan.wang@Sun.COM 	UNM_NIC_PCI_WRITE_32(adapter->crb_win, (void *) (CRB_WINDOW_2M +
4557956Sxiuyan.wang@Sun.COM 	    adapter->ahw.pci_base0));
4567956Sxiuyan.wang@Sun.COM 	/*
4577956Sxiuyan.wang@Sun.COM 	 * Read back value to make sure write has gone through before trying
4587956Sxiuyan.wang@Sun.COM 	 * to use it.
4597956Sxiuyan.wang@Sun.COM 	 */
4607956Sxiuyan.wang@Sun.COM 	win_read = UNM_NIC_PCI_READ_32((void *)
4617956Sxiuyan.wang@Sun.COM 	    (CRB_WINDOW_2M + adapter->ahw.pci_base0));
4627956Sxiuyan.wang@Sun.COM 	if (win_read != adapter->crb_win) {
4637956Sxiuyan.wang@Sun.COM 		cmn_err(CE_WARN, "%s: Written crbwin (0x%x) != Read crbwin "
4647956Sxiuyan.wang@Sun.COM 		    "(0x%x), off=0x%llx\n", __FUNCTION__, adapter->crb_win,
4657956Sxiuyan.wang@Sun.COM 		    win_read, *off);
4667956Sxiuyan.wang@Sun.COM 	}
4677956Sxiuyan.wang@Sun.COM 	*off = (*off & MASK(16)) + CRB_INDIRECT_2M +
4687956Sxiuyan.wang@Sun.COM 	    adapter->ahw.pci_base0;
4697956Sxiuyan.wang@Sun.COM }
4707956Sxiuyan.wang@Sun.COM 
4717956Sxiuyan.wang@Sun.COM int
unm_nic_hw_write_ioctl_128M(unm_adapter * adapter,u64 off,void * data,int len)4727956Sxiuyan.wang@Sun.COM unm_nic_hw_write_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
4737956Sxiuyan.wang@Sun.COM {
4747956Sxiuyan.wang@Sun.COM 	void		*addr;
4757956Sxiuyan.wang@Sun.COM 	u64		offset = off;
4767956Sxiuyan.wang@Sun.COM 
4777956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) { // Window 1
4787956Sxiuyan.wang@Sun.COM 		addr = CRB_NORMALIZE(adapter, off);
4797956Sxiuyan.wang@Sun.COM 		if (!addr) {
4807956Sxiuyan.wang@Sun.COM 			offset = CRB_NORMAL(off);
4817956Sxiuyan.wang@Sun.COM 			if (adapter->ahw.pci_len0 == 0)
4827956Sxiuyan.wang@Sun.COM 				offset -= UNM_PCI_CRBSPACE;
4837956Sxiuyan.wang@Sun.COM 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
4847956Sxiuyan.wang@Sun.COM 			    offset);
4857956Sxiuyan.wang@Sun.COM 		}
4867956Sxiuyan.wang@Sun.COM 		UNM_READ_LOCK(&adapter->adapter_lock);
4877956Sxiuyan.wang@Sun.COM 	} else {// Window 0
4887956Sxiuyan.wang@Sun.COM 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
4897956Sxiuyan.wang@Sun.COM 		if (!addr) {
4907956Sxiuyan.wang@Sun.COM 			offset = off;
4917956Sxiuyan.wang@Sun.COM 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
4927956Sxiuyan.wang@Sun.COM 			    offset);
4937956Sxiuyan.wang@Sun.COM 		}
4947956Sxiuyan.wang@Sun.COM 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
4957956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
4967956Sxiuyan.wang@Sun.COM 	}
4977956Sxiuyan.wang@Sun.COM 
4987956Sxiuyan.wang@Sun.COM 	switch (len) {
4997956Sxiuyan.wang@Sun.COM 		case 1:
5007956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
5017956Sxiuyan.wang@Sun.COM 			break;
5027956Sxiuyan.wang@Sun.COM 		case 2:
5037956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
5047956Sxiuyan.wang@Sun.COM 			break;
5057956Sxiuyan.wang@Sun.COM 		case 4:
5067956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
5077956Sxiuyan.wang@Sun.COM 			break;
5087956Sxiuyan.wang@Sun.COM 		case 8:
5097956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
5107956Sxiuyan.wang@Sun.COM 			break;
5117956Sxiuyan.wang@Sun.COM 		default:
5127956Sxiuyan.wang@Sun.COM #if !defined(NDEBUG)
5137956Sxiuyan.wang@Sun.COM 		if ((len & 0x7) != 0)
5147956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
5157956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name, __FUNCTION__, len);
5167956Sxiuyan.wang@Sun.COM #endif
5177956Sxiuyan.wang@Sun.COM 		UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
5187956Sxiuyan.wang@Sun.COM 		break;
5197956Sxiuyan.wang@Sun.COM 	}
5207956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) {// Window 1
5217956Sxiuyan.wang@Sun.COM 		UNM_READ_UNLOCK(&adapter->adapter_lock);
5227956Sxiuyan.wang@Sun.COM 	} else {// Window 0
5237956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
5247956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
5257956Sxiuyan.wang@Sun.COM 	}
5267956Sxiuyan.wang@Sun.COM 
5277956Sxiuyan.wang@Sun.COM 	return (0);
5287956Sxiuyan.wang@Sun.COM }
5297956Sxiuyan.wang@Sun.COM 
5307956Sxiuyan.wang@Sun.COM /*
5317956Sxiuyan.wang@Sun.COM  * Note : 'len' argument should be either 1, 2, 4, or a multiple of 8.
5327956Sxiuyan.wang@Sun.COM  */
5337956Sxiuyan.wang@Sun.COM int
unm_nic_hw_write_wx_128M(unm_adapter * adapter,u64 off,void * data,int len)5347956Sxiuyan.wang@Sun.COM unm_nic_hw_write_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
5357956Sxiuyan.wang@Sun.COM {
5367956Sxiuyan.wang@Sun.COM 	/*
5377956Sxiuyan.wang@Sun.COM 	 * This is modified from _unm_nic_hw_write().
5387956Sxiuyan.wang@Sun.COM 	 * unm_nic_hw_write does not exist now.
5397956Sxiuyan.wang@Sun.COM 	 */
5407956Sxiuyan.wang@Sun.COM 
5417956Sxiuyan.wang@Sun.COM 	void *addr;
5427956Sxiuyan.wang@Sun.COM 
5437956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) {// Window 1
5447956Sxiuyan.wang@Sun.COM 		addr = CRB_NORMALIZE(adapter, off);
5457956Sxiuyan.wang@Sun.COM 		UNM_READ_LOCK(&adapter->adapter_lock);
5467956Sxiuyan.wang@Sun.COM 	} else {// Window 0
5477956Sxiuyan.wang@Sun.COM 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
5487956Sxiuyan.wang@Sun.COM 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
5497956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
5507956Sxiuyan.wang@Sun.COM 	}
5517956Sxiuyan.wang@Sun.COM 
5527956Sxiuyan.wang@Sun.COM 
5537956Sxiuyan.wang@Sun.COM 	if (!addr) {
5547956Sxiuyan.wang@Sun.COM 		if (ADDR_IN_WINDOW1(off)) {// Window 1
5557956Sxiuyan.wang@Sun.COM 			UNM_READ_UNLOCK(&adapter->adapter_lock);
5567956Sxiuyan.wang@Sun.COM 		} else {// Window 0
5577956Sxiuyan.wang@Sun.COM 			unm_nic_pci_change_crbwindow_128M(adapter, 1);
5587956Sxiuyan.wang@Sun.COM 			UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
5597956Sxiuyan.wang@Sun.COM 		}
5607956Sxiuyan.wang@Sun.COM 		return (1);
5617956Sxiuyan.wang@Sun.COM 	}
5627956Sxiuyan.wang@Sun.COM 
5637956Sxiuyan.wang@Sun.COM 	switch (len) {
5647956Sxiuyan.wang@Sun.COM 		case 1:
5657956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
5667956Sxiuyan.wang@Sun.COM 			break;
5677956Sxiuyan.wang@Sun.COM 		case 2:
5687956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
5697956Sxiuyan.wang@Sun.COM 			break;
5707956Sxiuyan.wang@Sun.COM 		case 4:
5717956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
5727956Sxiuyan.wang@Sun.COM 			break;
5737956Sxiuyan.wang@Sun.COM 		case 8:
5747956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
5757956Sxiuyan.wang@Sun.COM 			break;
5767956Sxiuyan.wang@Sun.COM 		default:
5777956Sxiuyan.wang@Sun.COM #if !defined(NDEBUG)
5787956Sxiuyan.wang@Sun.COM 			if ((len & 0x7) != 0)
5797956Sxiuyan.wang@Sun.COM 				cmn_err(CE_WARN,
5807956Sxiuyan.wang@Sun.COM 				    "%s: %s  len(%d) not multiple of 8.\n",
5817956Sxiuyan.wang@Sun.COM 				    unm_nic_driver_name, __FUNCTION__, len);
5827956Sxiuyan.wang@Sun.COM #endif
5837956Sxiuyan.wang@Sun.COM 			UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
5847956Sxiuyan.wang@Sun.COM 			break;
5857956Sxiuyan.wang@Sun.COM 	}
5867956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) {// Window 1
5877956Sxiuyan.wang@Sun.COM 		UNM_READ_UNLOCK(&adapter->adapter_lock);
5887956Sxiuyan.wang@Sun.COM 	} else {// Window 0
5897956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
5907956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
5917956Sxiuyan.wang@Sun.COM 	}
5927956Sxiuyan.wang@Sun.COM 
5937956Sxiuyan.wang@Sun.COM 	return (0);
5947956Sxiuyan.wang@Sun.COM }
5957956Sxiuyan.wang@Sun.COM 
5967956Sxiuyan.wang@Sun.COM /*
5977956Sxiuyan.wang@Sun.COM  * Note : only 32-bit writes!
5987956Sxiuyan.wang@Sun.COM  */
5997956Sxiuyan.wang@Sun.COM void
unm_nic_pci_write_normalize_128M(unm_adapter * adapter,u64 off,u32 data)6007956Sxiuyan.wang@Sun.COM unm_nic_pci_write_normalize_128M(unm_adapter *adapter, u64 off, u32 data)
6017956Sxiuyan.wang@Sun.COM {
6027956Sxiuyan.wang@Sun.COM 	UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
6037956Sxiuyan.wang@Sun.COM }
6047956Sxiuyan.wang@Sun.COM 
6057956Sxiuyan.wang@Sun.COM /*
6067956Sxiuyan.wang@Sun.COM  * Note : only 32-bit reads!
6077956Sxiuyan.wang@Sun.COM  */
6087956Sxiuyan.wang@Sun.COM u32
unm_nic_pci_read_normalize_128M(unm_adapter * adapter,u64 off)6097956Sxiuyan.wang@Sun.COM unm_nic_pci_read_normalize_128M(unm_adapter *adapter, u64 off)
6107956Sxiuyan.wang@Sun.COM {
6117956Sxiuyan.wang@Sun.COM 	return (UNM_NIC_PCI_READ_32(CRB_NORMALIZE(adapter, off)));
6127956Sxiuyan.wang@Sun.COM }
6137956Sxiuyan.wang@Sun.COM 
6147956Sxiuyan.wang@Sun.COM /*
6157956Sxiuyan.wang@Sun.COM  * Note : only 32-bit writes!
6167956Sxiuyan.wang@Sun.COM  */
6177956Sxiuyan.wang@Sun.COM int
unm_nic_pci_write_immediate_128M(unm_adapter * adapter,u64 off,u32 * data)6187956Sxiuyan.wang@Sun.COM unm_nic_pci_write_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
6197956Sxiuyan.wang@Sun.COM {
6207956Sxiuyan.wang@Sun.COM 	UNM_NIC_PCI_WRITE_32(*data,
6217956Sxiuyan.wang@Sun.COM 	    (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
6227956Sxiuyan.wang@Sun.COM 	return (0);
6237956Sxiuyan.wang@Sun.COM }
6247956Sxiuyan.wang@Sun.COM 
6257956Sxiuyan.wang@Sun.COM /*
6267956Sxiuyan.wang@Sun.COM  * Note : only 32-bit reads!
6277956Sxiuyan.wang@Sun.COM  */
6287956Sxiuyan.wang@Sun.COM int
unm_nic_pci_read_immediate_128M(unm_adapter * adapter,u64 off,u32 * data)6297956Sxiuyan.wang@Sun.COM unm_nic_pci_read_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
6307956Sxiuyan.wang@Sun.COM {
6317956Sxiuyan.wang@Sun.COM 	*data = UNM_NIC_PCI_READ_32((void *)
6327956Sxiuyan.wang@Sun.COM 	    (uptr_t)(pci_base_offset(adapter, off)));
6337956Sxiuyan.wang@Sun.COM 	return (0);
6347956Sxiuyan.wang@Sun.COM }
6357956Sxiuyan.wang@Sun.COM 
6367956Sxiuyan.wang@Sun.COM /*
6377956Sxiuyan.wang@Sun.COM  * Note : only 32-bit writes!
6387956Sxiuyan.wang@Sun.COM  */
6397956Sxiuyan.wang@Sun.COM void
unm_nic_pci_write_normalize_2M(unm_adapter * adapter,u64 off,u32 data)6407956Sxiuyan.wang@Sun.COM unm_nic_pci_write_normalize_2M(unm_adapter *adapter, u64 off, u32 data)
6417956Sxiuyan.wang@Sun.COM {
6427956Sxiuyan.wang@Sun.COM 	u32 temp = data;
6437956Sxiuyan.wang@Sun.COM 
6447956Sxiuyan.wang@Sun.COM 	adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
6457956Sxiuyan.wang@Sun.COM }
6467956Sxiuyan.wang@Sun.COM 
6477956Sxiuyan.wang@Sun.COM /*
6487956Sxiuyan.wang@Sun.COM  * Note : only 32-bit reads!
6497956Sxiuyan.wang@Sun.COM  */
6507956Sxiuyan.wang@Sun.COM u32
unm_nic_pci_read_normalize_2M(unm_adapter * adapter,u64 off)6517956Sxiuyan.wang@Sun.COM unm_nic_pci_read_normalize_2M(unm_adapter *adapter, u64 off)
6527956Sxiuyan.wang@Sun.COM {
6537956Sxiuyan.wang@Sun.COM 	u32 temp;
6547956Sxiuyan.wang@Sun.COM 
6557956Sxiuyan.wang@Sun.COM 	adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
6567956Sxiuyan.wang@Sun.COM 
6577956Sxiuyan.wang@Sun.COM 	return (temp);
6587956Sxiuyan.wang@Sun.COM }
6597956Sxiuyan.wang@Sun.COM 
6607956Sxiuyan.wang@Sun.COM /*
6617956Sxiuyan.wang@Sun.COM  * Note : only 32-bit writes!
6627956Sxiuyan.wang@Sun.COM  */
6637956Sxiuyan.wang@Sun.COM int
unm_nic_pci_write_immediate_2M(unm_adapter * adapter,u64 off,u32 * data)6647956Sxiuyan.wang@Sun.COM unm_nic_pci_write_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
6657956Sxiuyan.wang@Sun.COM {
6667956Sxiuyan.wang@Sun.COM 	u32 temp = *data;
6677956Sxiuyan.wang@Sun.COM 
6687956Sxiuyan.wang@Sun.COM 	adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
6697956Sxiuyan.wang@Sun.COM 
6707956Sxiuyan.wang@Sun.COM 	return (0);
6717956Sxiuyan.wang@Sun.COM }
6727956Sxiuyan.wang@Sun.COM 
6737956Sxiuyan.wang@Sun.COM /*
6747956Sxiuyan.wang@Sun.COM  * Note : only 32-bit reads!
6757956Sxiuyan.wang@Sun.COM  */
6767956Sxiuyan.wang@Sun.COM int
unm_nic_pci_read_immediate_2M(unm_adapter * adapter,u64 off,u32 * data)6777956Sxiuyan.wang@Sun.COM unm_nic_pci_read_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
6787956Sxiuyan.wang@Sun.COM {
6797956Sxiuyan.wang@Sun.COM 	u32 temp;
6807956Sxiuyan.wang@Sun.COM 
6817956Sxiuyan.wang@Sun.COM 	adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
6827956Sxiuyan.wang@Sun.COM 
6837956Sxiuyan.wang@Sun.COM 	*data = temp;
6847956Sxiuyan.wang@Sun.COM 
6857956Sxiuyan.wang@Sun.COM 	return (0);
6867956Sxiuyan.wang@Sun.COM }
6877956Sxiuyan.wang@Sun.COM 
6887956Sxiuyan.wang@Sun.COM /*
6897956Sxiuyan.wang@Sun.COM  * write cross hw window boundary is not supported
6907956Sxiuyan.wang@Sun.COM  * 'len' should be either 1, 2, 4, or multiple of 8
6917956Sxiuyan.wang@Sun.COM  */
6927956Sxiuyan.wang@Sun.COM int
unm_nic_hw_write_wx_2M(unm_adapter * adapter,u64 off,void * data,int len)6937956Sxiuyan.wang@Sun.COM unm_nic_hw_write_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
6947956Sxiuyan.wang@Sun.COM {
6957956Sxiuyan.wang@Sun.COM 	int rv;
6967956Sxiuyan.wang@Sun.COM 
6977956Sxiuyan.wang@Sun.COM 	rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
6987956Sxiuyan.wang@Sun.COM 
6997956Sxiuyan.wang@Sun.COM 	if (rv == -1) {
7007956Sxiuyan.wang@Sun.COM 		cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
7017956Sxiuyan.wang@Sun.COM 		    __FUNCTION__, off);
7027956Sxiuyan.wang@Sun.COM 		return (-1);
7037956Sxiuyan.wang@Sun.COM 	}
7047956Sxiuyan.wang@Sun.COM 
7057956Sxiuyan.wang@Sun.COM 	if (rv == 1) {
7067956Sxiuyan.wang@Sun.COM 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
7077956Sxiuyan.wang@Sun.COM 		crb_win_lock(adapter);
7087956Sxiuyan.wang@Sun.COM 		unm_nic_pci_set_crbwindow_2M(adapter, &off);
7097956Sxiuyan.wang@Sun.COM 	}
7107956Sxiuyan.wang@Sun.COM 
7117956Sxiuyan.wang@Sun.COM 	switch (len) {
7127956Sxiuyan.wang@Sun.COM 	case 1:
7137956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_8(*(__uint8_t *)data, (void *) (uptr_t)off);
7147956Sxiuyan.wang@Sun.COM 		break;
7157956Sxiuyan.wang@Sun.COM 	case 2:
7167956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, (void *) (uptr_t)off);
7177956Sxiuyan.wang@Sun.COM 		break;
7187956Sxiuyan.wang@Sun.COM 	case 4:
7197956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, (void *) (uptr_t)off);
7207956Sxiuyan.wang@Sun.COM 		break;
7217956Sxiuyan.wang@Sun.COM 	case 8:
7227956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, (void *) (uptr_t)off);
7237956Sxiuyan.wang@Sun.COM 		break;
7247956Sxiuyan.wang@Sun.COM 	default:
7257956Sxiuyan.wang@Sun.COM #if !defined(NDEBUG)
7267956Sxiuyan.wang@Sun.COM 		if ((len & 0x7) != 0)
7277956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: %s  len(%d) not multiple of 8.\n",
7287956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name, __FUNCTION__, len);
7297956Sxiuyan.wang@Sun.COM #endif
7307956Sxiuyan.wang@Sun.COM 		UNM_NIC_HW_BLOCK_WRITE_64(data, (uptr_t)off, (len>>3));
7317956Sxiuyan.wang@Sun.COM 		break;
7327956Sxiuyan.wang@Sun.COM 	}
7337956Sxiuyan.wang@Sun.COM 	if (rv == 1) {
7347956Sxiuyan.wang@Sun.COM 		crb_win_unlock(adapter);
7357956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
7367956Sxiuyan.wang@Sun.COM 	}
7377956Sxiuyan.wang@Sun.COM 
7387956Sxiuyan.wang@Sun.COM 	return (0);
7397956Sxiuyan.wang@Sun.COM }
7407956Sxiuyan.wang@Sun.COM 
7417956Sxiuyan.wang@Sun.COM int
unm_nic_hw_read_ioctl_128M(unm_adapter * adapter,u64 off,void * data,int len)7427956Sxiuyan.wang@Sun.COM unm_nic_hw_read_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
7437956Sxiuyan.wang@Sun.COM {
7447956Sxiuyan.wang@Sun.COM 	void		*addr;
7457956Sxiuyan.wang@Sun.COM 	u64		offset;
7467956Sxiuyan.wang@Sun.COM 
7477956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) {// Window 1
7487956Sxiuyan.wang@Sun.COM 		addr = CRB_NORMALIZE(adapter, off);
7497956Sxiuyan.wang@Sun.COM 		if (!addr) {
7507956Sxiuyan.wang@Sun.COM 			offset = CRB_NORMAL(off);
7517956Sxiuyan.wang@Sun.COM 			if (adapter->ahw.pci_len0 == 0)
7527956Sxiuyan.wang@Sun.COM 				offset -= UNM_PCI_CRBSPACE;
7537956Sxiuyan.wang@Sun.COM 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
7547956Sxiuyan.wang@Sun.COM 			    offset);
7557956Sxiuyan.wang@Sun.COM 		}
7567956Sxiuyan.wang@Sun.COM 		UNM_READ_LOCK(&adapter->adapter_lock);
7577956Sxiuyan.wang@Sun.COM 	} else {// Window 0
7587956Sxiuyan.wang@Sun.COM 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
7597956Sxiuyan.wang@Sun.COM 		if (!addr) {
7607956Sxiuyan.wang@Sun.COM 			offset = off;
7617956Sxiuyan.wang@Sun.COM 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
7627956Sxiuyan.wang@Sun.COM 			    offset);
7637956Sxiuyan.wang@Sun.COM 		}
7647956Sxiuyan.wang@Sun.COM 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
7657956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
7667956Sxiuyan.wang@Sun.COM 	}
7677956Sxiuyan.wang@Sun.COM 
7687956Sxiuyan.wang@Sun.COM 	switch (len) {
7697956Sxiuyan.wang@Sun.COM 	case 1:
7707956Sxiuyan.wang@Sun.COM 		*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
7717956Sxiuyan.wang@Sun.COM 		break;
7727956Sxiuyan.wang@Sun.COM 	case 2:
7737956Sxiuyan.wang@Sun.COM 		*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
7747956Sxiuyan.wang@Sun.COM 		break;
7757956Sxiuyan.wang@Sun.COM 	case 4:
7767956Sxiuyan.wang@Sun.COM 		*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
7777956Sxiuyan.wang@Sun.COM 		break;
7787956Sxiuyan.wang@Sun.COM 	case 8:
7797956Sxiuyan.wang@Sun.COM 		*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
7807956Sxiuyan.wang@Sun.COM 		break;
7817956Sxiuyan.wang@Sun.COM 	default:
7827956Sxiuyan.wang@Sun.COM #if !defined(NDEBUG)
7837956Sxiuyan.wang@Sun.COM 		if ((len & 0x7) != 0)
7847956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
7857956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name, __FUNCTION__, len);
7867956Sxiuyan.wang@Sun.COM #endif
7877956Sxiuyan.wang@Sun.COM 		UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
7887956Sxiuyan.wang@Sun.COM 		break;
7897956Sxiuyan.wang@Sun.COM 	}
7907956Sxiuyan.wang@Sun.COM 
7917956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) {// Window 1
7927956Sxiuyan.wang@Sun.COM 		UNM_READ_UNLOCK(&adapter->adapter_lock);
7937956Sxiuyan.wang@Sun.COM 	} else {// Window 0
7947956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
7957956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
7967956Sxiuyan.wang@Sun.COM 	}
7977956Sxiuyan.wang@Sun.COM 
7987956Sxiuyan.wang@Sun.COM 	return (0);
7997956Sxiuyan.wang@Sun.COM }
8007956Sxiuyan.wang@Sun.COM 
8017956Sxiuyan.wang@Sun.COM int
unm_nic_hw_read_wx_2M(unm_adapter * adapter,u64 off,void * data,int len)8027956Sxiuyan.wang@Sun.COM unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
8037956Sxiuyan.wang@Sun.COM {
8047956Sxiuyan.wang@Sun.COM 	int rv;
8057956Sxiuyan.wang@Sun.COM 
8067956Sxiuyan.wang@Sun.COM 	rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
8077956Sxiuyan.wang@Sun.COM 
8087956Sxiuyan.wang@Sun.COM 	if (rv == -1) {
8097956Sxiuyan.wang@Sun.COM 		cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
8107956Sxiuyan.wang@Sun.COM 		    __FUNCTION__, off);
8117956Sxiuyan.wang@Sun.COM 		return (-1);
8127956Sxiuyan.wang@Sun.COM 	}
8137956Sxiuyan.wang@Sun.COM 
8147956Sxiuyan.wang@Sun.COM 	if (rv == 1) {
8157956Sxiuyan.wang@Sun.COM 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
8167956Sxiuyan.wang@Sun.COM 		crb_win_lock(adapter);
8177956Sxiuyan.wang@Sun.COM 		unm_nic_pci_set_crbwindow_2M(adapter, &off);
8187956Sxiuyan.wang@Sun.COM 	}
8197956Sxiuyan.wang@Sun.COM 
8207956Sxiuyan.wang@Sun.COM 	switch (len) {
8217956Sxiuyan.wang@Sun.COM 	case 1:
8227956Sxiuyan.wang@Sun.COM 		*(__uint8_t  *)data = UNM_NIC_PCI_READ_8((void *) (uptr_t)off);
8237956Sxiuyan.wang@Sun.COM 		break;
8247956Sxiuyan.wang@Sun.COM 	case 2:
8257956Sxiuyan.wang@Sun.COM 		*(__uint16_t *)data = UNM_NIC_PCI_READ_16((void *) (uptr_t)off);
8267956Sxiuyan.wang@Sun.COM 		break;
8277956Sxiuyan.wang@Sun.COM 	case 4:
8287956Sxiuyan.wang@Sun.COM 		*(__uint32_t *)data = UNM_NIC_PCI_READ_32((void *) (uptr_t)off);
8297956Sxiuyan.wang@Sun.COM 		break;
8307956Sxiuyan.wang@Sun.COM 	case 8:
8317956Sxiuyan.wang@Sun.COM 		*(__uint64_t *)data = UNM_NIC_PCI_READ_64((void *) (uptr_t)off);
8327956Sxiuyan.wang@Sun.COM 		break;
8337956Sxiuyan.wang@Sun.COM 	default:
8347956Sxiuyan.wang@Sun.COM #if !defined(NDEBUG)
8357956Sxiuyan.wang@Sun.COM 		if ((len & 0x7) != 0)
8367956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
8377956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name, __FUNCTION__, len);
8387956Sxiuyan.wang@Sun.COM #endif
8397956Sxiuyan.wang@Sun.COM 		UNM_NIC_HW_BLOCK_READ_64(data, (void *) (uptr_t)off, (len>>3));
8407956Sxiuyan.wang@Sun.COM 		break;
8417956Sxiuyan.wang@Sun.COM 	}
8427956Sxiuyan.wang@Sun.COM 
8437956Sxiuyan.wang@Sun.COM 	if (rv == 1) {
8447956Sxiuyan.wang@Sun.COM 		crb_win_unlock(adapter);
8457956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
8467956Sxiuyan.wang@Sun.COM 	}
8477956Sxiuyan.wang@Sun.COM 
8487956Sxiuyan.wang@Sun.COM 	return (0);
8497956Sxiuyan.wang@Sun.COM }
8507956Sxiuyan.wang@Sun.COM 
8517956Sxiuyan.wang@Sun.COM int
unm_nic_hw_read_wx_128M(unm_adapter * adapter,u64 off,void * data,int len)8527956Sxiuyan.wang@Sun.COM unm_nic_hw_read_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
8537956Sxiuyan.wang@Sun.COM {
8547956Sxiuyan.wang@Sun.COM 	void *addr;
8557956Sxiuyan.wang@Sun.COM 
8567956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) {
8577956Sxiuyan.wang@Sun.COM 		// Window 1
8587956Sxiuyan.wang@Sun.COM 		addr = CRB_NORMALIZE(adapter, off);
8597956Sxiuyan.wang@Sun.COM 		UNM_READ_LOCK(&adapter->adapter_lock);
8607956Sxiuyan.wang@Sun.COM 	} else {// Window 0
8617956Sxiuyan.wang@Sun.COM 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
8627956Sxiuyan.wang@Sun.COM 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
8637956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
8647956Sxiuyan.wang@Sun.COM 	}
8657956Sxiuyan.wang@Sun.COM 
8667956Sxiuyan.wang@Sun.COM 	if (!addr) {
8677956Sxiuyan.wang@Sun.COM 		if (ADDR_IN_WINDOW1(off)) {// Window 1
8687956Sxiuyan.wang@Sun.COM 			UNM_READ_UNLOCK(&adapter->adapter_lock);
8697956Sxiuyan.wang@Sun.COM 		} else {// Window 0
8707956Sxiuyan.wang@Sun.COM 			unm_nic_pci_change_crbwindow_128M(adapter, 1);
8717956Sxiuyan.wang@Sun.COM 			UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
8727956Sxiuyan.wang@Sun.COM 		}
8737956Sxiuyan.wang@Sun.COM 		return (1);
8747956Sxiuyan.wang@Sun.COM 	}
8757956Sxiuyan.wang@Sun.COM 
8767956Sxiuyan.wang@Sun.COM 	switch (len) {
8777956Sxiuyan.wang@Sun.COM 		case 1:
8787956Sxiuyan.wang@Sun.COM 			*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
8797956Sxiuyan.wang@Sun.COM 			break;
8807956Sxiuyan.wang@Sun.COM 		case 2:
8817956Sxiuyan.wang@Sun.COM 			*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
8827956Sxiuyan.wang@Sun.COM 			break;
8837956Sxiuyan.wang@Sun.COM 		case 4:
8847956Sxiuyan.wang@Sun.COM 			*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
8857956Sxiuyan.wang@Sun.COM 			break;
8867956Sxiuyan.wang@Sun.COM 		case 8:
8877956Sxiuyan.wang@Sun.COM 			*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
8887956Sxiuyan.wang@Sun.COM 			break;
8897956Sxiuyan.wang@Sun.COM 		default:
8907956Sxiuyan.wang@Sun.COM #if !defined(NDEBUG)
8917956Sxiuyan.wang@Sun.COM 			if ((len & 0x7) != 0)
8927956Sxiuyan.wang@Sun.COM 				cmn_err(CE_WARN,
8937956Sxiuyan.wang@Sun.COM 				    "%s: %s len(%d) not multiple of 8.\n",
8947956Sxiuyan.wang@Sun.COM 				    unm_nic_driver_name, __FUNCTION__, len);
8957956Sxiuyan.wang@Sun.COM #endif
8967956Sxiuyan.wang@Sun.COM 			UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
8977956Sxiuyan.wang@Sun.COM 			break;
8987956Sxiuyan.wang@Sun.COM 	}
8997956Sxiuyan.wang@Sun.COM 
9007956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) {// Window 1
9017956Sxiuyan.wang@Sun.COM 		UNM_READ_UNLOCK(&adapter->adapter_lock);
9027956Sxiuyan.wang@Sun.COM 	} else {// Window 0
9037956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
9047956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
9057956Sxiuyan.wang@Sun.COM 	}
9067956Sxiuyan.wang@Sun.COM 
9077956Sxiuyan.wang@Sun.COM 	return (0);
9087956Sxiuyan.wang@Sun.COM }
9097956Sxiuyan.wang@Sun.COM 
9107956Sxiuyan.wang@Sun.COM /*  PCI Windowing for DDR regions.  */
9117956Sxiuyan.wang@Sun.COM #define	ADDR_IN_RANGE(addr, low, high)	    \
9127956Sxiuyan.wang@Sun.COM 	(((addr) <= (high)) && ((low) ? ((addr) >= (low)) : 1))
9137956Sxiuyan.wang@Sun.COM 
9147956Sxiuyan.wang@Sun.COM /*
9157956Sxiuyan.wang@Sun.COM  * check memory access boundary.
9167956Sxiuyan.wang@Sun.COM  * used by test agent. support ddr access only for now
9177956Sxiuyan.wang@Sun.COM  */
9187956Sxiuyan.wang@Sun.COM /* ARGSUSED */
9197956Sxiuyan.wang@Sun.COM static unsigned long
unm_nic_pci_mem_bound_check(struct unm_adapter_s * adapter,unsigned long long addr,int size)9207956Sxiuyan.wang@Sun.COM unm_nic_pci_mem_bound_check(struct unm_adapter_s *adapter,
9217956Sxiuyan.wang@Sun.COM     unsigned long long addr, int size)
9227956Sxiuyan.wang@Sun.COM {
9237956Sxiuyan.wang@Sun.COM 	if (!ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX) ||
9247956Sxiuyan.wang@Sun.COM 	    !ADDR_IN_RANGE(addr + size -1, UNM_ADDR_DDR_NET,
9257956Sxiuyan.wang@Sun.COM 	    UNM_ADDR_DDR_NET_MAX) || ((size != 1) && (size != 2) &&
9267956Sxiuyan.wang@Sun.COM 	    (size != 4) && (size != 8)))
9277956Sxiuyan.wang@Sun.COM 		return (0);
9287956Sxiuyan.wang@Sun.COM 
9297956Sxiuyan.wang@Sun.COM 	return (1);
9307956Sxiuyan.wang@Sun.COM }
9317956Sxiuyan.wang@Sun.COM 
9327956Sxiuyan.wang@Sun.COM int unm_pci_set_window_warning_count = 0;
9337956Sxiuyan.wang@Sun.COM 
9347956Sxiuyan.wang@Sun.COM unsigned long long
unm_nic_pci_set_window_128M(struct unm_adapter_s * adapter,unsigned long long addr)9357956Sxiuyan.wang@Sun.COM unm_nic_pci_set_window_128M(struct unm_adapter_s *adapter,
9367956Sxiuyan.wang@Sun.COM     unsigned long long addr)
9377956Sxiuyan.wang@Sun.COM {
9387956Sxiuyan.wang@Sun.COM 	int		window;
9397956Sxiuyan.wang@Sun.COM 	unsigned long long	qdr_max;
9407956Sxiuyan.wang@Sun.COM 
9417956Sxiuyan.wang@Sun.COM 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
9427956Sxiuyan.wang@Sun.COM 		qdr_max = NX_P2_ADDR_QDR_NET_MAX;
9437956Sxiuyan.wang@Sun.COM 	} else {
9447956Sxiuyan.wang@Sun.COM 		qdr_max = NX_P3_ADDR_QDR_NET_MAX;
9457956Sxiuyan.wang@Sun.COM 	}
9467956Sxiuyan.wang@Sun.COM 
9477956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
9487956Sxiuyan.wang@Sun.COM 		/* DDR network side */
9497956Sxiuyan.wang@Sun.COM 		/* MN access should never come here */
9507956Sxiuyan.wang@Sun.COM 		cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
9517956Sxiuyan.wang@Sun.COM 		addr = -1ULL;
9527956Sxiuyan.wang@Sun.COM 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
9537956Sxiuyan.wang@Sun.COM 		addr -= UNM_ADDR_OCM0;
9547956Sxiuyan.wang@Sun.COM 		addr += UNM_PCI_OCM0;
9557956Sxiuyan.wang@Sun.COM 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
9567956Sxiuyan.wang@Sun.COM 		addr -= UNM_ADDR_OCM1;
9577956Sxiuyan.wang@Sun.COM 		addr += UNM_PCI_OCM1;
9587956Sxiuyan.wang@Sun.COM 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
9597956Sxiuyan.wang@Sun.COM 		/* QDR network side */
9607956Sxiuyan.wang@Sun.COM 		addr -= UNM_ADDR_QDR_NET;
9617956Sxiuyan.wang@Sun.COM 		window = (addr >> 22) & 0x3f;
9627956Sxiuyan.wang@Sun.COM 		if (adapter->ahw.qdr_sn_window != window) {
9637956Sxiuyan.wang@Sun.COM 			adapter->ahw.qdr_sn_window = window;
9647956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_32((window << 22),
9657956Sxiuyan.wang@Sun.COM 			    (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
9667956Sxiuyan.wang@Sun.COM 			    UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
9677956Sxiuyan.wang@Sun.COM 			    adapter->ahw.pci_func)))));
9687956Sxiuyan.wang@Sun.COM 			/* MUST make sure window is set before we forge on... */
9697956Sxiuyan.wang@Sun.COM 			(void) UNM_NIC_PCI_READ_32((void *)
9707956Sxiuyan.wang@Sun.COM 			    (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
9717956Sxiuyan.wang@Sun.COM 			    UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
9727956Sxiuyan.wang@Sun.COM 			    adapter->ahw.pci_func)))));
9737956Sxiuyan.wang@Sun.COM 		}
9747956Sxiuyan.wang@Sun.COM 		addr -= (window * 0x400000);
9757956Sxiuyan.wang@Sun.COM 		addr += UNM_PCI_QDR_NET;
9767956Sxiuyan.wang@Sun.COM 	} else {
9777956Sxiuyan.wang@Sun.COM 		/*
9787956Sxiuyan.wang@Sun.COM 		 * peg gdb frequently accesses memory that doesn't exist,
9797956Sxiuyan.wang@Sun.COM 		 * this limits the chit chat so debugging isn't slowed down.
9807956Sxiuyan.wang@Sun.COM 		 */
9817956Sxiuyan.wang@Sun.COM 		if ((unm_pci_set_window_warning_count++ < 8) ||
9827956Sxiuyan.wang@Sun.COM 		    (unm_pci_set_window_warning_count%64 == 0)) {
9837956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: Warning:unm_nic_pci_set_window() "
9847956Sxiuyan.wang@Sun.COM 			    "Unknown address range!\n", unm_nic_driver_name);
9857956Sxiuyan.wang@Sun.COM 		}
9867956Sxiuyan.wang@Sun.COM 		addr = -1ULL;
9877956Sxiuyan.wang@Sun.COM 	}
9887956Sxiuyan.wang@Sun.COM 	return (addr);
9897956Sxiuyan.wang@Sun.COM }
9907956Sxiuyan.wang@Sun.COM 
9917956Sxiuyan.wang@Sun.COM unsigned long long
unm_nic_pci_set_window_2M(struct unm_adapter_s * adapter,unsigned long long addr)9927956Sxiuyan.wang@Sun.COM unm_nic_pci_set_window_2M(struct unm_adapter_s *adapter,
9937956Sxiuyan.wang@Sun.COM     unsigned long long addr)
9947956Sxiuyan.wang@Sun.COM {
9957956Sxiuyan.wang@Sun.COM 	int window;
9967956Sxiuyan.wang@Sun.COM 	u32 win_read;
9977956Sxiuyan.wang@Sun.COM 
9987956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
9997956Sxiuyan.wang@Sun.COM 		/* DDR network side */
10007956Sxiuyan.wang@Sun.COM 		window = MN_WIN(addr);
10017956Sxiuyan.wang@Sun.COM 		adapter->ahw.ddr_mn_window = window;
10027956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
10037956Sxiuyan.wang@Sun.COM 		    UNM_PCI_CRBSPACE, &window, 4);
10047956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
10057956Sxiuyan.wang@Sun.COM 		    UNM_PCI_CRBSPACE, &win_read, 4);
10067956Sxiuyan.wang@Sun.COM 		if ((win_read << 17) != window) {
10077956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN,
10087956Sxiuyan.wang@Sun.COM 			    "%s: Written MNwin (0x%x) != Read MNwin (0x%x)\n",
10097956Sxiuyan.wang@Sun.COM 			    __FUNCTION__, window, win_read);
10107956Sxiuyan.wang@Sun.COM 		}
10117956Sxiuyan.wang@Sun.COM 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
10127956Sxiuyan.wang@Sun.COM 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
10137956Sxiuyan.wang@Sun.COM 		unsigned int temp1;
10147956Sxiuyan.wang@Sun.COM // OCM: pci_addr[20:18] == 011 && pci_addr[17:11] != 7f
10157956Sxiuyan.wang@Sun.COM 		if ((addr & 0x00ff800) == 0xff800) {
10167956Sxiuyan.wang@Sun.COM 			// if bits 19:18&17:11 are on
10177956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: QM access not handled.\n",
10187956Sxiuyan.wang@Sun.COM 			    __FUNCTION__);
10197956Sxiuyan.wang@Sun.COM 			addr = -1ULL;
10207956Sxiuyan.wang@Sun.COM 		}
10217956Sxiuyan.wang@Sun.COM 
10227956Sxiuyan.wang@Sun.COM 		window = OCM_WIN(addr);
10237956Sxiuyan.wang@Sun.COM 		adapter->ahw.ddr_mn_window = window;
10247956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
10257956Sxiuyan.wang@Sun.COM 		    UNM_PCI_CRBSPACE, &window, 4);
10267956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
10277956Sxiuyan.wang@Sun.COM 		    UNM_PCI_CRBSPACE, &win_read, 4);
10287956Sxiuyan.wang@Sun.COM 		temp1 = ((window & 0x1FF) << 7) |
10297956Sxiuyan.wang@Sun.COM 		    ((window & 0x0FFFE0000) >> 17);
10307956Sxiuyan.wang@Sun.COM 		if (win_read != temp1) {
10317956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN,
10327956Sxiuyan.wang@Sun.COM 			    "%s: Written OCMwin(0x%x) != Read OCMwin(0x%x)\n",
10337956Sxiuyan.wang@Sun.COM 			    __FUNCTION__, temp1, win_read);
10347956Sxiuyan.wang@Sun.COM 		}
10357956Sxiuyan.wang@Sun.COM 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
10367956Sxiuyan.wang@Sun.COM 
10377956Sxiuyan.wang@Sun.COM 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
10387956Sxiuyan.wang@Sun.COM 	    NX_P3_ADDR_QDR_NET_MAX)) {
10397956Sxiuyan.wang@Sun.COM 		/* QDR network side */
10407956Sxiuyan.wang@Sun.COM 		window = MS_WIN(addr);
10417956Sxiuyan.wang@Sun.COM 		adapter->ahw.qdr_sn_window = window;
10427956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.ms_win_crb |
10437956Sxiuyan.wang@Sun.COM 		    UNM_PCI_CRBSPACE, &window, 4);
10447956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.ms_win_crb |
10457956Sxiuyan.wang@Sun.COM 		    UNM_PCI_CRBSPACE, &win_read, 4);
10467956Sxiuyan.wang@Sun.COM 		if (win_read != window) {
10477956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN,
10487956Sxiuyan.wang@Sun.COM 			    "%s: Written MSwin (0x%x) != Read MSwin (0x%x)\n",
10497956Sxiuyan.wang@Sun.COM 			    __FUNCTION__, window, win_read);
10507956Sxiuyan.wang@Sun.COM 		}
10517956Sxiuyan.wang@Sun.COM 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
10527956Sxiuyan.wang@Sun.COM 
10537956Sxiuyan.wang@Sun.COM 	} else {
10547956Sxiuyan.wang@Sun.COM 		/*
10557956Sxiuyan.wang@Sun.COM 		 * peg gdb frequently accesses memory that doesn't exist,
10567956Sxiuyan.wang@Sun.COM 		 * this limits the chit chat so debugging isn't slowed down.
10577956Sxiuyan.wang@Sun.COM 		 */
10587956Sxiuyan.wang@Sun.COM 		if ((unm_pci_set_window_warning_count++ < 8) ||
10597956Sxiuyan.wang@Sun.COM 		    (unm_pci_set_window_warning_count%64 == 0)) {
10607956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s%d: %s Unknown address range!\n",
10617956Sxiuyan.wang@Sun.COM 			    adapter->name, adapter->instance, __FUNCTION__);
10627956Sxiuyan.wang@Sun.COM 		}
10637956Sxiuyan.wang@Sun.COM 		addr = -1ULL;
10647956Sxiuyan.wang@Sun.COM 	}
10657956Sxiuyan.wang@Sun.COM 	return (addr);
10667956Sxiuyan.wang@Sun.COM }
10677956Sxiuyan.wang@Sun.COM 
10687956Sxiuyan.wang@Sun.COM /* check if address is in the same windows as the previous access */
10697956Sxiuyan.wang@Sun.COM static unsigned long
unm_nic_pci_is_same_window(struct unm_adapter_s * adapter,unsigned long long addr)10707956Sxiuyan.wang@Sun.COM unm_nic_pci_is_same_window(struct unm_adapter_s *adapter,
10717956Sxiuyan.wang@Sun.COM     unsigned long long addr)
10727956Sxiuyan.wang@Sun.COM {
10737956Sxiuyan.wang@Sun.COM 	int			window;
10747956Sxiuyan.wang@Sun.COM 	unsigned long long	qdr_max;
10757956Sxiuyan.wang@Sun.COM 
10767956Sxiuyan.wang@Sun.COM 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
10777956Sxiuyan.wang@Sun.COM 		qdr_max = NX_P2_ADDR_QDR_NET_MAX;
10787956Sxiuyan.wang@Sun.COM 	} else {
10797956Sxiuyan.wang@Sun.COM 		qdr_max = NX_P3_ADDR_QDR_NET_MAX;
10807956Sxiuyan.wang@Sun.COM 	}
10817956Sxiuyan.wang@Sun.COM 
10827956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
10837956Sxiuyan.wang@Sun.COM 		/* DDR network side */
10847956Sxiuyan.wang@Sun.COM 		/* MN access can not come here */
10857956Sxiuyan.wang@Sun.COM 		cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
10867956Sxiuyan.wang@Sun.COM #if 0
10877956Sxiuyan.wang@Sun.COM 		window = ((addr - UNM_ADDR_DDR_NET) >> 25) & 0x3ff;
10887956Sxiuyan.wang@Sun.COM 		if (adapter->ahw.ddr_mn_window == window) {
10897956Sxiuyan.wang@Sun.COM 			return (1);
10907956Sxiuyan.wang@Sun.COM 		}
10917956Sxiuyan.wang@Sun.COM #endif
10927956Sxiuyan.wang@Sun.COM 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
10937956Sxiuyan.wang@Sun.COM 		return (1);
10947956Sxiuyan.wang@Sun.COM 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
10957956Sxiuyan.wang@Sun.COM 		return (1);
10967956Sxiuyan.wang@Sun.COM 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
10977956Sxiuyan.wang@Sun.COM 		/* QDR network side */
10987956Sxiuyan.wang@Sun.COM 		window = ((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f;
10997956Sxiuyan.wang@Sun.COM 		if (adapter->ahw.qdr_sn_window == window) {
11007956Sxiuyan.wang@Sun.COM 			return (1);
11017956Sxiuyan.wang@Sun.COM 		}
11027956Sxiuyan.wang@Sun.COM 	}
11037956Sxiuyan.wang@Sun.COM 
11047956Sxiuyan.wang@Sun.COM 	return (0);
11057956Sxiuyan.wang@Sun.COM }
11067956Sxiuyan.wang@Sun.COM 
11077956Sxiuyan.wang@Sun.COM static int
unm_nic_pci_mem_read_direct(struct unm_adapter_s * adapter,u64 off,void * data,int size)11087956Sxiuyan.wang@Sun.COM unm_nic_pci_mem_read_direct(struct unm_adapter_s *adapter,
11097956Sxiuyan.wang@Sun.COM     u64 off, void *data, int size)
11107956Sxiuyan.wang@Sun.COM {
11117956Sxiuyan.wang@Sun.COM 	void			*addr;
11127956Sxiuyan.wang@Sun.COM 	int				ret = 0;
11137956Sxiuyan.wang@Sun.COM 	u64				start;
11147956Sxiuyan.wang@Sun.COM 
11157956Sxiuyan.wang@Sun.COM #if 0
11167956Sxiuyan.wang@Sun.COM 	/*
11177956Sxiuyan.wang@Sun.COM 	 * This check can not be currently executed, since phanmon findq
11187956Sxiuyan.wang@Sun.COM 	 * command breaks this check whereby 8 byte reads are being attempted
11197956Sxiuyan.wang@Sun.COM 	 * on "aligned-by-4" addresses on x86. Reason this works is our version
11207956Sxiuyan.wang@Sun.COM 	 * breaks up the access into 2 consecutive 4 byte writes; on other
11217956Sxiuyan.wang@Sun.COM 	 * architectures, this might require "aligned-by-8" addresses and we
11227956Sxiuyan.wang@Sun.COM 	 * will run into trouble.
11237956Sxiuyan.wang@Sun.COM 	 *
11247956Sxiuyan.wang@Sun.COM 	 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
11257956Sxiuyan.wang@Sun.COM 	 * values will not trigger access.
11267956Sxiuyan.wang@Sun.COM 	 */
11277956Sxiuyan.wang@Sun.COM 	if ((off & (size - 1)) != 0)
11287956Sxiuyan.wang@Sun.COM 		return (-1);
11297956Sxiuyan.wang@Sun.COM #endif
11307956Sxiuyan.wang@Sun.COM 
11317956Sxiuyan.wang@Sun.COM 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
11327956Sxiuyan.wang@Sun.COM 
11337956Sxiuyan.wang@Sun.COM 	/*
11347956Sxiuyan.wang@Sun.COM 	 * If attempting to access unknown address or straddle hw windows,
11357956Sxiuyan.wang@Sun.COM 	 * do not access.
11367956Sxiuyan.wang@Sun.COM 	 */
11377956Sxiuyan.wang@Sun.COM 	if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
11387956Sxiuyan.wang@Sun.COM 	    (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
11397956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
11407956Sxiuyan.wang@Sun.COM 		cmn_err(CE_WARN, "%s out of bound pci memory access. "
11417956Sxiuyan.wang@Sun.COM 		    "offset is 0x%llx\n", unm_nic_driver_name, off);
11427956Sxiuyan.wang@Sun.COM 		return (-1);
11437956Sxiuyan.wang@Sun.COM 	}
11447956Sxiuyan.wang@Sun.COM 
11457956Sxiuyan.wang@Sun.COM 	addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
11467956Sxiuyan.wang@Sun.COM 	if (!addr)
11477956Sxiuyan.wang@Sun.COM 		addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
11487956Sxiuyan.wang@Sun.COM 
11497956Sxiuyan.wang@Sun.COM 	switch (size) {
11507956Sxiuyan.wang@Sun.COM 		case 1:
11517956Sxiuyan.wang@Sun.COM 			*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
11527956Sxiuyan.wang@Sun.COM 			break;
11537956Sxiuyan.wang@Sun.COM 		case 2:
11547956Sxiuyan.wang@Sun.COM 			*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
11557956Sxiuyan.wang@Sun.COM 			break;
11567956Sxiuyan.wang@Sun.COM 		case 4:
11577956Sxiuyan.wang@Sun.COM 			*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
11587956Sxiuyan.wang@Sun.COM 			break;
11597956Sxiuyan.wang@Sun.COM 		case 8:
11607956Sxiuyan.wang@Sun.COM 			*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
11617956Sxiuyan.wang@Sun.COM 			break;
11627956Sxiuyan.wang@Sun.COM 		default:
11637956Sxiuyan.wang@Sun.COM 			ret = -1;
11647956Sxiuyan.wang@Sun.COM 			break;
11657956Sxiuyan.wang@Sun.COM 	}
11667956Sxiuyan.wang@Sun.COM 
11677956Sxiuyan.wang@Sun.COM 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
11687956Sxiuyan.wang@Sun.COM 	return (ret);
11697956Sxiuyan.wang@Sun.COM }
11707956Sxiuyan.wang@Sun.COM 
11717956Sxiuyan.wang@Sun.COM static int
unm_nic_pci_mem_write_direct(struct unm_adapter_s * adapter,u64 off,void * data,int size)11727956Sxiuyan.wang@Sun.COM unm_nic_pci_mem_write_direct(struct unm_adapter_s *adapter, u64 off,
11737956Sxiuyan.wang@Sun.COM     void *data, int size)
11747956Sxiuyan.wang@Sun.COM {
11757956Sxiuyan.wang@Sun.COM 	void	*addr;
11767956Sxiuyan.wang@Sun.COM 	int		ret = 0;
11777956Sxiuyan.wang@Sun.COM 	u64		start;
11787956Sxiuyan.wang@Sun.COM 
11797956Sxiuyan.wang@Sun.COM #if 0
11807956Sxiuyan.wang@Sun.COM 	/*
11817956Sxiuyan.wang@Sun.COM 	 * This check can not be currently executed, since firmware load
11827956Sxiuyan.wang@Sun.COM 	 * breaks this check whereby 8 byte writes are being attempted on
11837956Sxiuyan.wang@Sun.COM 	 * "aligned-by-4" addresses on x86. Reason this works is our version
11847956Sxiuyan.wang@Sun.COM 	 * breaks up the access into 2 consecutive 4 byte writes; on other
11857956Sxiuyan.wang@Sun.COM 	 * architectures, this might require "aligned-by-8" addresses and we
11867956Sxiuyan.wang@Sun.COM 	 * will run into trouble.
11877956Sxiuyan.wang@Sun.COM 	 *
11887956Sxiuyan.wang@Sun.COM 	 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
11897956Sxiuyan.wang@Sun.COM 	 * values will not trigger access.
11907956Sxiuyan.wang@Sun.COM 	 */
11917956Sxiuyan.wang@Sun.COM 	if ((off & (size - 1)) != 0)
11927956Sxiuyan.wang@Sun.COM 		return (-1);
11937956Sxiuyan.wang@Sun.COM #endif
11947956Sxiuyan.wang@Sun.COM 
11957956Sxiuyan.wang@Sun.COM 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
11967956Sxiuyan.wang@Sun.COM 
11977956Sxiuyan.wang@Sun.COM 	/*
11987956Sxiuyan.wang@Sun.COM 	 * If attempting to access unknown address or straddle hw windows,
11997956Sxiuyan.wang@Sun.COM 	 * do not access.
12007956Sxiuyan.wang@Sun.COM 	 */
12017956Sxiuyan.wang@Sun.COM 	if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
12027956Sxiuyan.wang@Sun.COM 	    (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
12037956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
12047956Sxiuyan.wang@Sun.COM 		cmn_err(CE_WARN, "%s out of bound pci memory access. "
12057956Sxiuyan.wang@Sun.COM 		    "offset is 0x%llx\n", unm_nic_driver_name, off);
12067956Sxiuyan.wang@Sun.COM 		return (-1);
12077956Sxiuyan.wang@Sun.COM 	}
12087956Sxiuyan.wang@Sun.COM 
12097956Sxiuyan.wang@Sun.COM 	addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
12107956Sxiuyan.wang@Sun.COM 	if (!addr)
12117956Sxiuyan.wang@Sun.COM 		addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
12127956Sxiuyan.wang@Sun.COM 
12137956Sxiuyan.wang@Sun.COM 	switch (size) {
12147956Sxiuyan.wang@Sun.COM 		case 1:
12157956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_8(*(__uint8_t  *)data, addr);
12167956Sxiuyan.wang@Sun.COM 			break;
12177956Sxiuyan.wang@Sun.COM 		case 2:
12187956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, addr);
12197956Sxiuyan.wang@Sun.COM 			break;
12207956Sxiuyan.wang@Sun.COM 		case 4:
12217956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, addr);
12227956Sxiuyan.wang@Sun.COM 			break;
12237956Sxiuyan.wang@Sun.COM 		case 8:
12247956Sxiuyan.wang@Sun.COM 			UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, addr);
12257956Sxiuyan.wang@Sun.COM 			break;
12267956Sxiuyan.wang@Sun.COM 		default:
12277956Sxiuyan.wang@Sun.COM 			ret = -1;
12287956Sxiuyan.wang@Sun.COM 			break;
12297956Sxiuyan.wang@Sun.COM 	}
12307956Sxiuyan.wang@Sun.COM 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
12317956Sxiuyan.wang@Sun.COM 	return (ret);
12327956Sxiuyan.wang@Sun.COM }
12337956Sxiuyan.wang@Sun.COM 
12347956Sxiuyan.wang@Sun.COM 
12357956Sxiuyan.wang@Sun.COM int
unm_nic_pci_mem_write_128M(struct unm_adapter_s * adapter,u64 off,void * data,int size)12367956Sxiuyan.wang@Sun.COM unm_nic_pci_mem_write_128M(struct unm_adapter_s *adapter, u64 off, void *data,
12377956Sxiuyan.wang@Sun.COM     int size)
12387956Sxiuyan.wang@Sun.COM {
12397956Sxiuyan.wang@Sun.COM 	int		i, j, ret = 0, loop, sz[2], off0;
12407956Sxiuyan.wang@Sun.COM 	__uint32_t		temp;
12417956Sxiuyan.wang@Sun.COM 	__uint64_t		off8, mem_crb, tmpw, word[2] = {0, 0};
12427956Sxiuyan.wang@Sun.COM #define	MAX_CTL_CHECK   1000
12437956Sxiuyan.wang@Sun.COM 
12447956Sxiuyan.wang@Sun.COM 	/*
12457956Sxiuyan.wang@Sun.COM 	 * If not MN, go check for MS or invalid.
12467956Sxiuyan.wang@Sun.COM 	 */
12477956Sxiuyan.wang@Sun.COM 	if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
12487956Sxiuyan.wang@Sun.COM 		return (unm_nic_pci_mem_write_direct(adapter, off, data, size));
12497956Sxiuyan.wang@Sun.COM 
12507956Sxiuyan.wang@Sun.COM 	off8 = off & 0xfffffff8;
12517956Sxiuyan.wang@Sun.COM 	off0 = off & 0x7;
12527956Sxiuyan.wang@Sun.COM 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
12537956Sxiuyan.wang@Sun.COM 	sz[1] = size - sz[0];
12547956Sxiuyan.wang@Sun.COM 	loop = ((off0 + size - 1) >> 3) + 1;
12557956Sxiuyan.wang@Sun.COM 	/* LINTED: E_FALSE_LOGICAL_EXPR */
12567956Sxiuyan.wang@Sun.COM 	mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
12577956Sxiuyan.wang@Sun.COM 
12587956Sxiuyan.wang@Sun.COM 	if ((size != 8) || (off0 != 0))  {
12597956Sxiuyan.wang@Sun.COM 		for (i = 0; i < loop; i++) {
12607956Sxiuyan.wang@Sun.COM 			if (adapter->unm_nic_pci_mem_read(adapter,
12617956Sxiuyan.wang@Sun.COM 			    off8 + (i << 3), &word[i], 8))
12627956Sxiuyan.wang@Sun.COM 				return (-1);
12637956Sxiuyan.wang@Sun.COM 		}
12647956Sxiuyan.wang@Sun.COM 	}
12657956Sxiuyan.wang@Sun.COM 
12667956Sxiuyan.wang@Sun.COM 	switch (size) {
12677956Sxiuyan.wang@Sun.COM 		case 1:
12687956Sxiuyan.wang@Sun.COM 			tmpw = *((__uint8_t *)data);
12697956Sxiuyan.wang@Sun.COM 			break;
12707956Sxiuyan.wang@Sun.COM 		case 2:
12717956Sxiuyan.wang@Sun.COM 			tmpw = *((__uint16_t *)data);
12727956Sxiuyan.wang@Sun.COM 			break;
12737956Sxiuyan.wang@Sun.COM 		case 4:
12747956Sxiuyan.wang@Sun.COM 			tmpw = *((__uint32_t *)data);
12757956Sxiuyan.wang@Sun.COM 			break;
12767956Sxiuyan.wang@Sun.COM 		case 8:
12777956Sxiuyan.wang@Sun.COM 		default:
12787956Sxiuyan.wang@Sun.COM 			tmpw = *((__uint64_t *)data);
12797956Sxiuyan.wang@Sun.COM 			break;
12807956Sxiuyan.wang@Sun.COM 	}
12817956Sxiuyan.wang@Sun.COM 	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
12827956Sxiuyan.wang@Sun.COM 	word[0] |= tmpw << (off0 * 8);
12837956Sxiuyan.wang@Sun.COM 
12847956Sxiuyan.wang@Sun.COM 	if (loop == 2) {
12857956Sxiuyan.wang@Sun.COM 		word[1] &= ~(~0ULL << (sz[1] * 8));
12867956Sxiuyan.wang@Sun.COM 		word[1] |= tmpw >> (sz[0] * 8);
12877956Sxiuyan.wang@Sun.COM 	}
12887956Sxiuyan.wang@Sun.COM 
12897956Sxiuyan.wang@Sun.COM 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
12907956Sxiuyan.wang@Sun.COM 	unm_nic_pci_change_crbwindow_128M(adapter, 0);
12917956Sxiuyan.wang@Sun.COM 
12927956Sxiuyan.wang@Sun.COM 	for (i = 0; i < loop; i++) {
12937956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
12947956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
12957956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(0,
12967956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
12977956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(word[i] & 0xffffffff,
12987956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
12997956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32((word[i] >> 32) & 0xffffffff,
13007956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
13017956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
13027956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
13037956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE |
13047956Sxiuyan.wang@Sun.COM 		    MIU_TA_CTL_WRITE,
13057956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
13067956Sxiuyan.wang@Sun.COM 
13077956Sxiuyan.wang@Sun.COM 		for (j = 0; j < MAX_CTL_CHECK; j++) {
13087956Sxiuyan.wang@Sun.COM 			temp = UNM_NIC_PCI_READ_32((void *)
13097956Sxiuyan.wang@Sun.COM 			    (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
13107956Sxiuyan.wang@Sun.COM 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
13117956Sxiuyan.wang@Sun.COM 				break;
13127956Sxiuyan.wang@Sun.COM 			}
13137956Sxiuyan.wang@Sun.COM 		}
13147956Sxiuyan.wang@Sun.COM 
13157956Sxiuyan.wang@Sun.COM 		if (j >= MAX_CTL_CHECK) {
13167956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: %s Fail to write thru agent\n",
13177956Sxiuyan.wang@Sun.COM 			    __FUNCTION__, unm_nic_driver_name);
13187956Sxiuyan.wang@Sun.COM 			ret = -1;
13197956Sxiuyan.wang@Sun.COM 			break;
13207956Sxiuyan.wang@Sun.COM 		}
13217956Sxiuyan.wang@Sun.COM 	}
13227956Sxiuyan.wang@Sun.COM 
13237956Sxiuyan.wang@Sun.COM 	unm_nic_pci_change_crbwindow_128M(adapter, 1);
13247956Sxiuyan.wang@Sun.COM 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
13257956Sxiuyan.wang@Sun.COM 	return (ret);
13267956Sxiuyan.wang@Sun.COM }
13277956Sxiuyan.wang@Sun.COM 
13287956Sxiuyan.wang@Sun.COM int
unm_nic_pci_mem_read_128M(struct unm_adapter_s * adapter,u64 off,void * data,int size)13297956Sxiuyan.wang@Sun.COM unm_nic_pci_mem_read_128M(struct unm_adapter_s *adapter, u64 off, void *data,
13307956Sxiuyan.wang@Sun.COM     int size)
13317956Sxiuyan.wang@Sun.COM {
13327956Sxiuyan.wang@Sun.COM 	int		i, j = 0, k, start, end, loop, sz[2], off0[2];
13337956Sxiuyan.wang@Sun.COM 	__uint32_t		temp;
13347956Sxiuyan.wang@Sun.COM 	__uint64_t		off8, val, mem_crb, word[2] = {0, 0};
13357956Sxiuyan.wang@Sun.COM #define	MAX_CTL_CHECK   1000
13367956Sxiuyan.wang@Sun.COM 
13377956Sxiuyan.wang@Sun.COM 	/*
13387956Sxiuyan.wang@Sun.COM 	 * If not MN, go check for MS or invalid.
13397956Sxiuyan.wang@Sun.COM 	 */
13407956Sxiuyan.wang@Sun.COM 	if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
13417956Sxiuyan.wang@Sun.COM 		return (unm_nic_pci_mem_read_direct(adapter, off, data, size));
13427956Sxiuyan.wang@Sun.COM 
13437956Sxiuyan.wang@Sun.COM 	off8 = off & 0xfffffff8;
13447956Sxiuyan.wang@Sun.COM 	off0[0] = off & 0x7;
13457956Sxiuyan.wang@Sun.COM 	off0[1] = 0;
13467956Sxiuyan.wang@Sun.COM 	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
13477956Sxiuyan.wang@Sun.COM 	sz[1] = size - sz[0];
13487956Sxiuyan.wang@Sun.COM 	loop = ((off0[0] + size - 1) >> 3) + 1;
13497956Sxiuyan.wang@Sun.COM 	/* LINTED: E_FALSE_LOGICAL_EXPR */
13507956Sxiuyan.wang@Sun.COM 	mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
13517956Sxiuyan.wang@Sun.COM 
13527956Sxiuyan.wang@Sun.COM 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
13537956Sxiuyan.wang@Sun.COM 	unm_nic_pci_change_crbwindow_128M(adapter, 0);
13547956Sxiuyan.wang@Sun.COM 
13557956Sxiuyan.wang@Sun.COM 	for (i = 0; i < loop; i++) {
13567956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
13577956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
13587956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(0,
13597956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
13607956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE,
13617956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
13627956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
13637956Sxiuyan.wang@Sun.COM 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
13647956Sxiuyan.wang@Sun.COM 
13657956Sxiuyan.wang@Sun.COM 		for (j = 0; j < MAX_CTL_CHECK; j++) {
13667956Sxiuyan.wang@Sun.COM 			temp = UNM_NIC_PCI_READ_32((void *)
13677956Sxiuyan.wang@Sun.COM 			    (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
13687956Sxiuyan.wang@Sun.COM 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
13697956Sxiuyan.wang@Sun.COM 				break;
13707956Sxiuyan.wang@Sun.COM 			}
13717956Sxiuyan.wang@Sun.COM 		}
13727956Sxiuyan.wang@Sun.COM 
13737956Sxiuyan.wang@Sun.COM 		if (j >= MAX_CTL_CHECK) {
13747956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: %s Fail to read through agent\n",
13757956Sxiuyan.wang@Sun.COM 			    __FUNCTION__, unm_nic_driver_name);
13767956Sxiuyan.wang@Sun.COM 			break;
13777956Sxiuyan.wang@Sun.COM 		}
13787956Sxiuyan.wang@Sun.COM 
13797956Sxiuyan.wang@Sun.COM 		start = off0[i] >> 2;
13807956Sxiuyan.wang@Sun.COM 		end   = (off0[i] + sz[i] - 1) >> 2;
13817956Sxiuyan.wang@Sun.COM 		word[i] = 0;
13827956Sxiuyan.wang@Sun.COM 		for (k = start; k <= end; k++) {
13837956Sxiuyan.wang@Sun.COM 			word[i] |= ((__uint64_t)UNM_NIC_PCI_READ_32(
13847956Sxiuyan.wang@Sun.COM 			    (void *) (uptr_t)(mem_crb +
13857956Sxiuyan.wang@Sun.COM 			    MIU_TEST_AGT_RDDATA(k))) << (32*k));
13867956Sxiuyan.wang@Sun.COM 		}
13877956Sxiuyan.wang@Sun.COM 	}
13887956Sxiuyan.wang@Sun.COM 
13897956Sxiuyan.wang@Sun.COM 	unm_nic_pci_change_crbwindow_128M(adapter, 1);
13907956Sxiuyan.wang@Sun.COM 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
13917956Sxiuyan.wang@Sun.COM 
13927956Sxiuyan.wang@Sun.COM 	if (j >= MAX_CTL_CHECK)
13937956Sxiuyan.wang@Sun.COM 		return (-1);
13947956Sxiuyan.wang@Sun.COM 
13957956Sxiuyan.wang@Sun.COM 	if (sz[0] == 8) {
13967956Sxiuyan.wang@Sun.COM 		val = word[0];
13977956Sxiuyan.wang@Sun.COM 	} else {
13987956Sxiuyan.wang@Sun.COM 		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
13997956Sxiuyan.wang@Sun.COM 		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
14007956Sxiuyan.wang@Sun.COM 	}
14017956Sxiuyan.wang@Sun.COM 
14027956Sxiuyan.wang@Sun.COM 	switch (size) {
14037956Sxiuyan.wang@Sun.COM 	case 1:
14047956Sxiuyan.wang@Sun.COM 		*(__uint8_t  *)data = val;
14057956Sxiuyan.wang@Sun.COM 		break;
14067956Sxiuyan.wang@Sun.COM 	case 2:
14077956Sxiuyan.wang@Sun.COM 		*(__uint16_t *)data = val;
14087956Sxiuyan.wang@Sun.COM 		break;
14097956Sxiuyan.wang@Sun.COM 	case 4:
14107956Sxiuyan.wang@Sun.COM 		*(__uint32_t *)data = val;
14117956Sxiuyan.wang@Sun.COM 		break;
14127956Sxiuyan.wang@Sun.COM 	case 8:
14137956Sxiuyan.wang@Sun.COM 		*(__uint64_t *)data = val;
14147956Sxiuyan.wang@Sun.COM 		break;
14157956Sxiuyan.wang@Sun.COM 	}
14167956Sxiuyan.wang@Sun.COM 	return (0);
14177956Sxiuyan.wang@Sun.COM }
14187956Sxiuyan.wang@Sun.COM 
14197956Sxiuyan.wang@Sun.COM 
14207956Sxiuyan.wang@Sun.COM 
14217956Sxiuyan.wang@Sun.COM int
unm_nic_pci_mem_write_2M(struct unm_adapter_s * adapter,u64 off,void * data,int size)14227956Sxiuyan.wang@Sun.COM unm_nic_pci_mem_write_2M(struct unm_adapter_s *adapter, u64 off, void *data,
14237956Sxiuyan.wang@Sun.COM     int size)
14247956Sxiuyan.wang@Sun.COM {
14257956Sxiuyan.wang@Sun.COM 	int	i, j, ret = 0, loop, sz[2], off0;
14267956Sxiuyan.wang@Sun.COM 	__uint32_t	temp;
14277956Sxiuyan.wang@Sun.COM 	__uint64_t	off8, mem_crb, tmpw, word[2] = {0, 0};
14287956Sxiuyan.wang@Sun.COM #define	MAX_CTL_CHECK   1000
14297956Sxiuyan.wang@Sun.COM 
14307956Sxiuyan.wang@Sun.COM 	/*
14317956Sxiuyan.wang@Sun.COM 	 * If not MN, go check for MS or invalid.
14327956Sxiuyan.wang@Sun.COM 	 */
14337956Sxiuyan.wang@Sun.COM 	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
14347956Sxiuyan.wang@Sun.COM 		mem_crb = UNM_CRB_QDR_NET;
14357956Sxiuyan.wang@Sun.COM 	} else {
14367956Sxiuyan.wang@Sun.COM 		mem_crb = UNM_CRB_DDR_NET;
14377956Sxiuyan.wang@Sun.COM 		if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
14387956Sxiuyan.wang@Sun.COM 			return (unm_nic_pci_mem_write_direct(adapter,
14397956Sxiuyan.wang@Sun.COM 			    off, data, size));
14407956Sxiuyan.wang@Sun.COM 	}
14417956Sxiuyan.wang@Sun.COM 
14427956Sxiuyan.wang@Sun.COM 	off8 = off & 0xfffffff8;
14437956Sxiuyan.wang@Sun.COM 	off0 = off & 0x7;
14447956Sxiuyan.wang@Sun.COM 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
14457956Sxiuyan.wang@Sun.COM 	sz[1] = size - sz[0];
14467956Sxiuyan.wang@Sun.COM 	loop = ((off0 + size - 1) >> 3) + 1;
14477956Sxiuyan.wang@Sun.COM 
14487956Sxiuyan.wang@Sun.COM 	if ((size != 8) || (off0 != 0)) {
14497956Sxiuyan.wang@Sun.COM 		for (i = 0; i < loop; i++) {
14507956Sxiuyan.wang@Sun.COM 			if (adapter->unm_nic_pci_mem_read(adapter,
14517956Sxiuyan.wang@Sun.COM 			    off8 + (i << 3), &word[i], 8))
14527956Sxiuyan.wang@Sun.COM 				return (-1);
14537956Sxiuyan.wang@Sun.COM 		}
14547956Sxiuyan.wang@Sun.COM 	}
14557956Sxiuyan.wang@Sun.COM 
14567956Sxiuyan.wang@Sun.COM 	switch (size) {
14577956Sxiuyan.wang@Sun.COM 		case 1:
14587956Sxiuyan.wang@Sun.COM 			tmpw = *((__uint8_t *)data);
14597956Sxiuyan.wang@Sun.COM 			break;
14607956Sxiuyan.wang@Sun.COM 		case 2:
14617956Sxiuyan.wang@Sun.COM 			tmpw = *((__uint16_t *)data);
14627956Sxiuyan.wang@Sun.COM 			break;
14637956Sxiuyan.wang@Sun.COM 		case 4:
14647956Sxiuyan.wang@Sun.COM 			tmpw = *((__uint32_t *)data);
14657956Sxiuyan.wang@Sun.COM 			break;
14667956Sxiuyan.wang@Sun.COM 		case 8:
14677956Sxiuyan.wang@Sun.COM 		default:
14687956Sxiuyan.wang@Sun.COM 			tmpw = *((__uint64_t *)data);
14697956Sxiuyan.wang@Sun.COM 			break;
14707956Sxiuyan.wang@Sun.COM 	}
14717956Sxiuyan.wang@Sun.COM 
14727956Sxiuyan.wang@Sun.COM 	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
14737956Sxiuyan.wang@Sun.COM 	word[0] |= tmpw << (off0 * 8);
14747956Sxiuyan.wang@Sun.COM 
14757956Sxiuyan.wang@Sun.COM 	if (loop == 2) {
14767956Sxiuyan.wang@Sun.COM 		word[1] &= ~(~0ULL << (sz[1] * 8));
14777956Sxiuyan.wang@Sun.COM 		word[1] |= tmpw >> (sz[0] * 8);
14787956Sxiuyan.wang@Sun.COM 	}
14797956Sxiuyan.wang@Sun.COM 
14807956Sxiuyan.wang@Sun.COM // don't lock here - write_wx gets the lock if each time
14817956Sxiuyan.wang@Sun.COM // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
14827956Sxiuyan.wang@Sun.COM // unm_nic_pci_change_crbwindow_128M(adapter, 0);
14837956Sxiuyan.wang@Sun.COM 
14847956Sxiuyan.wang@Sun.COM 	for (i = 0; i < loop; i++) {
14857956Sxiuyan.wang@Sun.COM 		temp = off8 + (i << 3);
14867956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
14877956Sxiuyan.wang@Sun.COM 		    mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
14887956Sxiuyan.wang@Sun.COM 		temp = 0;
14897956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
14907956Sxiuyan.wang@Sun.COM 		    mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
14917956Sxiuyan.wang@Sun.COM 		temp = word[i] & 0xffffffff;
14927956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
14937956Sxiuyan.wang@Sun.COM 		    mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
14947956Sxiuyan.wang@Sun.COM 		temp = (word[i] >> 32) & 0xffffffff;
14957956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
14967956Sxiuyan.wang@Sun.COM 		    mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
14977956Sxiuyan.wang@Sun.COM 		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
14987956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
14997956Sxiuyan.wang@Sun.COM 		    mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
15007956Sxiuyan.wang@Sun.COM 		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
15017956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
15027956Sxiuyan.wang@Sun.COM 		    mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
15037956Sxiuyan.wang@Sun.COM 
15047956Sxiuyan.wang@Sun.COM 		for (j = 0; j < MAX_CTL_CHECK; j++) {
15057956Sxiuyan.wang@Sun.COM 			adapter->unm_nic_hw_read_wx(adapter,
15067956Sxiuyan.wang@Sun.COM 			    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
15077956Sxiuyan.wang@Sun.COM 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
15087956Sxiuyan.wang@Sun.COM 				break;
15097956Sxiuyan.wang@Sun.COM 			}
15107956Sxiuyan.wang@Sun.COM 		}
15117956Sxiuyan.wang@Sun.COM 
15127956Sxiuyan.wang@Sun.COM 		if (j >= MAX_CTL_CHECK) {
15137956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: Fail to write through agent\n",
15147956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name);
15157956Sxiuyan.wang@Sun.COM 			ret = -1;
15167956Sxiuyan.wang@Sun.COM 			break;
15177956Sxiuyan.wang@Sun.COM 		}
15187956Sxiuyan.wang@Sun.COM 	}
15197956Sxiuyan.wang@Sun.COM 
15207956Sxiuyan.wang@Sun.COM //  unm_nic_pci_change_crbwindow_128M(adapter, 1);
15217956Sxiuyan.wang@Sun.COM //  UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
15227956Sxiuyan.wang@Sun.COM 	return (ret);
15237956Sxiuyan.wang@Sun.COM }
15247956Sxiuyan.wang@Sun.COM 
15257956Sxiuyan.wang@Sun.COM int
unm_nic_pci_mem_read_2M(struct unm_adapter_s * adapter,u64 off,void * data,int size)15267956Sxiuyan.wang@Sun.COM unm_nic_pci_mem_read_2M(struct unm_adapter_s *adapter, u64 off, void *data,
15277956Sxiuyan.wang@Sun.COM     int size)
15287956Sxiuyan.wang@Sun.COM {
15297956Sxiuyan.wang@Sun.COM // unsigned long   flags;
15307956Sxiuyan.wang@Sun.COM 	int		i, j = 0, k, start, end, loop, sz[2], off0[2];
15317956Sxiuyan.wang@Sun.COM 	__uint32_t	temp;
15327956Sxiuyan.wang@Sun.COM 	__uint64_t	off8, val, mem_crb, word[2] = {0, 0};
15337956Sxiuyan.wang@Sun.COM #define	MAX_CTL_CHECK   1000
15347956Sxiuyan.wang@Sun.COM 
15357956Sxiuyan.wang@Sun.COM 	/*
15367956Sxiuyan.wang@Sun.COM 	 * If not MN, go check for MS or invalid.
15377956Sxiuyan.wang@Sun.COM 	 */
15387956Sxiuyan.wang@Sun.COM 
15397956Sxiuyan.wang@Sun.COM 	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
15407956Sxiuyan.wang@Sun.COM 		mem_crb = UNM_CRB_QDR_NET;
15417956Sxiuyan.wang@Sun.COM 	} else {
15427956Sxiuyan.wang@Sun.COM 		mem_crb = UNM_CRB_DDR_NET;
15437956Sxiuyan.wang@Sun.COM 		if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
15447956Sxiuyan.wang@Sun.COM 			return (unm_nic_pci_mem_read_direct(adapter,
15457956Sxiuyan.wang@Sun.COM 			    off, data, size));
15467956Sxiuyan.wang@Sun.COM 	}
15477956Sxiuyan.wang@Sun.COM 
15487956Sxiuyan.wang@Sun.COM 	off8 = off & 0xfffffff8;
15497956Sxiuyan.wang@Sun.COM 	off0[0] = off & 0x7;
15507956Sxiuyan.wang@Sun.COM 	off0[1] = 0;
15517956Sxiuyan.wang@Sun.COM 	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
15527956Sxiuyan.wang@Sun.COM 	sz[1] = size - sz[0];
15537956Sxiuyan.wang@Sun.COM 	loop = ((off0[0] + size - 1) >> 3) + 1;
15547956Sxiuyan.wang@Sun.COM 
15557956Sxiuyan.wang@Sun.COM // don't get lock - write_wx will get it
15567956Sxiuyan.wang@Sun.COM // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
15577956Sxiuyan.wang@Sun.COM // unm_nic_pci_change_crbwindow_128M(adapter, 0);
15587956Sxiuyan.wang@Sun.COM 
15597956Sxiuyan.wang@Sun.COM 	for (i = 0; i < loop; i++) {
15607956Sxiuyan.wang@Sun.COM 		temp = off8 + (i << 3);
15617956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
15627956Sxiuyan.wang@Sun.COM 		    mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
15637956Sxiuyan.wang@Sun.COM 		temp = 0;
15647956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
15657956Sxiuyan.wang@Sun.COM 		    mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
15667956Sxiuyan.wang@Sun.COM 		temp = MIU_TA_CTL_ENABLE;
15677956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
15687956Sxiuyan.wang@Sun.COM 		    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
15697956Sxiuyan.wang@Sun.COM 		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
15707956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_write_wx(adapter,
15717956Sxiuyan.wang@Sun.COM 		    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
15727956Sxiuyan.wang@Sun.COM 
15737956Sxiuyan.wang@Sun.COM 		for (j = 0; j < MAX_CTL_CHECK; j++) {
15747956Sxiuyan.wang@Sun.COM 			adapter->unm_nic_hw_read_wx(adapter,
15757956Sxiuyan.wang@Sun.COM 			    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
15767956Sxiuyan.wang@Sun.COM 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
15777956Sxiuyan.wang@Sun.COM 				break;
15787956Sxiuyan.wang@Sun.COM 			}
15797956Sxiuyan.wang@Sun.COM 		}
15807956Sxiuyan.wang@Sun.COM 
15817956Sxiuyan.wang@Sun.COM 		if (j >= MAX_CTL_CHECK) {
15827956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: Fail to read through agent\n",
15837956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name);
15847956Sxiuyan.wang@Sun.COM 			break;
15857956Sxiuyan.wang@Sun.COM 		}
15867956Sxiuyan.wang@Sun.COM 
15877956Sxiuyan.wang@Sun.COM 		start = off0[i] >> 2;
15887956Sxiuyan.wang@Sun.COM 		end   = (off0[i] + sz[i] - 1) >> 2;
15897956Sxiuyan.wang@Sun.COM 		for (k = start; k <= end; k++) {
15907956Sxiuyan.wang@Sun.COM 			adapter->unm_nic_hw_read_wx(adapter,
15917956Sxiuyan.wang@Sun.COM 			    mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
15927956Sxiuyan.wang@Sun.COM 			word[i] |= ((__uint64_t)temp << (32 * k));
15937956Sxiuyan.wang@Sun.COM 		}
15947956Sxiuyan.wang@Sun.COM 	}
15957956Sxiuyan.wang@Sun.COM 
15967956Sxiuyan.wang@Sun.COM // unm_nic_pci_change_crbwindow_128M(adapter, 1);
15977956Sxiuyan.wang@Sun.COM // UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
15987956Sxiuyan.wang@Sun.COM 
15997956Sxiuyan.wang@Sun.COM 	if (j >= MAX_CTL_CHECK)
16007956Sxiuyan.wang@Sun.COM 		return (-1);
16017956Sxiuyan.wang@Sun.COM 
16027956Sxiuyan.wang@Sun.COM 	if (sz[0] == 8) {
16037956Sxiuyan.wang@Sun.COM 		val = word[0];
16047956Sxiuyan.wang@Sun.COM 	} else {
16057956Sxiuyan.wang@Sun.COM 		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
16067956Sxiuyan.wang@Sun.COM 		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
16077956Sxiuyan.wang@Sun.COM 	}
16087956Sxiuyan.wang@Sun.COM 
16097956Sxiuyan.wang@Sun.COM 	switch (size) {
16107956Sxiuyan.wang@Sun.COM 		case 1:
16117956Sxiuyan.wang@Sun.COM 			*(__uint8_t  *)data = val;
16127956Sxiuyan.wang@Sun.COM 			break;
16137956Sxiuyan.wang@Sun.COM 		case 2:
16147956Sxiuyan.wang@Sun.COM 			*(__uint16_t *)data = val;
16157956Sxiuyan.wang@Sun.COM 			break;
16167956Sxiuyan.wang@Sun.COM 		case 4:
16177956Sxiuyan.wang@Sun.COM 			*(__uint32_t *)data = val;
16187956Sxiuyan.wang@Sun.COM 			break;
16197956Sxiuyan.wang@Sun.COM 		case 8:
16207956Sxiuyan.wang@Sun.COM 			*(__uint64_t *)data = val;
16217956Sxiuyan.wang@Sun.COM 			break;
16227956Sxiuyan.wang@Sun.COM 	}
16237956Sxiuyan.wang@Sun.COM 	return (0);
16247956Sxiuyan.wang@Sun.COM }
16257956Sxiuyan.wang@Sun.COM 
16267956Sxiuyan.wang@Sun.COM int
unm_crb_writelit_adapter_2M(struct unm_adapter_s * adapter,unsigned long off,int data)16277956Sxiuyan.wang@Sun.COM unm_crb_writelit_adapter_2M(struct unm_adapter_s *adapter, unsigned long off,
16287956Sxiuyan.wang@Sun.COM     int data)
16297956Sxiuyan.wang@Sun.COM {
16307956Sxiuyan.wang@Sun.COM 	return (unm_nic_hw_write_wx_2M(adapter, off, &data, 4));
16317956Sxiuyan.wang@Sun.COM }
16327956Sxiuyan.wang@Sun.COM 
16337956Sxiuyan.wang@Sun.COM int
unm_crb_writelit_adapter_128M(struct unm_adapter_s * adapter,unsigned long off,int data)16347956Sxiuyan.wang@Sun.COM unm_crb_writelit_adapter_128M(struct unm_adapter_s *adapter, unsigned long off,
16357956Sxiuyan.wang@Sun.COM     int data)
16367956Sxiuyan.wang@Sun.COM {
16377956Sxiuyan.wang@Sun.COM 	void *addr;
16387956Sxiuyan.wang@Sun.COM 
16397956Sxiuyan.wang@Sun.COM 	if (ADDR_IN_WINDOW1(off)) {
16407956Sxiuyan.wang@Sun.COM 		UNM_READ_LOCK(&adapter->adapter_lock);
16417956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
16427956Sxiuyan.wang@Sun.COM 		UNM_READ_UNLOCK(&adapter->adapter_lock);
16437956Sxiuyan.wang@Sun.COM 	} else {
16447956Sxiuyan.wang@Sun.COM 		// unm_nic_write_w0 (adapter, off, data);
16457956Sxiuyan.wang@Sun.COM 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
16467956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
16477956Sxiuyan.wang@Sun.COM 		addr = (void *) (pci_base_offset(adapter, off));
16487956Sxiuyan.wang@Sun.COM 		UNM_NIC_PCI_WRITE_32(data, addr);
16497956Sxiuyan.wang@Sun.COM 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
16507956Sxiuyan.wang@Sun.COM 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
16517956Sxiuyan.wang@Sun.COM 	}
16527956Sxiuyan.wang@Sun.COM 
16537956Sxiuyan.wang@Sun.COM 	return (0);
16547956Sxiuyan.wang@Sun.COM }
16557956Sxiuyan.wang@Sun.COM 
16567956Sxiuyan.wang@Sun.COM int
unm_nic_get_board_info(struct unm_adapter_s * adapter)16577956Sxiuyan.wang@Sun.COM unm_nic_get_board_info(struct unm_adapter_s *adapter)
16587956Sxiuyan.wang@Sun.COM {
16597956Sxiuyan.wang@Sun.COM 	int	rv = 0;
16607956Sxiuyan.wang@Sun.COM 	unm_board_info_t  *boardinfo;
16617956Sxiuyan.wang@Sun.COM 	int		i;
16627956Sxiuyan.wang@Sun.COM 	int		addr = BRDCFG_START;
16637956Sxiuyan.wang@Sun.COM 	uint32_t	  *ptr32;
16647956Sxiuyan.wang@Sun.COM 	uint32_t	gpioval;
16657956Sxiuyan.wang@Sun.COM 
16667956Sxiuyan.wang@Sun.COM 	boardinfo = &adapter->ahw.boardcfg;
16677956Sxiuyan.wang@Sun.COM 	ptr32 = (uint32_t *)boardinfo;
16687956Sxiuyan.wang@Sun.COM 
16697956Sxiuyan.wang@Sun.COM 	for (i = 0; i < sizeof (unm_board_info_t) / sizeof (uint32_t); i++) {
16707956Sxiuyan.wang@Sun.COM 		if (rom_fast_read(adapter, addr, (int *)ptr32) == -1) {
16717956Sxiuyan.wang@Sun.COM 			return (-1);
16727956Sxiuyan.wang@Sun.COM 		}
16737956Sxiuyan.wang@Sun.COM 		DPRINTF(1, (CE_WARN, "ROM(%d): %x\n", i, *ptr32));
16747956Sxiuyan.wang@Sun.COM 		ptr32++;
16757956Sxiuyan.wang@Sun.COM 		addr += sizeof (uint32_t);
16767956Sxiuyan.wang@Sun.COM 	}
16777956Sxiuyan.wang@Sun.COM 
16787956Sxiuyan.wang@Sun.COM 	if (boardinfo->magic != UNM_BDINFO_MAGIC) {
16797956Sxiuyan.wang@Sun.COM 		DPRINTF(1, (CE_WARN, "%s: ERROR reading board config."
16807956Sxiuyan.wang@Sun.COM 		    " Read %x, expected %x\n", unm_nic_driver_name,
16817956Sxiuyan.wang@Sun.COM 		    boardinfo->magic, UNM_BDINFO_MAGIC));
16827956Sxiuyan.wang@Sun.COM 		rv = -1;
16837956Sxiuyan.wang@Sun.COM 	}
16847956Sxiuyan.wang@Sun.COM 
16857956Sxiuyan.wang@Sun.COM 	if (boardinfo->header_version != UNM_BDINFO_VERSION) {
16867956Sxiuyan.wang@Sun.COM 		DPRINTF(1, (CE_WARN, "%s: Unknown board config version."
16877956Sxiuyan.wang@Sun.COM 		    " Read %x, expected %x\n", unm_nic_driver_name,
16887956Sxiuyan.wang@Sun.COM 		    boardinfo->header_version, UNM_BDINFO_VERSION));
16897956Sxiuyan.wang@Sun.COM 		rv = -1;
16907956Sxiuyan.wang@Sun.COM 	}
16917956Sxiuyan.wang@Sun.COM 
16927956Sxiuyan.wang@Sun.COM 	if (boardinfo->board_type == UNM_BRDTYPE_P3_4_GB_MM) {
16937956Sxiuyan.wang@Sun.COM 		gpioval = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_PAD_GPIO_I,
16947956Sxiuyan.wang@Sun.COM 		    adapter);
16957956Sxiuyan.wang@Sun.COM 		if ((gpioval & 0x8000) == 0)
16967956Sxiuyan.wang@Sun.COM 			boardinfo->board_type = UNM_BRDTYPE_P3_10G_TRP;
16977956Sxiuyan.wang@Sun.COM 	}
16987956Sxiuyan.wang@Sun.COM 
16997956Sxiuyan.wang@Sun.COM 	DPRINTF(0, (CE_WARN, "Discovered board type:0x%x  ",
17007956Sxiuyan.wang@Sun.COM 	    boardinfo->board_type));
17017956Sxiuyan.wang@Sun.COM 
17027956Sxiuyan.wang@Sun.COM 	switch ((unm_brdtype_t)boardinfo->board_type) {
17037956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P2_SB35_4G:
17047956Sxiuyan.wang@Sun.COM 		adapter->ahw.board_type = UNM_NIC_GBE;
17057956Sxiuyan.wang@Sun.COM 		break;
17067956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P2_SB31_10G:
17077956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
17087956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
17097956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P2_SB31_10G_CX4:
17107956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_HMEZ:
17117956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_XG_LOM:
17127956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_10G_CX4:
17137956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_10G_CX4_LP:
17147956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_IMEZ:
17157956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_10G_SFP_PLUS:
17167956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_10G_XFP:
17177956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_10000_BASE_T:
17187956Sxiuyan.wang@Sun.COM 		adapter->ahw.board_type = UNM_NIC_XGBE;
17197956Sxiuyan.wang@Sun.COM 		break;
17207956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_REF_QG:
17217956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_4_GB:
17227956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_4_GB_MM:
17237956Sxiuyan.wang@Sun.COM 		adapter->ahw.board_type = UNM_NIC_GBE;
17247956Sxiuyan.wang@Sun.COM 		break;
17257956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P1_BD:
17267956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P1_SB:
17277956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P1_SMAX:
17287956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P1_SOCK:
17297956Sxiuyan.wang@Sun.COM 		adapter->ahw.board_type = UNM_NIC_GBE;
17307956Sxiuyan.wang@Sun.COM 		break;
17317956Sxiuyan.wang@Sun.COM 	case UNM_BRDTYPE_P3_10G_TRP:
17327956Sxiuyan.wang@Sun.COM 		if (adapter->portnum < 2)
17337956Sxiuyan.wang@Sun.COM 			adapter->ahw.board_type = UNM_NIC_XGBE;
17347956Sxiuyan.wang@Sun.COM 		else
17357956Sxiuyan.wang@Sun.COM 			adapter->ahw.board_type = UNM_NIC_GBE;
17367956Sxiuyan.wang@Sun.COM 		break;
17377956Sxiuyan.wang@Sun.COM 	default:
17387956Sxiuyan.wang@Sun.COM 		DPRINTF(1, (CE_WARN, "%s: Unknown(%x)\n", unm_nic_driver_name,
17397956Sxiuyan.wang@Sun.COM 		    boardinfo->board_type));
17407956Sxiuyan.wang@Sun.COM 		break;
17417956Sxiuyan.wang@Sun.COM 	}
17427956Sxiuyan.wang@Sun.COM 
17437956Sxiuyan.wang@Sun.COM 	return (rv);
17447956Sxiuyan.wang@Sun.COM }
17457956Sxiuyan.wang@Sun.COM 
17467956Sxiuyan.wang@Sun.COM /* NIU access sections */
17477956Sxiuyan.wang@Sun.COM 
17487956Sxiuyan.wang@Sun.COM int
unm_nic_macaddr_set(struct unm_adapter_s * adapter,__uint8_t * addr)17497956Sxiuyan.wang@Sun.COM unm_nic_macaddr_set(struct unm_adapter_s *adapter, __uint8_t *addr)
17507956Sxiuyan.wang@Sun.COM {
17517956Sxiuyan.wang@Sun.COM 	int		ret = 0, i, retry_count = 10;
17527956Sxiuyan.wang@Sun.COM 	unsigned char		mac_addr[MAX_ADDR_LEN];
17537956Sxiuyan.wang@Sun.COM 
17547956Sxiuyan.wang@Sun.COM 	/* For P3, we should not set MAC in HW any more */
17557956Sxiuyan.wang@Sun.COM 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
17567956Sxiuyan.wang@Sun.COM 		return (0);
17577956Sxiuyan.wang@Sun.COM 
17587956Sxiuyan.wang@Sun.COM 	switch (adapter->ahw.board_type) {
17597956Sxiuyan.wang@Sun.COM 		case UNM_NIC_GBE:
17607956Sxiuyan.wang@Sun.COM 	/*
17617956Sxiuyan.wang@Sun.COM 	 * Flaky Mac address registers on qgig require several writes.
17627956Sxiuyan.wang@Sun.COM 	 */
17637956Sxiuyan.wang@Sun.COM 			for (i = 0; i < retry_count; ++i) {
17647956Sxiuyan.wang@Sun.COM 				if (unm_niu_macaddr_set(adapter, addr) != 0)
17657956Sxiuyan.wang@Sun.COM 					return (-1);
17667956Sxiuyan.wang@Sun.COM 
17677956Sxiuyan.wang@Sun.COM 				(void) unm_niu_macaddr_get(adapter,
17687956Sxiuyan.wang@Sun.COM 				    (unsigned char *)mac_addr);
17697956Sxiuyan.wang@Sun.COM 				if (memcmp(mac_addr, addr, 6) == 0)
17707956Sxiuyan.wang@Sun.COM 					return (0);
17717956Sxiuyan.wang@Sun.COM 			}
17727956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: Flaky MAC addr registers\n",
17737956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name);
17747956Sxiuyan.wang@Sun.COM 			break;
17757956Sxiuyan.wang@Sun.COM 
17767956Sxiuyan.wang@Sun.COM 		case UNM_NIC_XGBE:
17777956Sxiuyan.wang@Sun.COM 			ret = unm_niu_xg_macaddr_set(adapter, addr);
17787956Sxiuyan.wang@Sun.COM 			break;
17797956Sxiuyan.wang@Sun.COM 
17807956Sxiuyan.wang@Sun.COM 		default:
17817956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN,  "\r\nUnknown board type encountered"
17827956Sxiuyan.wang@Sun.COM 			    " while setting the MAC address.\n");
17837956Sxiuyan.wang@Sun.COM 			return (-1);
17847956Sxiuyan.wang@Sun.COM 	}
17857956Sxiuyan.wang@Sun.COM 	return (ret);
17867956Sxiuyan.wang@Sun.COM }
17877956Sxiuyan.wang@Sun.COM 
17887956Sxiuyan.wang@Sun.COM #define	MTU_FUDGE_FACTOR 100
17897956Sxiuyan.wang@Sun.COM int
unm_nic_set_mtu(struct unm_adapter_s * adapter,int new_mtu)17907956Sxiuyan.wang@Sun.COM unm_nic_set_mtu(struct unm_adapter_s *adapter, int new_mtu)
17917956Sxiuyan.wang@Sun.COM {
17927956Sxiuyan.wang@Sun.COM 	long		port = adapter->physical_port;
17937956Sxiuyan.wang@Sun.COM 	int			ret = 0;
17947956Sxiuyan.wang@Sun.COM 	u32			port_mode = 0;
17957956Sxiuyan.wang@Sun.COM 
17967956Sxiuyan.wang@Sun.COM 	if (adapter->ahw.revision_id >= NX_P3_A2)
17977956Sxiuyan.wang@Sun.COM 		return (nx_fw_cmd_set_mtu(adapter, new_mtu));
17987956Sxiuyan.wang@Sun.COM 
17997956Sxiuyan.wang@Sun.COM 	new_mtu += MTU_FUDGE_FACTOR; /* so that MAC accepts frames > MTU */
18007956Sxiuyan.wang@Sun.COM 	switch (adapter->ahw.board_type) {
18017956Sxiuyan.wang@Sun.COM 		case UNM_NIC_GBE:
18027956Sxiuyan.wang@Sun.COM 			unm_nic_write_w0(adapter,
18037956Sxiuyan.wang@Sun.COM 			    UNM_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
18047956Sxiuyan.wang@Sun.COM 			    new_mtu);
18057956Sxiuyan.wang@Sun.COM 
18067956Sxiuyan.wang@Sun.COM 			break;
18077956Sxiuyan.wang@Sun.COM 
18087956Sxiuyan.wang@Sun.COM 		case UNM_NIC_XGBE:
18097956Sxiuyan.wang@Sun.COM 			adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
18107956Sxiuyan.wang@Sun.COM 			    &port_mode, 4);
18117956Sxiuyan.wang@Sun.COM 			if (port_mode == UNM_PORT_MODE_802_3_AP) {
18127956Sxiuyan.wang@Sun.COM 				unm_nic_write_w0(adapter,
18137956Sxiuyan.wang@Sun.COM 				    UNM_NIU_AP_MAX_FRAME_SIZE(port), new_mtu);
18147956Sxiuyan.wang@Sun.COM 			} else {
18157956Sxiuyan.wang@Sun.COM 				if (adapter->physical_port == 0) {
18167956Sxiuyan.wang@Sun.COM 					unm_nic_write_w0(adapter,
18177956Sxiuyan.wang@Sun.COM 					    UNM_NIU_XGE_MAX_FRAME_SIZE,
18187956Sxiuyan.wang@Sun.COM 					    new_mtu);
18197956Sxiuyan.wang@Sun.COM 				} else {
18207956Sxiuyan.wang@Sun.COM 					unm_nic_write_w0(adapter,
18217956Sxiuyan.wang@Sun.COM 					    UNM_NIU_XG1_MAX_FRAME_SIZE,
18227956Sxiuyan.wang@Sun.COM 					    new_mtu);
18237956Sxiuyan.wang@Sun.COM 				}
18247956Sxiuyan.wang@Sun.COM 			}
18257956Sxiuyan.wang@Sun.COM 			break;
18267956Sxiuyan.wang@Sun.COM 
18277956Sxiuyan.wang@Sun.COM 		default:
18287956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
18297956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name);
18307956Sxiuyan.wang@Sun.COM 	}
18317956Sxiuyan.wang@Sun.COM 
18327956Sxiuyan.wang@Sun.COM 	return (ret);
18337956Sxiuyan.wang@Sun.COM }
18347956Sxiuyan.wang@Sun.COM 
18357956Sxiuyan.wang@Sun.COM int
unm_nic_set_promisc_mode(struct unm_adapter_s * adapter)18367956Sxiuyan.wang@Sun.COM unm_nic_set_promisc_mode(struct unm_adapter_s *adapter)
18377956Sxiuyan.wang@Sun.COM {
18387956Sxiuyan.wang@Sun.COM 	int		ret;
18397956Sxiuyan.wang@Sun.COM 
18407956Sxiuyan.wang@Sun.COM 	if (adapter->promisc)
18417956Sxiuyan.wang@Sun.COM 		return (0);
18427956Sxiuyan.wang@Sun.COM 
18437956Sxiuyan.wang@Sun.COM 	switch (adapter->ahw.board_type) {
18447956Sxiuyan.wang@Sun.COM 		case UNM_NIC_GBE:
18457956Sxiuyan.wang@Sun.COM 			ret = unm_niu_set_promiscuous_mode(adapter,
18467956Sxiuyan.wang@Sun.COM 			    UNM_NIU_PROMISCOUS_MODE);
18477956Sxiuyan.wang@Sun.COM 			break;
18487956Sxiuyan.wang@Sun.COM 
18497956Sxiuyan.wang@Sun.COM 		case UNM_NIC_XGBE:
18507956Sxiuyan.wang@Sun.COM 			ret = unm_niu_xg_set_promiscuous_mode(adapter,
18517956Sxiuyan.wang@Sun.COM 			    UNM_NIU_PROMISCOUS_MODE);
18527956Sxiuyan.wang@Sun.COM 			break;
18537956Sxiuyan.wang@Sun.COM 
18547956Sxiuyan.wang@Sun.COM 		default:
18557956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
18567956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name);
18577956Sxiuyan.wang@Sun.COM 			ret = -1;
18587956Sxiuyan.wang@Sun.COM 			break;
18597956Sxiuyan.wang@Sun.COM 	}
18607956Sxiuyan.wang@Sun.COM 
18617956Sxiuyan.wang@Sun.COM if (!ret)
18627956Sxiuyan.wang@Sun.COM 	adapter->promisc = 1;
18637956Sxiuyan.wang@Sun.COM 
18647956Sxiuyan.wang@Sun.COM 		return (ret);
18657956Sxiuyan.wang@Sun.COM }
18667956Sxiuyan.wang@Sun.COM 
18677956Sxiuyan.wang@Sun.COM int
unm_nic_unset_promisc_mode(struct unm_adapter_s * adapter)18687956Sxiuyan.wang@Sun.COM unm_nic_unset_promisc_mode(struct unm_adapter_s *adapter)
18697956Sxiuyan.wang@Sun.COM {
18707956Sxiuyan.wang@Sun.COM 	int	ret = 0;
18717956Sxiuyan.wang@Sun.COM 
18727956Sxiuyan.wang@Sun.COM 	/*
18737956Sxiuyan.wang@Sun.COM 	 * P3 does not unset promiscous mode. Why?
18747956Sxiuyan.wang@Sun.COM 	 */
18757956Sxiuyan.wang@Sun.COM 	if (adapter->ahw.revision_id >= NX_P3_A2) {
18767956Sxiuyan.wang@Sun.COM 		return (0);
18777956Sxiuyan.wang@Sun.COM 	}
18787956Sxiuyan.wang@Sun.COM 
18797956Sxiuyan.wang@Sun.COM 	if (!adapter->promisc)
18807956Sxiuyan.wang@Sun.COM 		return (0);
18817956Sxiuyan.wang@Sun.COM 
18827956Sxiuyan.wang@Sun.COM 	switch (adapter->ahw.board_type) {
18837956Sxiuyan.wang@Sun.COM 		case UNM_NIC_GBE:
18847956Sxiuyan.wang@Sun.COM 			ret = unm_niu_set_promiscuous_mode(adapter,
18857956Sxiuyan.wang@Sun.COM 			    UNM_NIU_NON_PROMISCOUS_MODE);
18867956Sxiuyan.wang@Sun.COM 			break;
18877956Sxiuyan.wang@Sun.COM 
18887956Sxiuyan.wang@Sun.COM 		case UNM_NIC_XGBE:
18897956Sxiuyan.wang@Sun.COM 			ret = unm_niu_xg_set_promiscuous_mode(adapter,
18907956Sxiuyan.wang@Sun.COM 			    UNM_NIU_NON_PROMISCOUS_MODE);
18917956Sxiuyan.wang@Sun.COM 			break;
18927956Sxiuyan.wang@Sun.COM 
18937956Sxiuyan.wang@Sun.COM 		default:
18947956Sxiuyan.wang@Sun.COM 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
18957956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name);
18967956Sxiuyan.wang@Sun.COM 			ret = -1;
18977956Sxiuyan.wang@Sun.COM 			break;
18987956Sxiuyan.wang@Sun.COM 	}
18997956Sxiuyan.wang@Sun.COM 
19007956Sxiuyan.wang@Sun.COM 	if (!ret)
19017956Sxiuyan.wang@Sun.COM 		adapter->promisc = 0;
19027956Sxiuyan.wang@Sun.COM 
19037956Sxiuyan.wang@Sun.COM 	return (ret);
19047956Sxiuyan.wang@Sun.COM }
19057956Sxiuyan.wang@Sun.COM 
19067956Sxiuyan.wang@Sun.COM long
unm_nic_phy_read(unm_adapter * adapter,long reg,__uint32_t * readval)19077956Sxiuyan.wang@Sun.COM unm_nic_phy_read(unm_adapter *adapter, long reg,
19087956Sxiuyan.wang@Sun.COM 		    __uint32_t *readval)
19097956Sxiuyan.wang@Sun.COM {
19107956Sxiuyan.wang@Sun.COM 	long	ret = 0;
19117956Sxiuyan.wang@Sun.COM 
19127956Sxiuyan.wang@Sun.COM 	switch (adapter->ahw.board_type) {
19137956Sxiuyan.wang@Sun.COM 	case UNM_NIC_GBE:
19147956Sxiuyan.wang@Sun.COM 		ret = unm_niu_gbe_phy_read(adapter, reg, readval);
19157956Sxiuyan.wang@Sun.COM 		break;
19167956Sxiuyan.wang@Sun.COM 
19177956Sxiuyan.wang@Sun.COM 	case UNM_NIC_XGBE:
19187956Sxiuyan.wang@Sun.COM 		DPRINTF(1, (CE_WARN,
19197956Sxiuyan.wang@Sun.COM 		    "%s: Function %s is not implemented for XG\n",
19207956Sxiuyan.wang@Sun.COM 		    unm_nic_driver_name, __FUNCTION__));
19217956Sxiuyan.wang@Sun.COM 		break;
19227956Sxiuyan.wang@Sun.COM 
19237956Sxiuyan.wang@Sun.COM 	default:
19247956Sxiuyan.wang@Sun.COM 		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
19257956Sxiuyan.wang@Sun.COM 		    unm_nic_driver_name));
19267956Sxiuyan.wang@Sun.COM 	}
19277956Sxiuyan.wang@Sun.COM 
19287956Sxiuyan.wang@Sun.COM 	return (ret);
19297956Sxiuyan.wang@Sun.COM }
19307956Sxiuyan.wang@Sun.COM 
19317956Sxiuyan.wang@Sun.COM long
unm_nic_init_port(struct unm_adapter_s * adapter)19327956Sxiuyan.wang@Sun.COM unm_nic_init_port(struct unm_adapter_s *adapter)
19337956Sxiuyan.wang@Sun.COM {
19347956Sxiuyan.wang@Sun.COM 	long	portnum = adapter->physical_port;
19357956Sxiuyan.wang@Sun.COM 	long	ret = 0;
19367956Sxiuyan.wang@Sun.COM 	long	reg = 0;
19377956Sxiuyan.wang@Sun.COM 	unm_niu_gbe_ifmode_t	mode_dont_care = 0;
19387956Sxiuyan.wang@Sun.COM 	u32			port_mode = 0;
19397956Sxiuyan.wang@Sun.COM 
19407956Sxiuyan.wang@Sun.COM 	unm_nic_set_link_parameters(adapter);
19417956Sxiuyan.wang@Sun.COM 
19427956Sxiuyan.wang@Sun.COM 	switch (adapter->ahw.board_type) {
19437956Sxiuyan.wang@Sun.COM 	case UNM_NIC_GBE:
19447956Sxiuyan.wang@Sun.COM 		ret = unm_niu_enable_gbe_port(adapter, mode_dont_care);
19457956Sxiuyan.wang@Sun.COM 		break;
19467956Sxiuyan.wang@Sun.COM 
19477956Sxiuyan.wang@Sun.COM 	case UNM_NIC_XGBE:
19487956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
19497956Sxiuyan.wang@Sun.COM 		    &port_mode, 4);
19507956Sxiuyan.wang@Sun.COM 		if (port_mode == UNM_PORT_MODE_802_3_AP) {
19517956Sxiuyan.wang@Sun.COM 			ret = unm_niu_enable_gbe_port(adapter, mode_dont_care);
19527956Sxiuyan.wang@Sun.COM 		} else {
19537956Sxiuyan.wang@Sun.COM 			adapter->unm_crb_writelit_adapter(adapter,
19547956Sxiuyan.wang@Sun.COM 			    UNM_NIU_XGE_CONFIG_0 + (0x10000 * portnum), 0x5);
19557956Sxiuyan.wang@Sun.COM 			UNM_CRB_READ_CHECK_ADAPTER(UNM_NIU_XGE_CONFIG_1 +
19567956Sxiuyan.wang@Sun.COM 			    (0x10000 * portnum), &reg, adapter);
19577956Sxiuyan.wang@Sun.COM 			if (adapter->ahw.revision_id < NX_P3_A2)
19587956Sxiuyan.wang@Sun.COM 				reg = (reg & ~0x2000UL);
19597956Sxiuyan.wang@Sun.COM 			adapter->unm_crb_writelit_adapter(adapter,
19607956Sxiuyan.wang@Sun.COM 			    UNM_NIU_XGE_CONFIG_1 + (0x10000 * portnum), reg);
19617956Sxiuyan.wang@Sun.COM 		}
19627956Sxiuyan.wang@Sun.COM 		break;
19637956Sxiuyan.wang@Sun.COM 
19647956Sxiuyan.wang@Sun.COM 	default:
19657956Sxiuyan.wang@Sun.COM 		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
19667956Sxiuyan.wang@Sun.COM 		    unm_nic_driver_name));
19677956Sxiuyan.wang@Sun.COM 	}
19687956Sxiuyan.wang@Sun.COM 
19697956Sxiuyan.wang@Sun.COM 	return (ret);
19707956Sxiuyan.wang@Sun.COM }
19717956Sxiuyan.wang@Sun.COM 
19727956Sxiuyan.wang@Sun.COM void
unm_nic_stop_port(struct unm_adapter_s * adapter)19737956Sxiuyan.wang@Sun.COM unm_nic_stop_port(struct unm_adapter_s *adapter)
19747956Sxiuyan.wang@Sun.COM {
19757956Sxiuyan.wang@Sun.COM 
1976*8687SJing.Xiong@Sun.COM 	(void) mac_unregister(adapter->mach);
19777956Sxiuyan.wang@Sun.COM 
19787956Sxiuyan.wang@Sun.COM 	switch (adapter->ahw.board_type) {
19797956Sxiuyan.wang@Sun.COM 	case UNM_NIC_GBE:
19807956Sxiuyan.wang@Sun.COM 		(void) unm_niu_disable_gbe_port(adapter);
19817956Sxiuyan.wang@Sun.COM 		break;
19827956Sxiuyan.wang@Sun.COM 
19837956Sxiuyan.wang@Sun.COM 	case UNM_NIC_XGBE:
19847956Sxiuyan.wang@Sun.COM 		(void) unm_niu_disable_xg_port(adapter);
19857956Sxiuyan.wang@Sun.COM 		break;
19867956Sxiuyan.wang@Sun.COM 
19877956Sxiuyan.wang@Sun.COM 	default:
19887956Sxiuyan.wang@Sun.COM 		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
19897956Sxiuyan.wang@Sun.COM 		    unm_nic_driver_name));
19907956Sxiuyan.wang@Sun.COM 	}
19917956Sxiuyan.wang@Sun.COM }
19927956Sxiuyan.wang@Sun.COM 
19937956Sxiuyan.wang@Sun.COM void
unm_crb_write_adapter(unsigned long off,void * data,struct unm_adapter_s * adapter)19947956Sxiuyan.wang@Sun.COM unm_crb_write_adapter(unsigned long off, void *data,
19957956Sxiuyan.wang@Sun.COM     struct unm_adapter_s *adapter)
19967956Sxiuyan.wang@Sun.COM {
19977956Sxiuyan.wang@Sun.COM 	(void) adapter->unm_nic_hw_write_wx(adapter, off, data, 4);
19987956Sxiuyan.wang@Sun.COM }
19997956Sxiuyan.wang@Sun.COM 
20007956Sxiuyan.wang@Sun.COM int
unm_crb_read_adapter(unsigned long off,void * data,struct unm_adapter_s * adapter)20017956Sxiuyan.wang@Sun.COM unm_crb_read_adapter(unsigned long off, void *data,
20027956Sxiuyan.wang@Sun.COM     struct unm_adapter_s *adapter)
20037956Sxiuyan.wang@Sun.COM {
20047956Sxiuyan.wang@Sun.COM 	return (adapter->unm_nic_hw_read_wx(adapter, off, data, 4));
20057956Sxiuyan.wang@Sun.COM }
20067956Sxiuyan.wang@Sun.COM 
20077956Sxiuyan.wang@Sun.COM int
unm_crb_read_val_adapter(unsigned long off,struct unm_adapter_s * adapter)20087956Sxiuyan.wang@Sun.COM unm_crb_read_val_adapter(unsigned long off, struct unm_adapter_s *adapter)
20097956Sxiuyan.wang@Sun.COM {
20107956Sxiuyan.wang@Sun.COM 	int data;
20117956Sxiuyan.wang@Sun.COM 
20127956Sxiuyan.wang@Sun.COM 	adapter->unm_nic_hw_read_wx(adapter, off, &data, 4);
20137956Sxiuyan.wang@Sun.COM 	return (data);
20147956Sxiuyan.wang@Sun.COM }
20157956Sxiuyan.wang@Sun.COM 
20167956Sxiuyan.wang@Sun.COM void
unm_nic_set_link_parameters(struct unm_adapter_s * adapter)20177956Sxiuyan.wang@Sun.COM unm_nic_set_link_parameters(struct unm_adapter_s *adapter)
20187956Sxiuyan.wang@Sun.COM {
20197956Sxiuyan.wang@Sun.COM 	unm_niu_phy_status_t status;
20207956Sxiuyan.wang@Sun.COM 	uint16_t defval = (uint16_t)-1;
20217956Sxiuyan.wang@Sun.COM 	unm_niu_control_t mode;
20227956Sxiuyan.wang@Sun.COM 	u32 port_mode = 0;
20237956Sxiuyan.wang@Sun.COM 
20247956Sxiuyan.wang@Sun.COM 	unm_nic_read_w0(adapter, UNM_NIU_MODE, (uint32_t *)&mode);
20257956Sxiuyan.wang@Sun.COM 	if (mode.enable_ge) { // Gb 10/100/1000 Mbps mode
20267956Sxiuyan.wang@Sun.COM 		adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
20277956Sxiuyan.wang@Sun.COM 		    &port_mode, 4);
20287956Sxiuyan.wang@Sun.COM 		if (port_mode == UNM_PORT_MODE_802_3_AP) {
20297956Sxiuyan.wang@Sun.COM 			adapter->link_speed = MBPS_1000;
20307956Sxiuyan.wang@Sun.COM 			adapter->link_duplex = LINK_DUPLEX_FULL;
20317956Sxiuyan.wang@Sun.COM 		} else {
20327956Sxiuyan.wang@Sun.COM 		if (unm_nic_phy_read(adapter,
20337956Sxiuyan.wang@Sun.COM 		    UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
20347956Sxiuyan.wang@Sun.COM 		    (unm_crbword_t *)&status) == 0) {
20357956Sxiuyan.wang@Sun.COM 			if (status.link) {
20367956Sxiuyan.wang@Sun.COM 				switch (status.speed) {
20377956Sxiuyan.wang@Sun.COM 				case 0: adapter->link_speed = MBPS_10;
20387956Sxiuyan.wang@Sun.COM 					break;
20397956Sxiuyan.wang@Sun.COM 				case 1: adapter->link_speed = MBPS_100;
20407956Sxiuyan.wang@Sun.COM 					break;
20417956Sxiuyan.wang@Sun.COM 				case 2: adapter->link_speed = MBPS_1000;
20427956Sxiuyan.wang@Sun.COM 					break;
20437956Sxiuyan.wang@Sun.COM 				default:
20447956Sxiuyan.wang@Sun.COM 					adapter->link_speed = defval;
20457956Sxiuyan.wang@Sun.COM 					break;
20467956Sxiuyan.wang@Sun.COM 				}
20477956Sxiuyan.wang@Sun.COM 				switch (status.duplex) {
20487956Sxiuyan.wang@Sun.COM 				case 0: adapter->link_duplex = LINK_DUPLEX_HALF;
20497956Sxiuyan.wang@Sun.COM 					break;
20507956Sxiuyan.wang@Sun.COM 				case 1: adapter->link_duplex = LINK_DUPLEX_FULL;
20517956Sxiuyan.wang@Sun.COM 					break;
20527956Sxiuyan.wang@Sun.COM 				default:
20537956Sxiuyan.wang@Sun.COM 					adapter->link_duplex = defval;
20547956Sxiuyan.wang@Sun.COM 					break;
20557956Sxiuyan.wang@Sun.COM 				}
20567956Sxiuyan.wang@Sun.COM 			} else {
20577956Sxiuyan.wang@Sun.COM 				adapter->link_speed = defval;
20587956Sxiuyan.wang@Sun.COM 				adapter->link_duplex = defval;
20597956Sxiuyan.wang@Sun.COM 			}
20607956Sxiuyan.wang@Sun.COM 		} else {
20617956Sxiuyan.wang@Sun.COM 			adapter->link_speed = defval;
20627956Sxiuyan.wang@Sun.COM 			adapter->link_duplex = defval;
20637956Sxiuyan.wang@Sun.COM 		}
20647956Sxiuyan.wang@Sun.COM 		}
20657956Sxiuyan.wang@Sun.COM 	}
20667956Sxiuyan.wang@Sun.COM }
20677956Sxiuyan.wang@Sun.COM 
20687956Sxiuyan.wang@Sun.COM void
unm_nic_flash_print(struct unm_adapter_s * adapter)20697956Sxiuyan.wang@Sun.COM unm_nic_flash_print(struct unm_adapter_s *adapter)
20707956Sxiuyan.wang@Sun.COM {
20717956Sxiuyan.wang@Sun.COM 	int valid = 1;
20727956Sxiuyan.wang@Sun.COM 	unm_board_info_t *board_info = &(adapter->ahw.boardcfg);
20737956Sxiuyan.wang@Sun.COM 
20747956Sxiuyan.wang@Sun.COM 	if (board_info->magic != UNM_BDINFO_MAGIC) {
20757956Sxiuyan.wang@Sun.COM 		cmn_err(CE_WARN, "%s UNM Unknown board config, Read 0x%x "
20767956Sxiuyan.wang@Sun.COM 		    "expected as 0x%x\n", unm_nic_driver_name,
20777956Sxiuyan.wang@Sun.COM 		    board_info->magic, UNM_BDINFO_MAGIC);
20787956Sxiuyan.wang@Sun.COM 		valid = 0;
20797956Sxiuyan.wang@Sun.COM 	}
20807956Sxiuyan.wang@Sun.COM 	if (board_info->header_version != UNM_BDINFO_VERSION) {
20817956Sxiuyan.wang@Sun.COM 		cmn_err(CE_WARN, "%s UNM Unknown board config version."
20827956Sxiuyan.wang@Sun.COM 		    " Read %x, expected %x\n", unm_nic_driver_name,
20837956Sxiuyan.wang@Sun.COM 		    board_info->header_version, UNM_BDINFO_VERSION);
20847956Sxiuyan.wang@Sun.COM 		valid = 0;
20857956Sxiuyan.wang@Sun.COM 	}
20867956Sxiuyan.wang@Sun.COM 	if (valid) {
20877956Sxiuyan.wang@Sun.COM 		unm_user_info_t  user_info;
20887956Sxiuyan.wang@Sun.COM 		int	i;
20897956Sxiuyan.wang@Sun.COM 		int	addr = USER_START;
20907956Sxiuyan.wang@Sun.COM 		int	*ptr32;
20917956Sxiuyan.wang@Sun.COM 
20927956Sxiuyan.wang@Sun.COM 		ptr32 = (int *)&user_info;
20937956Sxiuyan.wang@Sun.COM 		for (i = 0; i < sizeof (unm_user_info_t) / sizeof (uint32_t);
20947956Sxiuyan.wang@Sun.COM 		    i++) {
20957956Sxiuyan.wang@Sun.COM 			if (rom_fast_read(adapter, addr, ptr32) == -1) {
20967956Sxiuyan.wang@Sun.COM 				cmn_err(CE_WARN,
20977956Sxiuyan.wang@Sun.COM 				    "%s: ERROR reading %s board userarea.\n",
20987956Sxiuyan.wang@Sun.COM 				    unm_nic_driver_name, unm_nic_driver_name);
20997956Sxiuyan.wang@Sun.COM 				return;
21007956Sxiuyan.wang@Sun.COM 			}
21017956Sxiuyan.wang@Sun.COM 			ptr32++;
21027956Sxiuyan.wang@Sun.COM 			addr += sizeof (uint32_t);
21037956Sxiuyan.wang@Sun.COM 		}
21047956Sxiuyan.wang@Sun.COM 		if (verbmsg != 0) {
21057956Sxiuyan.wang@Sun.COM 			char	*brd_name;
21067956Sxiuyan.wang@Sun.COM 			GET_BRD_NAME_BY_TYPE(board_info->board_type, brd_name);
21077956Sxiuyan.wang@Sun.COM 			cmn_err(CE_NOTE, "%s %s Board S/N %s  Chip id 0x%x\n",
21087956Sxiuyan.wang@Sun.COM 			    unm_nic_driver_name, brd_name, user_info.serial_num,
21097956Sxiuyan.wang@Sun.COM 			    board_info->chip_id);
21107956Sxiuyan.wang@Sun.COM 		}
21117956Sxiuyan.wang@Sun.COM 	}
21127956Sxiuyan.wang@Sun.COM }
21137956Sxiuyan.wang@Sun.COM 
21147956Sxiuyan.wang@Sun.COM static int
nx_nic_send_cmd_descs(unm_adapter * adapter,cmdDescType0_t * cmd_desc_arr,int nr_elements)21157956Sxiuyan.wang@Sun.COM nx_nic_send_cmd_descs(unm_adapter *adapter, cmdDescType0_t *cmd_desc_arr,
21167956Sxiuyan.wang@Sun.COM     int nr_elements)
21177956Sxiuyan.wang@Sun.COM {
21187956Sxiuyan.wang@Sun.COM 	struct unm_cmd_buffer	*pbuf;
21197956Sxiuyan.wang@Sun.COM 	unsigned int		i = 0, producer;
21207956Sxiuyan.wang@Sun.COM 
21217956Sxiuyan.wang@Sun.COM 	/*
21227956Sxiuyan.wang@Sun.COM 	 * We need to check if space is available.
21237956Sxiuyan.wang@Sun.COM 	 */
21247956Sxiuyan.wang@Sun.COM 	UNM_SPIN_LOCK(&adapter->tx_lock);
21257956Sxiuyan.wang@Sun.COM 	producer = adapter->cmdProducer;
21267956Sxiuyan.wang@Sun.COM 
21277956Sxiuyan.wang@Sun.COM 	do {
21287956Sxiuyan.wang@Sun.COM 		pbuf = &adapter->cmd_buf_arr[producer];
21297956Sxiuyan.wang@Sun.COM 		pbuf->head = pbuf->tail = NULL;
21307956Sxiuyan.wang@Sun.COM 		pbuf->msg = NULL;
21317956Sxiuyan.wang@Sun.COM 		(void) memcpy(&adapter->ahw.cmdDescHead[producer],
21327956Sxiuyan.wang@Sun.COM 		    &cmd_desc_arr[i], sizeof (cmdDescType0_t));
21337956Sxiuyan.wang@Sun.COM 		unm_desc_dma_sync(adapter->ahw.cmd_desc_dma_handle, producer,
21347956Sxiuyan.wang@Sun.COM 		    1, adapter->MaxTxDescCount, sizeof (cmdDescType0_t),
21357956Sxiuyan.wang@Sun.COM 		    DDI_DMA_SYNC_FORDEV);
21367956Sxiuyan.wang@Sun.COM 		producer = get_next_index(producer, adapter->MaxTxDescCount);
21377956Sxiuyan.wang@Sun.COM 		i++;
21387956Sxiuyan.wang@Sun.COM 	} while (i != nr_elements);
21397956Sxiuyan.wang@Sun.COM 
21407956Sxiuyan.wang@Sun.COM 	adapter->cmdProducer = adapter->ahw.cmdProducer = producer;
21417956Sxiuyan.wang@Sun.COM 	adapter->freecmds -= i;
21427956Sxiuyan.wang@Sun.COM 
21437956Sxiuyan.wang@Sun.COM 	unm_nic_update_cmd_producer(adapter, producer);
21447956Sxiuyan.wang@Sun.COM 
21457956Sxiuyan.wang@Sun.COM 	UNM_SPIN_UNLOCK(&adapter->tx_lock);
21467956Sxiuyan.wang@Sun.COM 	return (0);
21477956Sxiuyan.wang@Sun.COM }
21487956Sxiuyan.wang@Sun.COM 
21497956Sxiuyan.wang@Sun.COM typedef struct {
21507956Sxiuyan.wang@Sun.COM 	u64	qhdr, req_hdr, words[6];
21517956Sxiuyan.wang@Sun.COM } nx_nic_req_t;
21527956Sxiuyan.wang@Sun.COM 
21537956Sxiuyan.wang@Sun.COM typedef struct {
21547956Sxiuyan.wang@Sun.COM 	u8	op, tag, mac_addr[6];
21557956Sxiuyan.wang@Sun.COM } nx_mac_req_t;
21567956Sxiuyan.wang@Sun.COM 
21577956Sxiuyan.wang@Sun.COM static void
nx_p3_sre_macaddr_change(unm_adapter * adapter,u8 * addr,u8 op)21587956Sxiuyan.wang@Sun.COM nx_p3_sre_macaddr_change(unm_adapter *adapter, u8 *addr, u8 op)
21597956Sxiuyan.wang@Sun.COM {
21607956Sxiuyan.wang@Sun.COM 	nx_nic_req_t	req;
21617956Sxiuyan.wang@Sun.COM 	nx_mac_req_t	mac_req;
21627956Sxiuyan.wang@Sun.COM 	int		rv;
21637956Sxiuyan.wang@Sun.COM 
21647956Sxiuyan.wang@Sun.COM 	(void) memset(&req, 0, sizeof (nx_nic_req_t));
21657956Sxiuyan.wang@Sun.COM 	req.qhdr |= (NX_NIC_REQUEST << 23);
21667956Sxiuyan.wang@Sun.COM 	req.req_hdr |= NX_MAC_EVENT;
21677956Sxiuyan.wang@Sun.COM 	req.req_hdr |= ((u64)adapter->portnum << 16);
21687956Sxiuyan.wang@Sun.COM 	mac_req.op = op;
21697956Sxiuyan.wang@Sun.COM 	(void) memcpy(&mac_req.mac_addr, addr, 6);
21707956Sxiuyan.wang@Sun.COM 	req.words[0] = HOST_TO_LE_64(*(u64 *)(uintptr_t)&mac_req);
21717956Sxiuyan.wang@Sun.COM 
21727956Sxiuyan.wang@Sun.COM 	rv = nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1);
21737956Sxiuyan.wang@Sun.COM 	if (rv != 0)
21747956Sxiuyan.wang@Sun.COM 		cmn_err(CE_WARN, "%s%d: Could not send mac update\n",
21757956Sxiuyan.wang@Sun.COM 		    adapter->name, adapter->instance);
21767956Sxiuyan.wang@Sun.COM }
21777956Sxiuyan.wang@Sun.COM 
21787956Sxiuyan.wang@Sun.COM static int
nx_p3_nic_set_promisc(unm_adapter * adapter,u32 mode)21797956Sxiuyan.wang@Sun.COM nx_p3_nic_set_promisc(unm_adapter *adapter, u32 mode)
21807956Sxiuyan.wang@Sun.COM {
21817956Sxiuyan.wang@Sun.COM 	nx_nic_req_t	req;
21827956Sxiuyan.wang@Sun.COM 
21837956Sxiuyan.wang@Sun.COM 	(void) memset(&req, 0, sizeof (nx_nic_req_t));
21847956Sxiuyan.wang@Sun.COM 
21857956Sxiuyan.wang@Sun.COM 	req.qhdr |= (NX_HOST_REQUEST << 23);
21867956Sxiuyan.wang@Sun.COM 	req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
21877956Sxiuyan.wang@Sun.COM 	req.req_hdr |= ((u64)adapter->portnum << 16);
21887956Sxiuyan.wang@Sun.COM 	req.words[0] = HOST_TO_LE_64(mode);
21897956Sxiuyan.wang@Sun.COM 
21907956Sxiuyan.wang@Sun.COM 	return (nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1));
21917956Sxiuyan.wang@Sun.COM }
21927956Sxiuyan.wang@Sun.COM 
21937956Sxiuyan.wang@Sun.COM /*
21947956Sxiuyan.wang@Sun.COM  * Currently only invoked at interface initialization time
21957956Sxiuyan.wang@Sun.COM  */
21967956Sxiuyan.wang@Sun.COM void
nx_p3_nic_set_multi(unm_adapter * adapter)21977956Sxiuyan.wang@Sun.COM nx_p3_nic_set_multi(unm_adapter *adapter)
21987956Sxiuyan.wang@Sun.COM {
21997956Sxiuyan.wang@Sun.COM 	u8	bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
22007956Sxiuyan.wang@Sun.COM 
22017956Sxiuyan.wang@Sun.COM 	if (nx_p3_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL))
22027956Sxiuyan.wang@Sun.COM 		cmn_err(CE_WARN, "Could not set promisc mode\n");
22037956Sxiuyan.wang@Sun.COM 
22047956Sxiuyan.wang@Sun.COM 	nx_p3_sre_macaddr_change(adapter, adapter->mac_addr, NETXEN_MAC_ADD);
22057956Sxiuyan.wang@Sun.COM 	nx_p3_sre_macaddr_change(adapter, bcast_addr, NETXEN_MAC_ADD);
22067956Sxiuyan.wang@Sun.COM }
2207